summaryrefslogtreecommitdiff
path: root/chromium/tools/metrics/histograms/pretty_print.py
blob: 05d68a37248cd21aabb85e97fdfe1826e57a620f (plain)
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
#!/usr/bin/env python
# Copyright 2013 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.

"""Pretty-prints the histograms.xml file, alphabetizing tags, wrapping text
at 80 chars, enforcing standard attribute ordering, and standardizing
indentation.

This is quite a bit more complicated than just calling tree.toprettyxml();
we need additional customization, like special attribute ordering in tags
and wrapping text nodes, so we implement our own full custom XML pretty-printer.
"""

from __future__ import with_statement

import logging
import os
import shutil
import sys
import xml.dom.minidom

sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'common'))
import diff_util
import presubmit_util

import print_style


class Error(Exception):
  pass


UNIT_REWRITES = {
  'microsecond': 'microseconds',
  'us': 'microseconds',
  'millisecond': 'ms',
  'milliseconds': 'ms',
  'kb': 'KB',
  'kB': 'KB',
  'kilobytes': 'KB',
  'kbits/s': 'kbps',
  'mb': 'MB',
  'mB': 'MB',
  'megabytes': 'MB',
  'mbits/s': 'mbps',
  'percent': '%',
  'Percent': '%',
  'percentage': '%',
}


def canonicalizeUnits(tree):
  """Canonicalize the spelling of certain units in histograms."""
  histograms = tree.getElementsByTagName('histogram')
  for histogram in histograms:
    units = histogram.attributes.get('units')
    if units and units.value in UNIT_REWRITES:
      histogram.attributes['units'] = UNIT_REWRITES[units.value]


def fixObsoleteOrder(tree):
  """Put obsolete tags at the beginning of histogram tags."""
  histograms = tree.getElementsByTagName('histogram')
  for histogram in histograms:
    obsoletes = histogram.getElementsByTagName('obsolete')
    if obsoletes:
      histogram.insertBefore(obsoletes[0], histogram.firstChild)


def DropNodesByTagName(tree, tag):
  """Drop all nodes with named tag from the XML tree."""
  nodes = tree.getElementsByTagName(tag)
  for node in nodes:
    node.parentNode.removeChild(node)


def PrettyPrintHistograms(raw_xml):
  """Pretty-print the given XML.

  Args:
    raw_xml: The contents of the histograms XML file, as a string.

  Returns:
    The pretty-printed version.
  """
  tree = xml.dom.minidom.parseString(raw_xml)
  # Prevent accidentally adding enums to histograms.xml
  DropNodesByTagName(tree, 'enums')
  canonicalizeUnits(tree)
  fixObsoleteOrder(tree)
  return print_style.GetPrintStyle().PrettyPrintXml(tree)


def PrettyPrintEnums(raw_xml):
  """Pretty print the enums.xml file."""
  tree = xml.dom.minidom.parseString(raw_xml)
  # Prevent accidentally adding histograms to enums.xml
  DropNodesByTagName(tree, 'histograms')
  DropNodesByTagName(tree, 'histogram_suffixes_list')
  return print_style.GetPrintStyle().PrettyPrintXml(tree)


def main():
  status1 = presubmit_util.DoPresubmit(sys.argv, 'enums.xml',
                                       'enums.before.pretty-print.xml',
                                       'pretty_print.py', PrettyPrintEnums)
  status2 = presubmit_util.DoPresubmit(sys.argv, 'histograms.xml',
                                       'histograms.before.pretty-print.xml',
                                       'pretty_print.py', PrettyPrintHistograms)
  sys.exit(status1 or status2)

if __name__ == '__main__':
  main()