Add soong_build primary builder

Initial build logic for building android with soong.  It can build
a variety of C and C++ files for arm/arm64 and host.

Change-Id: I10eb37c2c2a50be6af1bb5fd568c0962b9476bf0
diff --git a/androidmk/parser/make_strings.go b/androidmk/parser/make_strings.go
new file mode 100644
index 0000000..558853f
--- /dev/null
+++ b/androidmk/parser/make_strings.go
@@ -0,0 +1,170 @@
+package parser
+
+import (
+	"strings"
+	"text/scanner"
+	"unicode"
+)
+
+// A MakeString is a string that may contain variable substitutions in it.
+// It can be considered as an alternating list of raw Strings and variable
+// substitutions, where the first and last entries in the list must be raw
+// Strings (possibly empty).  A MakeString that starts with a variable
+// will have an empty first raw string, and a MakeString that ends with a
+// variable will have an empty last raw string.  Two sequential Variables
+// will have an empty raw string between them.
+//
+// The MakeString is stored as two lists, a list of raw Strings and a list
+// of Variables.  The raw string list is always one longer than the variable
+// list.
+type MakeString struct {
+	Pos       scanner.Position
+	Strings   []string
+	Variables []Variable
+}
+
+func SimpleMakeString(s string, pos scanner.Position) *MakeString {
+	return &MakeString{
+		Pos:     pos,
+		Strings: []string{s},
+	}
+}
+
+func (ms *MakeString) appendString(s string) {
+	if len(ms.Strings) == 0 {
+		ms.Strings = []string{s}
+		return
+	} else {
+		ms.Strings[len(ms.Strings)-1] += s
+	}
+}
+
+func (ms *MakeString) appendVariable(v Variable) {
+	if len(ms.Strings) == 0 {
+		ms.Strings = []string{"", ""}
+		ms.Variables = []Variable{v}
+	} else {
+		ms.Strings = append(ms.Strings, "")
+		ms.Variables = append(ms.Variables, v)
+	}
+}
+
+func (ms *MakeString) appendMakeString(other *MakeString) {
+	last := len(ms.Strings) - 1
+	ms.Strings[last] += other.Strings[0]
+	ms.Strings = append(ms.Strings, other.Strings[1:]...)
+	ms.Variables = append(ms.Variables, other.Variables...)
+}
+
+func (ms *MakeString) Value(scope Scope) string {
+	if len(ms.Strings) == 0 {
+		return ""
+	} else {
+		ret := ms.Strings[0]
+		for i := range ms.Strings[1:] {
+			ret += ms.Variables[i].Value(scope)
+			ret += ms.Strings[i+1]
+		}
+		return ret
+	}
+}
+
+func (ms *MakeString) Dump() string {
+	if len(ms.Strings) == 0 {
+		return ""
+	} else {
+		ret := ms.Strings[0]
+		for i := range ms.Strings[1:] {
+			ret += ms.Variables[i].Dump()
+			ret += ms.Strings[i+1]
+		}
+		return ret
+	}
+}
+
+func (ms *MakeString) Const() bool {
+	return len(ms.Strings) <= 1
+}
+
+func (ms *MakeString) Empty() bool {
+	return len(ms.Strings) == 0 || (len(ms.Strings) == 1 && ms.Strings[0] == "")
+}
+
+func (ms *MakeString) Split(sep string) []*MakeString {
+	return ms.SplitN(sep, -1)
+}
+
+func (ms *MakeString) SplitN(sep string, n int) []*MakeString {
+	ret := []*MakeString{}
+
+	curMs := SimpleMakeString("", ms.Pos)
+
+	var i int
+	var s string
+	for i, s = range ms.Strings {
+		if n != 0 {
+			split := splitAnyN(s, sep, n)
+			if n != -1 {
+				if len(split) > n {
+					panic("oops!")
+				} else {
+					n -= len(split)
+				}
+			}
+			curMs.appendString(split[0])
+
+			for _, r := range split[1:] {
+				ret = append(ret, curMs)
+				curMs = SimpleMakeString(r, ms.Pos)
+			}
+		} else {
+			curMs.appendString(s)
+		}
+
+		if i < len(ms.Strings)-1 {
+			curMs.appendVariable(ms.Variables[i])
+		}
+	}
+
+	ret = append(ret, curMs)
+	return ret
+}
+
+func (ms *MakeString) TrimLeftSpaces() {
+	ms.Strings[0] = strings.TrimLeftFunc(ms.Strings[0], unicode.IsSpace)
+}
+
+func (ms *MakeString) TrimRightSpaces() {
+	last := len(ms.Strings) - 1
+	ms.Strings[last] = strings.TrimRightFunc(ms.Strings[last], unicode.IsSpace)
+}
+
+func (ms *MakeString) TrimRightOne() {
+	last := len(ms.Strings) - 1
+	if len(ms.Strings[last]) > 1 {
+		ms.Strings[last] = ms.Strings[last][0 : len(ms.Strings[last])-1]
+	}
+}
+
+func (ms *MakeString) EndsWith(ch rune) bool {
+	s := ms.Strings[len(ms.Strings)-1]
+	return s[len(s)-1] == uint8(ch)
+}
+
+func splitAnyN(s, sep string, n int) []string {
+	ret := []string{}
+	for n == -1 || n > 1 {
+		index := strings.IndexAny(s, sep)
+		if index >= 0 {
+			ret = append(ret, s[0:index])
+			s = s[index+1:]
+			if n > 0 {
+				n--
+			}
+		} else {
+			break
+		}
+	}
+	ret = append(ret, s)
+	return ret
+}