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

Side by Side Diff: core/scripts/in_file.py

Issue 126143003: Update IDL to Chrome 32 (Closed) Base URL: https://dart.googlecode.com/svn/third_party/WebCore
Patch Set: Add new files Created 6 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « core/scripts/action_useragentstylesheets.py ('k') | core/scripts/in_file_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
(Empty)
1 # Copyright (C) 2013 Google Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
5 # met:
6 #
7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the
12 # distribution.
13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 import copy
30 import os
31
32 # NOTE: This has only been used to parse
33 # core/page/RuntimeEnabledFeatures.in and may not be capable
34 # of parsing other .in files correctly.
35
36 # .in file format is:
37 # // comment
38 # name1 arg=value, arg2=value2, arg2=value3
39 #
40 # InFile must be passed a dictionary of default values
41 # with which to validate arguments against known names.
42 # Sequence types as default values will produce sequences
43 # as parse results.
44 # Bare arguments (no '=') are treated as names with value True.
45 # The first field will always be labeled 'name'.
46 #
47 # InFile.load_from_files(['file.in'], {'arg': None, 'arg2': []})
48 #
49 # Parsing produces an array of dictionaries:
50 # [ { 'name' : 'name1', 'arg' :' value', arg2=['value2', 'value3'] }
51
52 def _is_comment(line):
53 return line.startswith("//") or line.startswith("#")
54
55 class InFile(object):
56 def __init__(self, lines, defaults, valid_values=None, default_parameters=No ne):
57 self.name_dictionaries = []
58 self.parameters = copy.deepcopy(default_parameters if default_parameters else {})
59 self._defaults = defaults
60 self._valid_values = copy.deepcopy(valid_values if valid_values else {})
61 self._parse(map(str.strip, lines))
62
63 @classmethod
64 def load_from_files(self, file_paths, defaults, valid_values, default_parame ters):
65 lines = []
66 for path in file_paths:
67 with open(os.path.abspath(path)) as in_file:
68 lines += in_file.readlines()
69 return InFile(lines, defaults, valid_values, default_parameters)
70
71 def _is_sequence(self, arg):
72 return (not hasattr(arg, "strip")
73 and hasattr(arg, "__getitem__")
74 or hasattr(arg, "__iter__"))
75
76 def _parse(self, lines):
77 parsing_parameters = True
78 indices = {}
79 for line in lines:
80 if _is_comment(line):
81 continue
82 if not line:
83 parsing_parameters = False
84 continue
85 if parsing_parameters:
86 self._parse_parameter(line)
87 else:
88 entry = self._parse_line(line)
89 name = entry['name']
90 if name in indices:
91 entry = self._merge_entries(entry, self.name_dictionaries[in dices[name]])
92 entry['name'] = name
93 self.name_dictionaries[indices[name]] = entry
94 else:
95 indices[name] = len(self.name_dictionaries)
96 self.name_dictionaries.append(entry)
97
98
99 def _merge_entries(self, one, two):
100 merged = {}
101 for key in one:
102 if key not in two:
103 self._fatal("Expected key '%s' not found in entry: %s" % (key, t wo))
104 if one[key] and two[key]:
105 val_one = one[key]
106 val_two = two[key]
107 if isinstance(val_one, list) and isinstance(val_two, list):
108 val = val_one + val_two
109 elif isinstance(val_one, list):
110 val = val_one + [val_two]
111 elif isinstance(val_two, list):
112 val = [val_one] + val_two
113 else:
114 val = [val_one, val_two]
115 merged[key] = val
116 elif one[key]:
117 merged[key] = one[key]
118 else:
119 merged[key] = two[key]
120 return merged
121
122
123 def _parse_parameter(self, line):
124 if '=' in line:
125 name, value = line.split('=')
126 else:
127 name, value = line, True
128 if not name in self.parameters:
129 self._fatal("Unknown parameter: '%s' in line:\n%s\nKnown parameters: %s" % (name, line, self.parameters.keys()))
130 self.parameters[name] = value
131
132 def _parse_line(self, line):
133 args = copy.deepcopy(self._defaults)
134 parts = line.split(' ')
135 args['name'] = parts[0]
136 # re-join the rest of the line and split on ','
137 args_list = ' '.join(parts[1:]).strip().split(',')
138 for arg_string in args_list:
139 arg_string = arg_string.strip()
140 if not arg_string: # Ignore empty args
141 continue
142 if '=' in arg_string:
143 arg_name, arg_value = arg_string.split('=')
144 else:
145 arg_name, arg_value = arg_string, True
146 if arg_name not in self._defaults:
147 self._fatal("Unknown argument: '%s' in line:\n%s\nKnown argument s: %s" % (arg_name, line, self._defaults.keys()))
148 valid_values = self._valid_values.get(arg_name)
149 if valid_values and arg_value not in valid_values:
150 self._fatal("Unknown value: '%s' in line:\n%s\nKnown values: %s" % (arg_value, line, valid_values))
151 if self._is_sequence(args[arg_name]):
152 args[arg_name].append(arg_value)
153 else:
154 args[arg_name] = arg_value
155 return args
156
157 def _fatal(self, message):
158 # FIXME: This should probably raise instead of exit(1)
159 print message
160 exit(1)
OLDNEW
« no previous file with comments | « core/scripts/action_useragentstylesheets.py ('k') | core/scripts/in_file_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698