Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (C) 2013 Google Inc. All rights reserved. | 1 # Copyright (C) 2013 Google Inc. All rights reserved. |
| 2 # | 2 # |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
| 5 # met: | 5 # met: |
| 6 # | 6 # |
| 7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following disclaimer | 10 # copyright notice, this list of conditions and the following disclaimer |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 # with which to validate arguments against known names. | 41 # with which to validate arguments against known names. |
| 42 # Sequence types as default values will produce sequences | 42 # Sequence types as default values will produce sequences |
| 43 # as parse results. | 43 # as parse results. |
| 44 # Bare arguments (no '=') are treated as names with value True. | 44 # Bare arguments (no '=') are treated as names with value True. |
| 45 # The first field will always be labeled 'name'. | 45 # The first field will always be labeled 'name'. |
| 46 # | 46 # |
| 47 # InFile.load_from_path('file.in', {'arg': None, 'arg2': []}) | 47 # InFile.load_from_path('file.in', {'arg': None, 'arg2': []}) |
| 48 # | 48 # |
| 49 # Parsing produces an array of dictionaries: | 49 # Parsing produces an array of dictionaries: |
| 50 # [ { 'name' : 'name1', 'arg' :' value', arg2=['value2', 'value3'] } | 50 # [ { 'name' : 'name1', 'arg' :' value', arg2=['value2', 'value3'] } |
| 51 | |
| 52 def _is_comment(line): | |
| 53 return line.startswith("//") or line.startswith("#") | |
| 54 | |
| 51 class InFile(object): | 55 class InFile(object): |
| 52 def __init__(self, lines, defaults): | 56 def __init__(self, lines, defaults, default_parameters): |
| 53 lines = map(str.strip, lines) | 57 self.name_dictionaries = [] |
| 54 lines = filter(lambda line: line and not line.startswith("//"), lines) | 58 self.parameters = copy.deepcopy(default_parameters if default_parameters else {}) |
| 55 self.name_dictionaries = [self._parse_line(line, defaults) for line in l ines] | 59 self._defaults = defaults |
| 60 self._parse(map(str.strip, lines)) | |
| 56 | 61 |
| 57 @classmethod | 62 @classmethod |
| 58 def load_from_path(self, path, defaults): | 63 def load_from_path(self, path, defaults, default_parameters): |
| 59 with open(os.path.abspath(path)) as in_file: | 64 with open(os.path.abspath(path)) as in_file: |
| 60 return InFile(in_file.readlines(), defaults) | 65 return InFile(in_file.readlines(), defaults, default_parameters) |
| 61 | 66 |
| 62 def _is_sequence(self, arg): | 67 def _is_sequence(self, arg): |
| 63 return (not hasattr(arg, "strip") | 68 return (not hasattr(arg, "strip") |
| 64 and hasattr(arg, "__getitem__") | 69 and hasattr(arg, "__getitem__") |
| 65 or hasattr(arg, "__iter__")) | 70 or hasattr(arg, "__iter__")) |
| 66 | 71 |
| 67 def _parse_line(self, line, defaults): | 72 def _parse(self, lines): |
| 68 args = copy.deepcopy(defaults) | 73 parsing_parameters = True |
| 74 for line in lines: | |
| 75 if _is_comment(line): | |
| 76 continue | |
| 77 if not line: | |
|
eseidel
2013/04/30 21:46:16
So a leading newline (between the comments and the
abarth-chromium
2013/04/30 21:50:44
I'm just matching the behavior of the Perl "in" fi
| |
| 78 parsing_parameters = False | |
| 79 continue | |
| 80 if parsing_parameters: | |
| 81 self._parse_parameter(line) | |
| 82 else: | |
| 83 self.name_dictionaries.append(self._parse_line(line)) | |
| 84 | |
| 85 def _parse_parameter(self, line): | |
| 86 if '=' in line: | |
| 87 name, value = line.split('=') | |
| 88 else: | |
| 89 name, value = line, True | |
|
eseidel
2013/04/30 21:46:16
If we don't support bare parameters, then paramete
abarth-chromium
2013/04/30 21:50:44
The Perl supports parameters that lack a =. I don
| |
| 90 if not name in self.parameters: | |
| 91 self._fatal("Unknown parameter: '%s' in line:\n%s\nKnown parameters: %s" % (name, line, self.parameters.keys())) | |
| 92 self.parameters[name] = value | |
| 93 | |
| 94 def _parse_line(self, line): | |
| 95 args = copy.deepcopy(self._defaults) | |
| 69 parts = line.split(' ') | 96 parts = line.split(' ') |
| 70 args['name'] = parts[0] | 97 args['name'] = parts[0] |
| 71 # re-join the rest of the line and split on ',' | 98 # re-join the rest of the line and split on ',' |
| 72 args_list = ' '.join(parts[1:]).strip().split(',') | 99 args_list = ' '.join(parts[1:]).strip().split(',') |
| 73 for arg_string in args_list: | 100 for arg_string in args_list: |
| 74 arg_string = arg_string.strip() | 101 arg_string = arg_string.strip() |
| 75 if not arg_string: # Ignore empty args | 102 if not arg_string: # Ignore empty args |
| 76 continue | 103 continue |
| 77 if '=' in arg_string: | 104 if '=' in arg_string: |
| 78 arg_name, arg_value = arg_string.split('=') | 105 arg_name, arg_value = arg_string.split('=') |
| 79 else: | 106 else: |
| 80 arg_name, arg_value = arg_string, True | 107 arg_name, arg_value = arg_string, True |
| 81 if arg_name not in defaults: | 108 if arg_name not in self._defaults: |
| 82 # FIXME: This should probably raise instead of exit(1) | 109 self._fatal("Unknown argument: '%s' in line:\n%s\nKnown argument s: %s" % (arg_name, line, self._defaults.keys())) |
| 83 print "Unknown argument: '%s' in line:\n%s\nKnown arguments: %s" % (arg_name, line, defaults.keys()) | |
| 84 exit(1) | |
| 85 if self._is_sequence(args[arg_name]): | 110 if self._is_sequence(args[arg_name]): |
| 86 args[arg_name].append(arg_value) | 111 args[arg_name].append(arg_value) |
| 87 else: | 112 else: |
| 88 args[arg_name] = arg_value | 113 args[arg_name] = arg_value |
| 89 return args | 114 return args |
| 115 | |
| 116 def _fatal(self, message): | |
| 117 # FIXME: This should probably raise instead of exit(1) | |
| 118 print message | |
| 119 exit(1) | |
| OLD | NEW |