• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// strip_unneeded is a tool that attempts to remove unnecessary lines from a
16// file by running a test script after each marked line is removed.
17//
18// strip_unneeded will scan the file specified by the --file argument for lines
19// that contain the substring specified by the --marker argument. One-by-one
20// those marked lines will be removed from the file, after which the test script
21// specified by --test will be run. If the test passes (the process completes
22// with a 0 return code), then the line will remain removed, otherwise it is
23// restored. This will repeat for every line in the file containing the marker,
24// until all lines are tested.
25package main
26
27import (
28	"flag"
29	"fmt"
30	"io/ioutil"
31	"os"
32	"os/exec"
33	"strings"
34)
35
36var (
37	file   = flag.String("file", "", "file to modify")
38	marker = flag.String("marker", "CHECK_NEEDED", "line token")
39	test   = flag.String("test", "", "test script to run with each change")
40)
41
42func main() {
43	if err := run(); err != nil {
44		fmt.Println(err.Error())
45		os.Exit(1)
46	}
47}
48
49func run() error {
50	flag.Parse()
51	if *file == "" {
52		return fmt.Errorf("Missing --file argument")
53	}
54	if *marker == "" {
55		return fmt.Errorf("Missing --marker argument")
56	}
57	if *test == "" {
58		return fmt.Errorf("Missing --test argument")
59	}
60
61	// make sure the test passes with no modifications
62	if err := runTest(); err != nil {
63		return fmt.Errorf("Test fails with no modifications.\n%v", err)
64	}
65
66	// load the test file
67	body, err := ioutil.ReadFile(*file)
68	if err != nil {
69		return fmt.Errorf("Couldn't load file '%v'", *file)
70	}
71
72	// gather all the lines
73	allLines := strings.Split(string(body), "\n")
74
75	// find all the lines with the marker
76	markerLines := make([]int, 0, len(allLines))
77	for i, l := range allLines {
78		if strings.Contains(l, *marker) {
79			markerLines = append(markerLines, i)
80		}
81	}
82
83	omit := map[int]bool{}
84
85	save := func() error {
86		f, err := os.Create(*file)
87		if err != nil {
88			return err
89		}
90		defer f.Close()
91		for i, l := range allLines {
92			if !omit[i] {
93				f.WriteString(l)
94				f.WriteString("\n")
95			}
96		}
97		return nil
98	}
99
100	for i, l := range markerLines {
101		omit[l] = true
102		if err := save(); err != nil {
103			return err
104		}
105		if err := runTest(); err != nil {
106			omit[l] = false
107			fmt.Printf("%d/%d: Test fails when removing line %v: %v\n", i, len(markerLines), l, allLines[l])
108		} else {
109			fmt.Printf("%d/%d: Test passes when removing line %v: %v\n", i, len(markerLines), l, allLines[l])
110		}
111	}
112
113	return save()
114}
115
116func runTest() error {
117	cmd := exec.Command("sh", "-c", *test)
118	out, err := cmd.CombinedOutput()
119	if err != nil {
120		return fmt.Errorf("Test failed with error: %v\n%v", err, string(out))
121	}
122	return nil
123}
124