Add a dependency fixer for proto deps

protoc dependency files, at least for C++ outputs, uses the form of:

  a/b.c \
  a/b.h: <dep1> <dep2>...

Ninja will fail the command when it parses a dep file and there's more
than one output file (even though it doesn't care what the output file
name is). So this tool will parse the original file, and output a
version with only a single output file.

Bug: 67329638
Test: NINJA_ARGS="-t deps ...pb.c" m
Test: NINJA_ARGS="-t deps ...srcjar" m
Test: NINJA_ARGS="-t deps ...srcszip" m
Test: Run dep_fixer across all of taimen's dep files, no failures.
Test: Run dep_fixer against the processed files, no changes.
Test: Run androidmk across all of our Android.mk files, inspect the diffs
Change-Id: I4263b7d5faea37285afa6b24dedf5964aa7d19dc
diff --git a/androidmk/parser/parser_test.go b/androidmk/parser/parser_test.go
new file mode 100644
index 0000000..f562c29
--- /dev/null
+++ b/androidmk/parser/parser_test.go
@@ -0,0 +1,61 @@
+// Copyright 2018 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package parser
+
+import (
+	"bytes"
+	"testing"
+)
+
+var parserTestCases = []struct {
+	name string
+	in   string
+	out  []Node
+}{
+	{
+		name: "Escaped $",
+		in:   `a$$ b: c`,
+		out: []Node{
+			&Rule{
+				Target:        SimpleMakeString("a$ b", NoPos),
+				Prerequisites: SimpleMakeString("c", NoPos),
+			},
+		},
+	},
+}
+
+func TestParse(t *testing.T) {
+	for _, test := range parserTestCases {
+		t.Run(test.name, func(t *testing.T) {
+			p := NewParser(test.name, bytes.NewBufferString(test.in))
+			got, errs := p.Parse()
+
+			if len(errs) != 0 {
+				t.Fatalf("Unexpected errors while parsing: %v", errs)
+			}
+
+			if len(got) != len(test.out) {
+				t.Fatalf("length mismatch, expected %d nodes, got %d", len(test.out), len(got))
+			}
+
+			for i := range got {
+				if got[i].Dump() != test.out[i].Dump() {
+					t.Errorf("incorrect node %d:\nexpected: %#v (%s)\n     got: %#v (%s)",
+						i, test.out[i], test.out[i].Dump(), got[i], got[i].Dump())
+				}
+			}
+		})
+	}
+}