File: update_editor_commands.py

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (145 lines) | stat: -rw-r--r-- 4,334 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# Copyright 2014 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Updates MappedEditingCommands enum in histograms.xml file with values read
 from EditorCommand.cpp.

If the file was pretty-printed, the updated version is pretty-printed too.
"""

from __future__ import print_function

import logging
import os
import re
import sys

from xml.dom import minidom

sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'common'))
from diff_util import PromptUserToAcceptDiff
import path_util

import histogram_paths
import histogram_configuration_model


ENUMS_PATH = histogram_paths.ENUMS_XML
ENUM_NAME = 'MappedEditingCommands'

EDITOR_COMMAND_CPP = 'third_party/blink/renderer/core/editing/editor_command.cc'
ENUM_START_MARKER = "^    static const CommandEntry commands\[\] = {"
ENUM_END_MARKER = "^    };"


class UserError(Exception):
  def __init__(self, message):
    Exception.__init__(self, message)

  @property
  def message(self):
    return self.args[0]


def ReadHistogramValues(filename):
  """Returns a list of pairs (label, value) corresponding to HistogramValue.

  Reads the EditorCommand.cpp file, locates the
  HistogramValue enum definition and returns a pair for each entry.
  """

  # Read the file as a list of lines
  with open(path_util.GetInputFile(filename)) as f:
    content = f.readlines()

  # Locate the enum definition and collect all entries in it
  inside_enum = False # We haven't found the enum definition yet
  result = []
  for line in content:
    if inside_enum:
      # Exit condition: we reached last enum value
      if re.match(ENUM_END_MARKER, line):
        inside_enum = False
      else:
        # Inside enum: generate new xml entry
        m = re.match("^{ \"([\w]+)\", \{([\w]+)", line.strip())
        if m:
          result.append((m.group(1), int(m.group(2))))
    else:
      if re.match(ENUM_START_MARKER, line):
        inside_enum = True
        enum_value = 0 # Start at 'UNKNOWN'
  return sorted(result, key=lambda pair: pair[1])


def UpdateHistogramDefinitions(histogram_values, document):
  """Sets the children of <enum name="ExtensionFunctions" ...> node in
  |document| to values generated from policy ids contained in
  |policy_templates|.

  Args:
    histogram_values: A list of pairs (label, value) defining each extension
                      function
    document: A minidom.Document object representing parsed histogram
              definitions XML file.

  """
  # Find ExtensionFunctions enum.
  for enum_node in document.getElementsByTagName('enum'):
    if enum_node.attributes['name'].value == ENUM_NAME:
      extension_functions_enum_node = enum_node
      break
  else:
    raise UserError('No policy enum node found')

  # Remove existing values.
  while extension_functions_enum_node.hasChildNodes():
    extension_functions_enum_node.removeChild(
      extension_functions_enum_node.lastChild)

  # Add a "Generated from (...)" comment
  comment = ' Generated from {0} '.format(EDITOR_COMMAND_CPP)
  extension_functions_enum_node.appendChild(document.createComment(comment))

  # Add values generated from policy templates.
  for (label, value) in histogram_values:
    node = document.createElement('int')
    node.attributes['value'] = str(value)
    node.attributes['label'] = label
    extension_functions_enum_node.appendChild(node)


def Log(message):
  logging.info(message)


def main():
  if len(sys.argv) > 1:
    print('No arguments expected!', file=sys.stderr)
    sys.stderr.write(__doc__)
    sys.exit(1)

  Log('Reading histogram enum definition from "%s".' % EDITOR_COMMAND_CPP)
  histogram_values = ReadHistogramValues(EDITOR_COMMAND_CPP)

  Log('Reading existing histograms from "%s".' % (ENUMS_PATH))
  with open(ENUMS_PATH, 'rb') as f:
    histograms_doc = minidom.parse(f)
    f.seek(0)
    xml = f.read()

  Log('Comparing histograms enum with new enum definition.')
  UpdateHistogramDefinitions(histogram_values, histograms_doc)

  Log('Writing out new histograms file.')
  new_xml = histogram_configuration_model.PrettifyTree(histograms_doc)
  if PromptUserToAcceptDiff(xml, new_xml, 'Is the updated version acceptable?'):
    with open(ENUMS_PATH, 'wb') as f:
      f.write(new_xml)

  Log('Done.')


if __name__ == '__main__':
  main()