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