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/make_strings.go b/androidmk/parser/make_strings.go
index e6885a8..4b782a2 100644
--- a/androidmk/parser/make_strings.go
+++ b/androidmk/parser/make_strings.go
@@ -90,10 +90,10 @@
 	if len(ms.Strings) == 0 {
 		return ""
 	} else {
-		ret := ms.Strings[0]
+		ret := unescape(ms.Strings[0])
 		for i := range ms.Strings[1:] {
 			ret += ms.Variables[i].Value(scope)
-			ret += ms.Strings[i+1]
+			ret += unescape(ms.Strings[i+1])
 		}
 		return ret
 	}
@@ -125,6 +125,16 @@
 }
 
 func (ms *MakeString) SplitN(sep string, n int) []*MakeString {
+	return ms.splitNFunc(n, func(s string, n int) []string {
+		return splitAnyN(s, sep, n)
+	})
+}
+
+func (ms *MakeString) Words() []*MakeString {
+	return ms.splitNFunc(-1, splitWords)
+}
+
+func (ms *MakeString) splitNFunc(n int, splitFunc func(s string, n int) []string) []*MakeString {
 	ret := []*MakeString{}
 
 	curMs := SimpleMakeString("", ms.Pos())
@@ -133,7 +143,7 @@
 	var s string
 	for i, s = range ms.Strings {
 		if n != 0 {
-			split := splitAnyN(s, sep, n)
+			split := splitFunc(s, n)
 			if n != -1 {
 				if len(split) > n {
 					panic("oops!")
@@ -156,7 +166,9 @@
 		}
 	}
 
-	ret = append(ret, curMs)
+	if !curMs.Empty() {
+		ret = append(ret, curMs)
+	}
 	return ret
 }
 
@@ -206,3 +218,64 @@
 	ret = append(ret, s)
 	return ret
 }
+
+func splitWords(s string, n int) []string {
+	ret := []string{}
+	preserve := ""
+	for n == -1 || n > 1 {
+		index := strings.IndexAny(s, " \t")
+		if index == 0 && len(preserve) == 0 {
+			s = s[1:]
+		} else if index >= 0 {
+			escapeCount := 0
+			for i := index - 1; i >= 0; i-- {
+				if s[i] != '\\' {
+					break
+				}
+				escapeCount += 1
+			}
+
+			if escapeCount%2 == 1 {
+				preserve += s[0 : index+1]
+				s = s[index+1:]
+				continue
+			}
+
+			ret = append(ret, preserve+s[0:index])
+			s = s[index+1:]
+			preserve = ""
+			if n > 0 {
+				n--
+			}
+		} else {
+			break
+		}
+	}
+	if preserve != "" || s != "" || len(ret) == 0 {
+		ret = append(ret, preserve+s)
+	}
+	return ret
+}
+
+func unescape(s string) string {
+	ret := ""
+	for {
+		index := strings.IndexByte(s, '\\')
+		if index < 0 {
+			break
+		}
+
+		if index+1 == len(s) {
+			break
+		}
+
+		switch s[index+1] {
+		case ' ', '\\', '#', ':', '*', '[', '|', '\t', '\n', '\r':
+			ret += s[:index] + s[index+1:index+2]
+		default:
+			ret += s[:index+2]
+		}
+		s = s[index+2:]
+	}
+	return ret + s
+}