| OLD | NEW |
| 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 raise GNException("Dictionary key is not a string.") | 56 raise GNException("Dictionary key is not a string.") |
| 57 result += "%s = %s\n" % (key, ToGNString(value[key], False)) | 57 result += "%s = %s\n" % (key, ToGNString(value[key], False)) |
| 58 return result | 58 return result |
| 59 | 59 |
| 60 if isinstance(value, int): | 60 if isinstance(value, int): |
| 61 return str(value) | 61 return str(value) |
| 62 | 62 |
| 63 raise GNException("Unsupported type when printing to GN.") | 63 raise GNException("Unsupported type when printing to GN.") |
| 64 | 64 |
| 65 | 65 |
| 66 def FromGNString(input): | 66 def FromGNString(input_string): |
| 67 """Converts the input string from a GN serialized value to Python values. | 67 """Converts the input string from a GN serialized value to Python values. |
| 68 | 68 |
| 69 For details on supported types see GNValueParser.Parse() below. | 69 For details on supported types see GNValueParser.Parse() below. |
| 70 | 70 |
| 71 If your GN script did: | 71 If your GN script did: |
| 72 something = [ "file1", "file2" ] | 72 something = [ "file1", "file2" ] |
| 73 args = [ "--values=$something" ] | 73 args = [ "--values=$something" ] |
| 74 The command line would look something like: | 74 The command line would look something like: |
| 75 --values="[ \"file1\", \"file2\" ]" | 75 --values="[ \"file1\", \"file2\" ]" |
| 76 Which when interpreted as a command line gives the value: | 76 Which when interpreted as a command line gives the value: |
| (...skipping 15 matching lines...) Expand all Loading... |
| 92 Will yield the command line: | 92 Will yield the command line: |
| 93 asdf --value=asdf | 93 asdf --value=asdf |
| 94 The unquoted asdf string will not be valid input to this function, which | 94 The unquoted asdf string will not be valid input to this function, which |
| 95 accepts only quoted strings like GN scripts. In such cases, you can just use | 95 accepts only quoted strings like GN scripts. In such cases, you can just use |
| 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_string) |
| 103 return parser.Parse() | 103 return parser.Parse() |
| 104 | 104 |
| 105 | 105 |
| 106 def FromGNArgs(input): | 106 def FromGNArgs(input_string): |
| 107 """Converts a string with a bunch of gn arg assignments into a Python dict. | 107 """Converts a string with a bunch of gn arg assignments into a Python dict. |
| 108 | 108 |
| 109 Given a whitespace-separated list of | 109 Given a whitespace-separated list of |
| 110 | 110 |
| 111 <ident> = (integer | string | boolean | <list of the former>) | 111 <ident> = (integer | string | boolean | <list of the former>) |
| 112 | 112 |
| 113 gn assignments, this returns a Python dict, i.e.: | 113 gn assignments, this returns a Python dict, i.e.: |
| 114 | 114 |
| 115 FromGNArgs("foo=true\nbar=1\n") -> { 'foo': True, 'bar': 1 }. | 115 FromGNArgs("foo=true\nbar=1\n") -> { 'foo': True, 'bar': 1 }. |
| 116 | 116 |
| 117 Only simple types and lists supported; variables, structs, calls | 117 Only simple types and lists supported; variables, structs, calls |
| 118 and other, more complicated things are not. | 118 and other, more complicated things are not. |
| 119 | 119 |
| 120 This routine is meant to handle only the simple sorts of values that | 120 This routine is meant to handle only the simple sorts of values that |
| 121 arise in parsing --args. | 121 arise in parsing --args. |
| 122 """ | 122 """ |
| 123 parser = GNValueParser(input) | 123 parser = GNValueParser(input_string) |
| 124 return parser.ParseArgs() | 124 return parser.ParseArgs() |
| 125 | 125 |
| 126 | 126 |
| 127 def UnescapeGNString(value): | 127 def UnescapeGNString(value): |
| 128 """Given a string with GN escaping, returns the unescaped string. | 128 """Given a string with GN escaping, returns the unescaped string. |
| 129 | 129 |
| 130 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 |
| 131 '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 |
| 132 fed into the GN unescaper.""" | 132 fed into the GN unescaper.""" |
| 133 result = '' | 133 result = '' |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 elif next_char == '"': | 230 elif next_char == '"': |
| 231 return self.ParseString() | 231 return self.ParseString() |
| 232 elif self._ConstantFollows('true'): | 232 elif self._ConstantFollows('true'): |
| 233 return True | 233 return True |
| 234 elif self._ConstantFollows('false'): | 234 elif self._ConstantFollows('false'): |
| 235 return False | 235 return False |
| 236 else: | 236 else: |
| 237 raise GNException("Unexpected token: " + self.input[self.cur:]) | 237 raise GNException("Unexpected token: " + self.input[self.cur:]) |
| 238 | 238 |
| 239 def _ParseIdent(self): | 239 def _ParseIdent(self): |
| 240 id = '' | 240 ident = '' |
| 241 | 241 |
| 242 next_char = self.input[self.cur] | 242 next_char = self.input[self.cur] |
| 243 if not next_char.isalpha() and not next_char=='_': | 243 if not next_char.isalpha() and not next_char=='_': |
| 244 raise GNException("Expected an identifier: " + self.input[self.cur:]) | 244 raise GNException("Expected an identifier: " + self.input[self.cur:]) |
| 245 | 245 |
| 246 id += next_char | 246 ident += next_char |
| 247 self.cur += 1 | 247 self.cur += 1 |
| 248 | 248 |
| 249 next_char = self.input[self.cur] | 249 next_char = self.input[self.cur] |
| 250 while next_char.isalpha() or next_char.isdigit() or next_char=='_': | 250 while next_char.isalpha() or next_char.isdigit() or next_char=='_': |
| 251 id += next_char | 251 ident += next_char |
| 252 self.cur += 1 | 252 self.cur += 1 |
| 253 next_char = self.input[self.cur] | 253 next_char = self.input[self.cur] |
| 254 | 254 |
| 255 return id | 255 return ident |
| 256 | 256 |
| 257 def ParseNumber(self): | 257 def ParseNumber(self): |
| 258 self.ConsumeWhitespace() | 258 self.ConsumeWhitespace() |
| 259 if self.IsDone(): | 259 if self.IsDone(): |
| 260 raise GNException('Expected number but got nothing.') | 260 raise GNException('Expected number but got nothing.') |
| 261 | 261 |
| 262 begin = self.cur | 262 begin = self.cur |
| 263 | 263 |
| 264 # The first character can include a negative sign. | 264 # The first character can include a negative sign. |
| 265 if not self.IsDone() and _IsDigitOrMinus(self.input[self.cur]): | 265 if not self.IsDone() and _IsDigitOrMinus(self.input[self.cur]): |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 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 |
| 343 returns true. Otherwise, returns false and the current position is | 343 returns true. Otherwise, returns false and the current position is |
| 344 unchanged.""" | 344 unchanged.""" |
| 345 end = self.cur + len(constant) | 345 end = self.cur + len(constant) |
| 346 if end > len(self.input): | 346 if end > len(self.input): |
| 347 return False # Not enough room. | 347 return False # Not enough room. |
| 348 if self.input[self.cur:end] == constant: | 348 if self.input[self.cur:end] == constant: |
| 349 self.cur = end | 349 self.cur = end |
| 350 return True | 350 return True |
| 351 return False | 351 return False |
| OLD | NEW |