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 """Updates enums in histograms.xml file with values read from provided C++ enum. | 5 """Updates enums in histograms.xml file with values read from provided C++ enum. |
6 | 6 |
7 If the file was pretty-printed, the updated version is pretty-printed too. | 7 If the file was pretty-printed, the updated version is pretty-printed too. |
8 """ | 8 """ |
9 | 9 |
10 import logging | 10 import logging |
(...skipping 15 matching lines...) Expand all Loading... |
26 | 26 |
27 class UserError(Exception): | 27 class UserError(Exception): |
28 def __init__(self, message): | 28 def __init__(self, message): |
29 Exception.__init__(self, message) | 29 Exception.__init__(self, message) |
30 | 30 |
31 @property | 31 @property |
32 def message(self): | 32 def message(self): |
33 return self.args[0] | 33 return self.args[0] |
34 | 34 |
35 | 35 |
| 36 class DuplicatedValue(Exception): |
| 37 """Exception raised for duplicated enum values. |
| 38 |
| 39 Attributes: |
| 40 first_label: First enum label that shares the duplicated enum value. |
| 41 second_label: Second enum label that shares the duplicated enum value. |
| 42 """ |
| 43 def __init__(self, first_label, second_label): |
| 44 self.first_label = first_label |
| 45 self.second_label = second_label |
| 46 |
| 47 |
36 def Log(message): | 48 def Log(message): |
37 logging.info(message) | 49 logging.info(message) |
38 | 50 |
39 | 51 |
40 def ReadHistogramValues(filename, start_marker, end_marker, strip_k_prefix): | 52 def ReadHistogramValues(filename, start_marker, end_marker, strip_k_prefix): |
41 """Returns a dictionary of enum values and a pair of labels that have the same | 53 """Creates a dictionary of enum values, read from a C++ file. |
42 enum values, read from a C++ file. | |
43 | 54 |
44 Args: | 55 Args: |
45 filename: The unix-style path (relative to src/) of the file to open. | 56 filename: The unix-style path (relative to src/) of the file to open. |
46 start_marker: A regex that signifies the start of the enum values. | 57 start_marker: A regex that signifies the start of the enum values. |
47 end_marker: A regex that signifies the end of the enum values. | 58 end_marker: A regex that signifies the end of the enum values. |
48 strip_k_prefix: Set to True if enum values are declared as kFoo and the | 59 strip_k_prefix: Set to True if enum values are declared as kFoo and the |
49 'k' should be stripped. | 60 'k' should be stripped. |
| 61 |
| 62 Returns: |
| 63 A boolean indicating wheather the histograms.xml file would be changed. |
| 64 |
| 65 Raises: |
| 66 DuplicatedValue: An error when two enum labels share the same value. |
50 """ | 67 """ |
51 # Read the file as a list of lines | 68 # Read the file as a list of lines |
52 with open(path_util.GetInputFile(filename)) as f: | 69 with open(path_util.GetInputFile(filename)) as f: |
53 content = f.readlines() | 70 content = f.readlines() |
54 | 71 |
55 START_REGEX = re.compile(start_marker) | 72 START_REGEX = re.compile(start_marker) |
56 ITEM_REGEX = re.compile(r'^(\w+)') | 73 ITEM_REGEX = re.compile(r'^(\w+)') |
57 ITEM_REGEX_WITH_INIT = re.compile(r'(\w+)\s*=\s*(\d*)') | 74 ITEM_REGEX_WITH_INIT = re.compile(r'(\w+)\s*=\s*(\d*)') |
58 WRAPPED_INIT = re.compile(r'(\d+)') | 75 WRAPPED_INIT = re.compile(r'(\d+)') |
59 END_REGEX = re.compile(end_marker) | 76 END_REGEX = re.compile(end_marker) |
(...skipping 25 matching lines...) Expand all Loading... |
85 m = ITEM_REGEX.match(line) | 102 m = ITEM_REGEX.match(line) |
86 if m: | 103 if m: |
87 label = m.group(1) | 104 label = m.group(1) |
88 else: | 105 else: |
89 continue | 106 continue |
90 if strip_k_prefix: | 107 if strip_k_prefix: |
91 assert label.startswith('k'), "Enum " + label + " should start with 'k'." | 108 assert label.startswith('k'), "Enum " + label + " should start with 'k'." |
92 label = label[1:] | 109 label = label[1:] |
93 # If two enum labels have the same value | 110 # If two enum labels have the same value |
94 if enum_value in result: | 111 if enum_value in result: |
95 return result, (result[enum_value], label) | 112 raise DuplicatedValue(result[enum_value], label) |
96 result[enum_value] = label | 113 result[enum_value] = label |
97 enum_value += 1 | 114 enum_value += 1 |
98 return result, None | 115 return result |
99 | 116 |
100 | 117 |
101 def CreateEnumItemNode(document, value, label): | 118 def CreateEnumItemNode(document, value, label): |
102 """Creates an int element to append to an enum.""" | 119 """Creates an int element to append to an enum.""" |
103 item_node = document.createElement('int') | 120 item_node = document.createElement('int') |
104 item_node.attributes['value'] = str(value) | 121 item_node.attributes['value'] = str(value) |
105 item_node.attributes['label'] = label | 122 item_node.attributes['label'] = label |
106 return item_node | 123 return item_node |
107 | 124 |
108 | 125 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 the C++ header file from which to read the enum. | 212 the C++ header file from which to read the enum. |
196 start_marker: A regular expression that matches the start of the C++ enum. | 213 start_marker: A regular expression that matches the start of the C++ enum. |
197 end_marker: A regular expression that matches the end of the C++ enum. | 214 end_marker: A regular expression that matches the end of the C++ enum. |
198 strip_k_prefix: Set to True if enum values are declared as kFoo and the | 215 strip_k_prefix: Set to True if enum values are declared as kFoo and the |
199 'k' should be stripped. | 216 'k' should be stripped. |
200 | 217 |
201 Returns: | 218 Returns: |
202 A string with presubmit failure description, or None (if no failures). | 219 A string with presubmit failure description, or None (if no failures). |
203 """ | 220 """ |
204 Log('Reading histogram enum definition from "{0}".'.format(source_enum_path)) | 221 Log('Reading histogram enum definition from "{0}".'.format(source_enum_path)) |
205 source_enum_values, duplicated_values = ReadHistogramValues( | 222 try: |
206 source_enum_path, start_marker, end_marker, strip_k_prefix) | 223 source_enum_values = ReadHistogramValues( |
207 | 224 source_enum_path, start_marker, end_marker, strip_k_prefix) |
208 if duplicated_values: | 225 except DuplicatedValue as duplicated_values: |
209 return ('%s enum has been updated and there exist ' | 226 return ('%s enum has been updated and there exist ' |
210 'duplicated values between (%s) and (%s)' % (histogram_enum_name, | 227 'duplicated values between (%s) and (%s)' % |
211 duplicated_values[0], | 228 (histogram_enum_name, duplicated_values.first_label, |
212 duplicated_values[1])) | 229 duplicated_values.second_label)) |
213 | 230 |
214 (xml, new_xml) = _GetOldAndUpdatedXml(histogram_enum_name, source_enum_values, | 231 (xml, new_xml) = _GetOldAndUpdatedXml(histogram_enum_name, source_enum_values, |
215 source_enum_path) | 232 source_enum_path) |
216 if xml != new_xml: | 233 if xml != new_xml: |
217 return ('%s enum has been updated and the UMA mapping needs to be ' | 234 return ('%s enum has been updated and the UMA mapping needs to be ' |
218 'regenerated. Please run %s in src/tools/metrics/histograms/ to ' | 235 'regenerated. Please run %s in src/tools/metrics/histograms/ to ' |
219 'update the mapping.' % (histogram_enum_name, update_script_name)) | 236 'update the mapping.' % (histogram_enum_name, update_script_name)) |
220 | 237 |
221 return None | 238 return None |
222 | 239 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 strip_k_prefix: Set to True if enum values are declared as kFoo and the | 271 strip_k_prefix: Set to True if enum values are declared as kFoo and the |
255 'k' should be stripped. | 272 'k' should be stripped. |
256 """ | 273 """ |
257 | 274 |
258 Log('Reading histogram enum definition from "{0}".'.format(source_enum_path)) | 275 Log('Reading histogram enum definition from "{0}".'.format(source_enum_path)) |
259 source_enum_values, ignored = ReadHistogramValues(source_enum_path, | 276 source_enum_values, ignored = ReadHistogramValues(source_enum_path, |
260 start_marker, end_marker, strip_k_prefix) | 277 start_marker, end_marker, strip_k_prefix) |
261 | 278 |
262 UpdateHistogramFromDict(histogram_enum_name, source_enum_values, | 279 UpdateHistogramFromDict(histogram_enum_name, source_enum_values, |
263 source_enum_path) | 280 source_enum_path) |
OLD | NEW |