| Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 1 | // Copyright 2018 Google Inc. 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 |  | 
| Dan Willemsen | c89b6f1 | 2019-08-29 14:47:40 -0700 | [diff] [blame] | 15 | package makedeps | 
| Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 16 |  | 
 | 17 | import ( | 
 | 18 | 	"bytes" | 
 | 19 | 	"io" | 
 | 20 | 	"io/ioutil" | 
 | 21 | 	"os" | 
 | 22 | 	"testing" | 
 | 23 | ) | 
 | 24 |  | 
 | 25 | func TestParse(t *testing.T) { | 
 | 26 | 	testCases := []struct { | 
 | 27 | 		name   string | 
 | 28 | 		input  string | 
 | 29 | 		output Deps | 
 | 30 | 		err    error | 
 | 31 | 	}{ | 
 | 32 | 		// These come from the ninja test suite | 
 | 33 | 		{ | 
 | 34 | 			name:  "Basic", | 
 | 35 | 			input: "build/ninja.o: ninja.cc ninja.h eval_env.h manifest_parser.h", | 
 | 36 | 			output: Deps{ | 
 | 37 | 				Output: "build/ninja.o", | 
 | 38 | 				Inputs: []string{ | 
 | 39 | 					"ninja.cc", | 
 | 40 | 					"ninja.h", | 
 | 41 | 					"eval_env.h", | 
 | 42 | 					"manifest_parser.h", | 
 | 43 | 				}, | 
 | 44 | 			}, | 
 | 45 | 		}, | 
 | 46 | 		{ | 
 | 47 | 			name: "EarlyNewlineAndWhitespace", | 
 | 48 | 			input: ` \ | 
 | 49 |   out: in`, | 
 | 50 | 			output: Deps{ | 
 | 51 | 				Output: "out", | 
 | 52 | 				Inputs: []string{"in"}, | 
 | 53 | 			}, | 
 | 54 | 		}, | 
 | 55 | 		{ | 
 | 56 | 			name: "Continuation", | 
 | 57 | 			input: `foo.o: \ | 
 | 58 |   bar.h baz.h | 
 | 59 | `, | 
 | 60 | 			output: Deps{ | 
 | 61 | 				Output: "foo.o", | 
 | 62 | 				Inputs: []string{"bar.h", "baz.h"}, | 
 | 63 | 			}, | 
 | 64 | 		}, | 
 | 65 | 		{ | 
 | 66 | 			name:  "CarriageReturnContinuation", | 
 | 67 | 			input: "foo.o: \\\r\n  bar.h baz.h\r\n", | 
 | 68 | 			output: Deps{ | 
 | 69 | 				Output: "foo.o", | 
 | 70 | 				Inputs: []string{"bar.h", "baz.h"}, | 
 | 71 | 			}, | 
 | 72 | 		}, | 
 | 73 | 		{ | 
 | 74 | 			name: "BackSlashes", | 
 | 75 | 			input: `Project\Dir\Build\Release8\Foo\Foo.res : \ | 
 | 76 |   Dir\Library\Foo.rc \ | 
 | 77 |   Dir\Library\Version\Bar.h \ | 
 | 78 |   Dir\Library\Foo.ico \ | 
 | 79 |   Project\Thing\Bar.tlb \ | 
 | 80 | `, | 
 | 81 | 			output: Deps{ | 
 | 82 | 				Output: `Project\Dir\Build\Release8\Foo\Foo.res`, | 
 | 83 | 				Inputs: []string{ | 
 | 84 | 					`Dir\Library\Foo.rc`, | 
 | 85 | 					`Dir\Library\Version\Bar.h`, | 
 | 86 | 					`Dir\Library\Foo.ico`, | 
 | 87 | 					`Project\Thing\Bar.tlb`, | 
 | 88 | 				}, | 
 | 89 | 			}, | 
 | 90 | 		}, | 
 | 91 | 		{ | 
 | 92 | 			name:  "Spaces", | 
 | 93 | 			input: `a\ bc\ def:   a\ b c d`, | 
 | 94 | 			output: Deps{ | 
 | 95 | 				Output: `a bc def`, | 
 | 96 | 				Inputs: []string{"a b", "c", "d"}, | 
 | 97 | 			}, | 
 | 98 | 		}, | 
 | 99 | 		{ | 
 | 100 | 			name:  "Escapes", | 
 | 101 | 			input: `\!\@\#$$\%\^\&\\:`, | 
 | 102 | 			output: Deps{ | 
 | 103 | 				Output: `\!\@#$\%\^\&\`, | 
 | 104 | 			}, | 
 | 105 | 		}, | 
 | 106 | 		{ | 
 | 107 | 			name: "SpecialChars", | 
 | 108 | 			// Ninja includes a number of '=', but our parser can't handle that, | 
 | 109 | 			// since it sees the equals and switches over to assuming it's an | 
 | 110 | 			// assignment. | 
 | 111 | 			// | 
 | 112 | 			// We don't have any files in our tree that contain an '=' character, | 
 | 113 | 			// and Kati can't handle parsing this either, so for now I'm just | 
 | 114 | 			// going to remove all the '=' characters below. | 
 | 115 | 			// | 
 | 116 | 			// It looks like make will only do this for the first | 
 | 117 | 			// dependency, but not later dependencies. | 
 | 118 | 			input: `C\:/Program\ Files\ (x86)/Microsoft\ crtdefs.h: \ | 
 | 119 |  en@quot.header~ t+t-x!1 \ | 
 | 120 |  openldap/slapd.d/cnconfig/cnschema/cn{0}core.ldif \ | 
 | 121 |  Fu` + "\303\244ball", | 
 | 122 | 			output: Deps{ | 
 | 123 | 				Output: "C:/Program Files (x86)/Microsoft crtdefs.h", | 
 | 124 | 				Inputs: []string{ | 
 | 125 | 					"en@quot.header~", | 
 | 126 | 					"t+t-x!1", | 
 | 127 | 					"openldap/slapd.d/cnconfig/cnschema/cn{0}core.ldif", | 
 | 128 | 					"Fu\303\244ball", | 
 | 129 | 				}, | 
 | 130 | 			}, | 
 | 131 | 		}, | 
 | 132 | 		// Ninja's UnifyMultipleOutputs and RejectMultipleDifferentOutputs tests have been omitted, | 
 | 133 | 		// since we don't want the same behavior. | 
 | 134 |  | 
 | 135 | 		// Our own tests | 
 | 136 | 		{ | 
 | 137 | 			name: "Multiple outputs", | 
 | 138 | 			input: `a b: c | 
 | 139 | a: d | 
 | 140 | b: e`, | 
 | 141 | 			output: Deps{ | 
 | 142 | 				Output: "b", | 
 | 143 | 				Inputs: []string{ | 
 | 144 | 					"c", | 
 | 145 | 					"d", | 
 | 146 | 					"e", | 
 | 147 | 				}, | 
 | 148 | 			}, | 
 | 149 | 		}, | 
| Colin Cross | 5274d58 | 2019-10-04 12:34:19 -0700 | [diff] [blame] | 150 | 		{ | 
 | 151 | 			// TODO(b/141372861): remove this | 
 | 152 | 			// AIDL produces a dep file with no output file for a parcelable (b/ | 
 | 153 | 			name: "AIDL parcelable", | 
 | 154 | 			input: ` : \ | 
 | 155 |   frameworks/base/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.aidl | 
 | 156 | `, | 
 | 157 | 			output: Deps{ | 
 | 158 | 				Output: "", | 
 | 159 | 				Inputs: []string{ | 
 | 160 | 					"frameworks/base/tests/net/integration/src/com/android/server/net/integrationtests/HttpResponse.aidl", | 
 | 161 | 				}, | 
 | 162 | 			}, | 
 | 163 | 		}, | 
| Dan Willemsen | 4339853 | 2018-02-21 02:10:29 -0800 | [diff] [blame] | 164 | 	} | 
 | 165 |  | 
 | 166 | 	for _, tc := range testCases { | 
 | 167 | 		t.Run(tc.name, func(t *testing.T) { | 
 | 168 | 			out, err := Parse("test.d", bytes.NewBufferString(tc.input)) | 
 | 169 | 			if err != tc.err { | 
 | 170 | 				t.Fatalf("Unexpected error: %v (expected %v)", err, tc.err) | 
 | 171 | 			} | 
 | 172 |  | 
 | 173 | 			if out.Output != tc.output.Output { | 
 | 174 | 				t.Errorf("output file doesn't match:\n"+ | 
 | 175 | 					" str: %#v\n"+ | 
 | 176 | 					"want: %#v\n"+ | 
 | 177 | 					" got: %#v", tc.input, tc.output.Output, out.Output) | 
 | 178 | 			} | 
 | 179 |  | 
 | 180 | 			matches := true | 
 | 181 | 			if len(out.Inputs) != len(tc.output.Inputs) { | 
 | 182 | 				matches = false | 
 | 183 | 			} else { | 
 | 184 | 				for i := range out.Inputs { | 
 | 185 | 					if out.Inputs[i] != tc.output.Inputs[i] { | 
 | 186 | 						matches = false | 
 | 187 | 					} | 
 | 188 | 				} | 
 | 189 | 			} | 
 | 190 | 			if !matches { | 
 | 191 | 				t.Errorf("input files don't match:\n"+ | 
 | 192 | 					" str: %#v\n"+ | 
 | 193 | 					"want: %#v\n"+ | 
 | 194 | 					" got: %#v", tc.input, tc.output.Inputs, out.Inputs) | 
 | 195 | 			} | 
 | 196 | 		}) | 
 | 197 | 	} | 
 | 198 | } | 
 | 199 |  | 
 | 200 | func BenchmarkParsing(b *testing.B) { | 
 | 201 | 	// Write it out to a file to most closely match ninja's perftest | 
 | 202 | 	tmpfile, err := ioutil.TempFile("", "depfile") | 
 | 203 | 	if err != nil { | 
 | 204 | 		b.Fatal("Failed to create temp file:", err) | 
 | 205 | 	} | 
 | 206 | 	defer os.Remove(tmpfile.Name()) | 
 | 207 | 	_, err = io.WriteString(tmpfile, `out/soong/.intermediates/external/ninja/ninja/linux_glibc_x86_64/obj/external/ninja/src/ninja.o: \ | 
 | 208 |   external/ninja/src/ninja.cc external/libcxx/include/errno.h \ | 
 | 209 |   external/libcxx/include/__config \ | 
 | 210 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/features.h \ | 
 | 211 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/predefs.h \ | 
 | 212 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/sys/cdefs.h \ | 
 | 213 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/wordsize.h \ | 
 | 214 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/gnu/stubs.h \ | 
 | 215 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ | 
 | 216 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/errno.h \ | 
 | 217 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/errno.h \ | 
 | 218 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/linux/errno.h \ | 
 | 219 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/asm/errno.h \ | 
 | 220 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/asm-generic/errno.h \ | 
 | 221 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/asm-generic/errno-base.h \ | 
 | 222 |   external/libcxx/include/limits.h \ | 
 | 223 |   prebuilts/clang/host/linux-x86/clang-4639204/lib64/clang/6.0.1/include/limits.h \ | 
 | 224 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/limits.h \ | 
 | 225 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ | 
 | 226 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/local_lim.h \ | 
 | 227 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/linux/limits.h \ | 
 | 228 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ | 
 | 229 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ | 
 | 230 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ | 
 | 231 |   external/libcxx/include/stdio.h \ | 
 | 232 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/stdio.h \ | 
 | 233 |   external/libcxx/include/stddef.h \ | 
 | 234 |   prebuilts/clang/host/linux-x86/clang-4639204/lib64/clang/6.0.1/include/stddef.h \ | 
 | 235 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/types.h \ | 
 | 236 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/typesizes.h \ | 
 | 237 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/libio.h \ | 
 | 238 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/_G_config.h \ | 
 | 239 |   external/libcxx/include/wchar.h \ | 
 | 240 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/wchar.h \ | 
 | 241 |   prebuilts/clang/host/linux-x86/clang-4639204/lib64/clang/6.0.1/include/stdarg.h \ | 
 | 242 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ | 
 | 243 |   external/libcxx/include/stdlib.h \ | 
 | 244 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/stdlib.h \ | 
 | 245 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/waitflags.h \ | 
 | 246 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/waitstatus.h \ | 
 | 247 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/endian.h \ | 
 | 248 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/endian.h \ | 
 | 249 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/byteswap.h \ | 
 | 250 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/xlocale.h \ | 
 | 251 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/sys/types.h \ | 
 | 252 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/time.h \ | 
 | 253 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/sys/select.h \ | 
 | 254 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/select.h \ | 
 | 255 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/sigset.h \ | 
 | 256 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/time.h \ | 
 | 257 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/select2.h \ | 
 | 258 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/sys/sysmacros.h \ | 
 | 259 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ | 
 | 260 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/alloca.h \ | 
 | 261 |   external/libcxx/include/string.h \ | 
 | 262 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/string.h \ | 
 | 263 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/getopt.h \ | 
 | 264 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/unistd.h \ | 
 | 265 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/posix_opt.h \ | 
 | 266 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/environments.h \ | 
 | 267 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/confname.h \ | 
 | 268 |   external/ninja/src/browse.h external/ninja/src/build.h \ | 
 | 269 |   external/libcxx/include/cstdio external/libcxx/include/map \ | 
 | 270 |   external/libcxx/include/__tree external/libcxx/include/iterator \ | 
 | 271 |   external/libcxx/include/iosfwd \ | 
 | 272 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/wchar.h \ | 
 | 273 |   external/libcxx/include/__functional_base \ | 
 | 274 |   external/libcxx/include/type_traits external/libcxx/include/cstddef \ | 
 | 275 |   prebuilts/clang/host/linux-x86/clang-4639204/lib64/clang/6.0.1/include/__stddef_max_align_t.h \ | 
 | 276 |   external/libcxx/include/__nullptr external/libcxx/include/typeinfo \ | 
 | 277 |   external/libcxx/include/exception external/libcxx/include/cstdlib \ | 
 | 278 |   external/libcxx/include/cstdint external/libcxx/include/stdint.h \ | 
 | 279 |   prebuilts/clang/host/linux-x86/clang-4639204/lib64/clang/6.0.1/include/stdint.h \ | 
 | 280 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/stdint.h \ | 
 | 281 |   external/libcxx/include/new external/libcxx/include/utility \ | 
 | 282 |   external/libcxx/include/__tuple \ | 
 | 283 |   external/libcxx/include/initializer_list \ | 
 | 284 |   external/libcxx/include/cstring external/libcxx/include/__debug \ | 
 | 285 |   external/libcxx/include/memory external/libcxx/include/limits \ | 
 | 286 |   external/libcxx/include/__undef_macros external/libcxx/include/tuple \ | 
 | 287 |   external/libcxx/include/stdexcept external/libcxx/include/cassert \ | 
 | 288 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/assert.h \ | 
 | 289 |   external/libcxx/include/atomic external/libcxx/include/algorithm \ | 
 | 290 |   external/libcxx/include/functional external/libcxx/include/queue \ | 
 | 291 |   external/libcxx/include/deque external/libcxx/include/__split_buffer \ | 
 | 292 |   external/libcxx/include/vector external/libcxx/include/__bit_reference \ | 
 | 293 |   external/libcxx/include/climits external/libcxx/include/set \ | 
 | 294 |   external/libcxx/include/string external/libcxx/include/string_view \ | 
 | 295 |   external/libcxx/include/__string external/libcxx/include/cwchar \ | 
 | 296 |   external/libcxx/include/cwctype external/libcxx/include/cctype \ | 
 | 297 |   external/libcxx/include/ctype.h \ | 
 | 298 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/ctype.h \ | 
 | 299 |   external/libcxx/include/wctype.h \ | 
 | 300 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/wctype.h \ | 
 | 301 |   external/ninja/src/graph.h external/ninja/src/eval_env.h \ | 
 | 302 |   external/ninja/src/string_piece.h external/ninja/src/timestamp.h \ | 
 | 303 |   external/ninja/src/util.h external/ninja/src/exit_status.h \ | 
 | 304 |   external/ninja/src/line_printer.h external/ninja/src/metrics.h \ | 
 | 305 |   external/ninja/src/build_log.h external/ninja/src/hash_map.h \ | 
 | 306 |   external/libcxx/include/unordered_map \ | 
 | 307 |   external/libcxx/include/__hash_table external/libcxx/include/cmath \ | 
 | 308 |   external/libcxx/include/math.h \ | 
 | 309 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/math.h \ | 
 | 310 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/huge_val.h \ | 
 | 311 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/huge_valf.h \ | 
 | 312 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/huge_vall.h \ | 
 | 313 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/inf.h \ | 
 | 314 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/nan.h \ | 
 | 315 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/mathdef.h \ | 
 | 316 |   prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/sysroot/usr/include/x86_64-linux-gnu/bits/mathcalls.h \ | 
 | 317 |   external/ninja/src/deps_log.h external/ninja/src/clean.h \ | 
 | 318 |   external/ninja/src/debug_flags.h external/ninja/src/disk_interface.h \ | 
 | 319 |   external/ninja/src/graphviz.h external/ninja/src/manifest_parser.h \ | 
 | 320 |   external/ninja/src/lexer.h external/ninja/src/state.h \ | 
 | 321 |   external/ninja/src/version.h`) | 
 | 322 | 	tmpfile.Close() | 
 | 323 | 	if err != nil { | 
 | 324 | 		b.Fatal("Failed to write dep file:", err) | 
 | 325 | 	} | 
 | 326 | 	b.ResetTimer() | 
 | 327 |  | 
 | 328 | 	for n := 0; n < b.N; n++ { | 
 | 329 | 		depfile, err := ioutil.ReadFile(tmpfile.Name()) | 
 | 330 | 		if err != nil { | 
 | 331 | 			b.Fatal("Failed to read dep file:", err) | 
 | 332 | 		} | 
 | 333 |  | 
 | 334 | 		_, err = Parse(tmpfile.Name(), bytes.NewBuffer(depfile)) | 
 | 335 | 		if err != nil { | 
 | 336 | 			b.Fatal("Failed to parse:", err) | 
 | 337 | 		} | 
 | 338 | 	} | 
 | 339 | } | 
 | 340 |  | 
 | 341 | func TestDepPrint(t *testing.T) { | 
 | 342 | 	testCases := []struct { | 
 | 343 | 		name   string | 
 | 344 | 		input  Deps | 
 | 345 | 		output string | 
 | 346 | 	}{ | 
 | 347 | 		{ | 
 | 348 | 			name: "Empty", | 
 | 349 | 			input: Deps{ | 
 | 350 | 				Output: "a", | 
 | 351 | 			}, | 
 | 352 | 			output: "a:", | 
 | 353 | 		}, | 
 | 354 | 		{ | 
 | 355 | 			name: "Basic", | 
 | 356 | 			input: Deps{ | 
 | 357 | 				Output: "a", | 
 | 358 | 				Inputs: []string{"b", "c"}, | 
 | 359 | 			}, | 
 | 360 | 			output: "a: b c", | 
 | 361 | 		}, | 
 | 362 | 		{ | 
 | 363 | 			name: "Escapes", | 
 | 364 | 			input: Deps{ | 
 | 365 | 				Output: `\!\@#$\%\^\&\`, | 
 | 366 | 			}, | 
 | 367 | 			output: `\\!\\@\#$$\\%\\^\\&\\:`, | 
 | 368 | 		}, | 
 | 369 | 		{ | 
 | 370 | 			name: "Spaces", | 
 | 371 | 			input: Deps{ | 
 | 372 | 				Output: "a b", | 
 | 373 | 				Inputs: []string{"c d", "e f "}, | 
 | 374 | 			}, | 
 | 375 | 			output: `a\ b: c\ d e\ f\ `, | 
 | 376 | 		}, | 
 | 377 | 		{ | 
 | 378 | 			name: "SpecialChars", | 
 | 379 | 			input: Deps{ | 
 | 380 | 				Output: "C:/Program Files (x86)/Microsoft crtdefs.h", | 
 | 381 | 				Inputs: []string{ | 
 | 382 | 					"en@quot.header~", | 
 | 383 | 					"t+t-x!1", | 
 | 384 | 					"openldap/slapd.d/cnconfig/cnschema/cn{0}core.ldif", | 
 | 385 | 					"Fu\303\244ball", | 
 | 386 | 				}, | 
 | 387 | 			}, | 
 | 388 | 			output: `C\:/Program\ Files\ (x86)/Microsoft\ crtdefs.h: en@quot.header~ t+t-x!1 openldap/slapd.d/cnconfig/cnschema/cn{0}core.ldif Fu` + "\303\244ball", | 
 | 389 | 		}, | 
 | 390 | 	} | 
 | 391 |  | 
 | 392 | 	for _, tc := range testCases { | 
 | 393 | 		t.Run(tc.name, func(t *testing.T) { | 
 | 394 | 			out := tc.input.Print() | 
 | 395 | 			outStr := string(out) | 
 | 396 | 			want := tc.output + "\n" | 
 | 397 |  | 
 | 398 | 			if outStr != want { | 
 | 399 | 				t.Errorf("output doesn't match:\nwant:%q\n got:%q", want, outStr) | 
 | 400 | 			} | 
 | 401 | 		}) | 
 | 402 | 	} | 
 | 403 | } |