• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 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
15package main
16
17import (
18	"fmt"
19	"strings"
20
21	mkparser "android/soong/androidmk/parser"
22
23	bpparser "github.com/google/blueprint/parser"
24)
25
26func stringToStringValue(s string) bpparser.Expression {
27	return &bpparser.String{
28		Value: s,
29	}
30}
31
32func stringListToStringValueList(list []string) []bpparser.Expression {
33	valList := make([]bpparser.Expression, len(list))
34	for i, l := range list {
35		valList[i] = stringToStringValue(l)
36	}
37	return valList
38}
39
40func addValues(val1, val2 bpparser.Expression) (bpparser.Expression, error) {
41	if val1 == nil {
42		return val2, nil
43	}
44
45	if val1.Type() == bpparser.StringType && val2.Type() == bpparser.ListType {
46		val1 = &bpparser.List{
47			Values: []bpparser.Expression{val1},
48		}
49	} else if val2.Type() == bpparser.StringType && val1.Type() == bpparser.ListType {
50		val2 = &bpparser.List{
51			Values: []bpparser.Expression{val1},
52		}
53	} else if val1.Type() != val2.Type() {
54		return nil, fmt.Errorf("cannot add mismatched types")
55	}
56
57	return &bpparser.Operator{
58		Operator: '+',
59		Args:     [2]bpparser.Expression{val1, val2},
60	}, nil
61}
62
63func makeToStringExpression(ms *mkparser.MakeString, scope mkparser.Scope) (bpparser.Expression, error) {
64
65	var val bpparser.Expression
66	var err error
67
68	if ms.Strings[0] != "" {
69		val = stringToStringValue(ms.Strings[0])
70	}
71
72	for i, s := range ms.Strings[1:] {
73		if ret, ok := ms.Variables[i].EvalFunction(scope); ok {
74			if len(ret) > 1 {
75				return nil, fmt.Errorf("Unexpected list value %s", ms.Dump())
76			}
77			val, err = addValues(val, stringToStringValue(ret[0]))
78		} else {
79			name := ms.Variables[i].Name
80			if !name.Const() {
81				return nil, fmt.Errorf("Unsupported non-const variable name %s", name.Dump())
82			}
83			tmp := &bpparser.Variable{
84				Name:  name.Value(nil),
85				Value: &bpparser.String{},
86			}
87
88			if tmp.Name == "TOP" {
89				if s[0] == '/' {
90					s = s[1:]
91				} else {
92					s = "." + s
93				}
94			} else {
95				val, err = addValues(val, tmp)
96				if err != nil {
97					return nil, err
98				}
99			}
100		}
101
102		if s != "" {
103			tmp := stringToStringValue(s)
104			val, err = addValues(val, tmp)
105			if err != nil {
106				return nil, err
107			}
108		}
109	}
110
111	return val, nil
112}
113
114func stringToListValue(s string) bpparser.Expression {
115	list := strings.Fields(s)
116	valList := make([]bpparser.Expression, len(list))
117	for i, l := range list {
118		valList[i] = &bpparser.String{
119			Value: l,
120		}
121	}
122	return &bpparser.List{
123		Values: valList,
124	}
125
126}
127
128func makeToListExpression(ms *mkparser.MakeString, scope mkparser.Scope) (bpparser.Expression, error) {
129
130	fields := ms.Split(" \t")
131
132	var listOfListValues []bpparser.Expression
133
134	listValue := &bpparser.List{}
135
136	for _, f := range fields {
137		if len(f.Variables) == 1 && f.Strings[0] == "" && f.Strings[1] == "" {
138			if ret, ok := f.Variables[0].EvalFunction(scope); ok {
139				listValue.Values = append(listValue.Values, stringListToStringValueList(ret)...)
140			} else {
141				// Variable by itself, variable is probably a list
142				if !f.Variables[0].Name.Const() {
143					return nil, fmt.Errorf("unsupported non-const variable name")
144				}
145				if f.Variables[0].Name.Value(nil) == "TOP" {
146					listValue.Values = append(listValue.Values, &bpparser.String{
147						Value: ".",
148					})
149				} else {
150					if len(listValue.Values) > 0 {
151						listOfListValues = append(listOfListValues, listValue)
152					}
153					listOfListValues = append(listOfListValues, &bpparser.Variable{
154						Name:  f.Variables[0].Name.Value(nil),
155						Value: &bpparser.List{},
156					})
157					listValue = &bpparser.List{}
158				}
159			}
160		} else {
161			s, err := makeToStringExpression(f, scope)
162			if err != nil {
163				return nil, err
164			}
165			if s == nil {
166				continue
167			}
168
169			listValue.Values = append(listValue.Values, s)
170		}
171	}
172
173	if len(listValue.Values) > 0 {
174		listOfListValues = append(listOfListValues, listValue)
175	}
176
177	if len(listOfListValues) == 0 {
178		return listValue, nil
179	}
180
181	val := listOfListValues[0]
182	for _, tmp := range listOfListValues[1:] {
183		var err error
184		val, err = addValues(val, tmp)
185		if err != nil {
186			return nil, err
187		}
188	}
189
190	return val, nil
191}
192
193func stringToBoolValue(s string) (bpparser.Expression, error) {
194	var b bool
195	s = strings.TrimSpace(s)
196	switch s {
197	case "true":
198		b = true
199	case "false", "":
200		b = false
201	case "-frtti": // HACK for LOCAL_RTTI_VALUE
202		b = true
203	default:
204		return nil, fmt.Errorf("unexpected bool value %s", s)
205	}
206	return &bpparser.Bool{
207		Value: b,
208	}, nil
209}
210
211func makeToBoolExpression(ms *mkparser.MakeString) (bpparser.Expression, error) {
212	if !ms.Const() {
213		if len(ms.Variables) == 1 && ms.Strings[0] == "" && ms.Strings[1] == "" {
214			name := ms.Variables[0].Name
215			if !name.Const() {
216				return nil, fmt.Errorf("unsupported non-const variable name")
217			}
218			return &bpparser.Variable{
219				Name:  name.Value(nil),
220				Value: &bpparser.Bool{},
221			}, nil
222		} else {
223			return nil, fmt.Errorf("non-const bool expression %s", ms.Dump())
224		}
225	}
226
227	return stringToBoolValue(ms.Value(nil))
228}
229