Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: build/gn_helpers.py

Issue 1847333005: Add FromGNArgs() to gn_helpers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fix_gn_helpers_bools
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | build/gn_helpers_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Helper functions useful when writing scripts that integrate with GN. 5 """Helper functions useful when writing scripts that integrate with GN.
6 6
7 The main functions are ToGNString and FromGNString which convert between 7 The main functions are ToGNString and FromGNString which convert between
8 serialized GN veriables and Python variables. 8 serialized GN veriables and Python variables.
9 9
10 To use in a random python file in the build: 10 To use in a random python file in the build:
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 the Python string literal directly. 93 the Python string literal directly.
94 94
95 The main use cases for this is for other types, in particular lists. When 95 The main use cases for this is for other types, in particular lists. When
96 using string interpolation on a list (as in the top example) the embedded 96 using string interpolation on a list (as in the top example) the embedded
97 strings will be quoted and escaped according to GN rules so the list can be 97 strings will be quoted and escaped according to GN rules so the list can be
98 re-parsed to get the same result.""" 98 re-parsed to get the same result."""
99 parser = GNValueParser(input) 99 parser = GNValueParser(input)
100 return parser.Parse() 100 return parser.Parse()
101 101
102 102
103 def FromGNArgs(input):
104 """Converts a string with a bunch of gn arg assignments into a Python dict.
105
106 Given a whitespace-separated list of
107
108 <ident> = (integer | string | boolean)
109
110 gn assignments, this returns a Python dict, i.e.:
111
112 FromGNArgs("foo=true\nbar=1\n") -> { 'foo': True, 'bar': 1 }.
113
114 Only simple types are supported; variables, complex types, calls
115 and other, more complicated things are not.
116
117 This routine is meant to handle only the simple sorts of values that
118 arise in parsing --args.
119 """
120 parser = GNValueParser(input)
121 return parser.ParseArgs()
122
123
103 def UnescapeGNString(value): 124 def UnescapeGNString(value):
104 """Given a string with GN escaping, returns the unescaped string. 125 """Given a string with GN escaping, returns the unescaped string.
105 126
106 Be careful not to feed with input from a Python parsing function like 127 Be careful not to feed with input from a Python parsing function like
107 'ast' because it will do Python unescaping, which will be incorrect when 128 'ast' because it will do Python unescaping, which will be incorrect when
108 fed into the GN unescaper.""" 129 fed into the GN unescaper."""
109 result = '' 130 result = ''
110 i = 0 131 i = 0
111 while i < len(value): 132 while i < len(value):
112 if value[i] == '\\': 133 if value[i] == '\\':
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 - GN lists ('[1, "asdf", 3]') will be converted to Python lists. 185 - GN lists ('[1, "asdf", 3]') will be converted to Python lists.
165 186
166 - GN scopes ('{ ... }') are not supported.""" 187 - GN scopes ('{ ... }') are not supported."""
167 result = self._ParseAllowTrailing() 188 result = self._ParseAllowTrailing()
168 self.ConsumeWhitespace() 189 self.ConsumeWhitespace()
169 if not self.IsDone(): 190 if not self.IsDone():
170 raise GNException("Trailing input after parsing:\n " + 191 raise GNException("Trailing input after parsing:\n " +
171 self.input[self.cur:]) 192 self.input[self.cur:])
172 return result 193 return result
173 194
174 def _ParseAllowTrailing(self): 195 def ParseArgs(self):
196 """Converts a whitespace-separated list of ident=literals to a dict.
197
198 See additional usage notes on FromGNArgs, above.
199 """
200 d = {}
201
202 self.ConsumeWhitespace()
203 while not self.IsDone():
204 ident = self._ParseIdent()
205 self.ConsumeWhitespace()
206 if self.input[self.cur] != '=':
207 raise GNException("Unexpected token: " + self.input[self.cur:])
208 self.cur += 1
209 self.ConsumeWhitespace()
210 val = self._ParseAllowTrailing(lists_are_allowed=False)
brettw 2016/04/05 19:25:27 It seems like you go through some effort here to d
Dirk Pranke 2016/04/05 19:28:42 I don't remember exactly now, but I have a vague m
211 self.ConsumeWhitespace()
212 d[ident] = val
213
214 return d
215
216 def _ParseAllowTrailing(self, lists_are_allowed=True):
175 """Internal version of Parse that doesn't check for trailing stuff.""" 217 """Internal version of Parse that doesn't check for trailing stuff."""
176 self.ConsumeWhitespace() 218 self.ConsumeWhitespace()
177 if self.IsDone(): 219 if self.IsDone():
178 raise GNException("Expected input to parse.") 220 raise GNException("Expected input to parse.")
179 221
180 next_char = self.input[self.cur] 222 next_char = self.input[self.cur]
181 if next_char == '[': 223 if lists_are_allowed and next_char == '[':
182 return self.ParseList() 224 return self.ParseList()
183 elif _IsDigitOrMinus(next_char): 225 elif _IsDigitOrMinus(next_char):
184 return self.ParseNumber() 226 return self.ParseNumber()
185 elif next_char == '"': 227 elif next_char == '"':
186 return self.ParseString() 228 return self.ParseString()
187 elif self._ConstantFollows('true'): 229 elif self._ConstantFollows('true'):
188 return True 230 return True
189 elif self._ConstantFollows('false'): 231 elif self._ConstantFollows('false'):
190 return False 232 return False
191 else: 233 else:
192 raise GNException("Unexpected token: " + self.input[self.cur:]) 234 raise GNException("Unexpected token: " + self.input[self.cur:])
193 235
236 def _ParseIdent(self):
237 id = ''
238
239 next_char = self.input[self.cur]
240 if not next_char.isalpha() and not next_char=='_':
241 raise GNException("Expected an identifier: " + self.input[self.cur:])
242
243 id += next_char
244 self.cur += 1
245
246 next_char = self.input[self.cur]
247 while next_char.isalpha() or next_char.isdigit() or next_char=='_':
248 id += next_char
249 self.cur += 1
250 next_char = self.input[self.cur]
251
252 return id
253
194 def ParseNumber(self): 254 def ParseNumber(self):
195 self.ConsumeWhitespace() 255 self.ConsumeWhitespace()
196 if self.IsDone(): 256 if self.IsDone():
197 raise GNException('Expected number but got nothing.') 257 raise GNException('Expected number but got nothing.')
198 258
199 begin = self.cur 259 begin = self.cur
200 260
201 # The first character can include a negative sign. 261 # The first character can include a negative sign.
202 if not self.IsDone() and _IsDigitOrMinus(self.input[self.cur]): 262 if not self.IsDone() and _IsDigitOrMinus(self.input[self.cur]):
203 self.cur += 1 263 self.cur += 1
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 location in the input. If it does, the text is consumed and the function 339 location in the input. If it does, the text is consumed and the function
280 returns true. Otherwise, returns false and the current position is 340 returns true. Otherwise, returns false and the current position is
281 unchanged.""" 341 unchanged."""
282 end = self.cur + len(constant) 342 end = self.cur + len(constant)
283 if end > len(self.input): 343 if end > len(self.input):
284 return False # Not enough room. 344 return False # Not enough room.
285 if self.input[self.cur:end] == constant: 345 if self.input[self.cur:end] == constant:
286 self.cur = end 346 self.cur = end
287 return True 347 return True
288 return False 348 return False
OLDNEW
« no previous file with comments | « no previous file | build/gn_helpers_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698