| # Copyright 2014 The Chromium Authors. All rights reserved. | 
 | # Use of this source code is governed by a BSD-style license that can be | 
 | # found in the LICENSE file. | 
 | """Helper functions useful when writing scripts that are run from GN's | 
 | exec_script function.""" | 
 |  | 
 |  | 
 | import sys | 
 |  | 
 |  | 
 | class GNException(Exception): | 
 |     pass | 
 |  | 
 |  | 
 | # Computes ASCII code of an element of encoded Python 2 str / Python 3 bytes. | 
 | _Ord = ord if sys.version_info.major < 3 else lambda c: c | 
 |  | 
 |  | 
 | def _TranslateToGnChars(s): | 
 |     for decoded_ch in s.encode('utf-8'):  # str in Python 2, bytes in Python 3. | 
 |         code = _Ord(decoded_ch)  # int | 
 |         if code in (34, 36, 92):  # For '"', '$', or '\\'. | 
 |             yield '\\' + chr(code) | 
 |         elif 32 <= code < 127: | 
 |             yield chr(code) | 
 |         else: | 
 |             yield '$0x%02X' % code | 
 |  | 
 |  | 
 | def ToGNString(value, allow_dicts=True): | 
 |     """Returns a stringified GN equivalent of a Python value. | 
 |  | 
 |   allow_dicts indicates if this function will allow converting dictionaries | 
 |   to GN scopes. This is only possible at the top level, you can't nest a | 
 |   GN scope in a list, so this should be set to False for recursive calls.""" | 
 |     if isinstance(value, str) or isinstance(value, unicode): | 
 |         if value.find('\n') >= 0: | 
 |             raise GNException("Trying to print a string with a newline in it.") | 
 |         return '"' + ''.join(_TranslateToGnChars(value)) + '"' | 
 |  | 
 |     if isinstance(value, list): | 
 |         return '[ %s ]' % ', '.join(ToGNString(v, False) for v in value) | 
 |  | 
 |     if isinstance(value, dict): | 
 |         if not allow_dicts: | 
 |             raise GNException("Attempting to recursively print a dictionary.") | 
 |         result = "" | 
 |         for key in value: | 
 |             if not isinstance(key, str): | 
 |                 raise GNException("Dictionary key is not a string.") | 
 |             result += "%s = %s\n" % (key, ToGNString(value[key], False)) | 
 |         return result | 
 |  | 
 |     if isinstance(value, int): | 
 |         return str(value) | 
 |  | 
 |     raise GNException("Unsupported type %s (value %s) when printing to GN." % | 
 |                       (type(value), value)) |