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

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: allow lists in args 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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 the Python string literal directly. 96 the Python string literal directly.
97 97
98 The main use cases for this is for other types, in particular lists. When 98 The main use cases for this is for other types, in particular lists. When
99 using string interpolation on a list (as in the top example) the embedded 99 using string interpolation on a list (as in the top example) the embedded
100 strings will be quoted and escaped according to GN rules so the list can be 100 strings will be quoted and escaped according to GN rules so the list can be
101 re-parsed to get the same result.""" 101 re-parsed to get the same result."""
102 parser = GNValueParser(input) 102 parser = GNValueParser(input)
103 return parser.Parse() 103 return parser.Parse()
104 104
105 105
106 def FromGNArgs(input):
107 """Converts a string with a bunch of gn arg assignments into a Python dict.
108
109 Given a whitespace-separated list of
110
111 <ident> = (integer | string | boolean | <list of the former>)
112
113 gn assignments, this returns a Python dict, i.e.:
114
115 FromGNArgs("foo=true\nbar=1\n") -> { 'foo': True, 'bar': 1 }.
116
117 Only simple types and lists supported; variables, structs, calls
118 and other, more complicated things are not.
119
120 This routine is meant to handle only the simple sorts of values that
121 arise in parsing --args.
122 """
123 parser = GNValueParser(input)
124 return parser.ParseArgs()
125
126
106 def UnescapeGNString(value): 127 def UnescapeGNString(value):
107 """Given a string with GN escaping, returns the unescaped string. 128 """Given a string with GN escaping, returns the unescaped string.
108 129
109 Be careful not to feed with input from a Python parsing function like 130 Be careful not to feed with input from a Python parsing function like
110 'ast' because it will do Python unescaping, which will be incorrect when 131 'ast' because it will do Python unescaping, which will be incorrect when
111 fed into the GN unescaper.""" 132 fed into the GN unescaper."""
112 result = '' 133 result = ''
113 i = 0 134 i = 0
114 while i < len(value): 135 while i < len(value):
115 if value[i] == '\\': 136 if value[i] == '\\':
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 - GN lists ('[1, "asdf", 3]') will be converted to Python lists. 188 - GN lists ('[1, "asdf", 3]') will be converted to Python lists.
168 189
169 - GN scopes ('{ ... }') are not supported.""" 190 - GN scopes ('{ ... }') are not supported."""
170 result = self._ParseAllowTrailing() 191 result = self._ParseAllowTrailing()
171 self.ConsumeWhitespace() 192 self.ConsumeWhitespace()
172 if not self.IsDone(): 193 if not self.IsDone():
173 raise GNException("Trailing input after parsing:\n " + 194 raise GNException("Trailing input after parsing:\n " +
174 self.input[self.cur:]) 195 self.input[self.cur:])
175 return result 196 return result
176 197
198 def ParseArgs(self):
199 """Converts a whitespace-separated list of ident=literals to a dict.
200
201 See additional usage notes on FromGNArgs, above.
202 """
203 d = {}
204
205 self.ConsumeWhitespace()
206 while not self.IsDone():
207 ident = self._ParseIdent()
208 self.ConsumeWhitespace()
209 if self.input[self.cur] != '=':
210 raise GNException("Unexpected token: " + self.input[self.cur:])
211 self.cur += 1
212 self.ConsumeWhitespace()
213 val = self._ParseAllowTrailing()
214 self.ConsumeWhitespace()
215 d[ident] = val
216
217 return d
218
177 def _ParseAllowTrailing(self): 219 def _ParseAllowTrailing(self):
178 """Internal version of Parse that doesn't check for trailing stuff.""" 220 """Internal version of Parse that doesn't check for trailing stuff."""
179 self.ConsumeWhitespace() 221 self.ConsumeWhitespace()
180 if self.IsDone(): 222 if self.IsDone():
181 raise GNException("Expected input to parse.") 223 raise GNException("Expected input to parse.")
182 224
183 next_char = self.input[self.cur] 225 next_char = self.input[self.cur]
184 if next_char == '[': 226 if next_char == '[':
185 return self.ParseList() 227 return self.ParseList()
186 elif _IsDigitOrMinus(next_char): 228 elif _IsDigitOrMinus(next_char):
187 return self.ParseNumber() 229 return self.ParseNumber()
188 elif next_char == '"': 230 elif next_char == '"':
189 return self.ParseString() 231 return self.ParseString()
190 elif self._ConstantFollows('true'): 232 elif self._ConstantFollows('true'):
191 return True 233 return True
192 elif self._ConstantFollows('false'): 234 elif self._ConstantFollows('false'):
193 return False 235 return False
194 else: 236 else:
195 raise GNException("Unexpected token: " + self.input[self.cur:]) 237 raise GNException("Unexpected token: " + self.input[self.cur:])
196 238
239 def _ParseIdent(self):
240 id = ''
241
242 next_char = self.input[self.cur]
243 if not next_char.isalpha() and not next_char=='_':
244 raise GNException("Expected an identifier: " + self.input[self.cur:])
245
246 id += next_char
247 self.cur += 1
248
249 next_char = self.input[self.cur]
250 while next_char.isalpha() or next_char.isdigit() or next_char=='_':
251 id += next_char
252 self.cur += 1
253 next_char = self.input[self.cur]
254
255 return id
256
197 def ParseNumber(self): 257 def ParseNumber(self):
198 self.ConsumeWhitespace() 258 self.ConsumeWhitespace()
199 if self.IsDone(): 259 if self.IsDone():
200 raise GNException('Expected number but got nothing.') 260 raise GNException('Expected number but got nothing.')
201 261
202 begin = self.cur 262 begin = self.cur
203 263
204 # The first character can include a negative sign. 264 # The first character can include a negative sign.
205 if not self.IsDone() and _IsDigitOrMinus(self.input[self.cur]): 265 if not self.IsDone() and _IsDigitOrMinus(self.input[self.cur]):
206 self.cur += 1 266 self.cur += 1
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 location in the input. If it does, the text is consumed and the function 342 location in the input. If it does, the text is consumed and the function
283 returns true. Otherwise, returns false and the current position is 343 returns true. Otherwise, returns false and the current position is
284 unchanged.""" 344 unchanged."""
285 end = self.cur + len(constant) 345 end = self.cur + len(constant)
286 if end > len(self.input): 346 if end > len(self.input):
287 return False # Not enough room. 347 return False # Not enough room.
288 if self.input[self.cur:end] == constant: 348 if self.input[self.cur:end] == constant:
289 self.cur = end 349 self.cur = end
290 return True 350 return True
291 return False 351 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