layout/style/generate-stylestructlist.py

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 #!/usr/bin/env python
michael@0 2
michael@0 3 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 6
michael@0 7 # This script generates nsStyleStructList.h, which contains macro invocations
michael@0 8 # that can be used for three things:
michael@0 9 #
michael@0 10 # 1. To generate code for each inherited style struct.
michael@0 11 # 2. To generate code for each reset style struct.
michael@0 12 # 3. To generate a tree of nested if statements that can be used to run
michael@0 13 # some code on each style struct.
michael@0 14 #
michael@0 15 # As an example, if we assume that we have only four style structs, the
michael@0 16 # generated tree of nested if statements looks like this:
michael@0 17 #
michael@0 18 # if (STYLE_STRUCT_TEST < 4) {
michael@0 19 # if (STYLE_STRUCT_TEST < 2) {
michael@0 20 # if (STYLE_STRUCT_TEST == 0) {
michael@0 21 # ... code for style struct with id 0 ...
michael@0 22 # } else {
michael@0 23 # ... code for style struct with id 1 ...
michael@0 24 # }
michael@0 25 # } else {
michael@0 26 # if (STYLE_STRUCT_TEST == 2) {
michael@0 27 # ... code for style struct with id 2 ...
michael@0 28 # } else {
michael@0 29 # ... code for style struct with id 3 ...
michael@0 30 # }
michael@0 31 # }
michael@0 32 # }
michael@0 33 #
michael@0 34 # The TOPLEVELBRANCHES variable controls how widely we branch on the outermost
michael@0 35 # if statement. In the example above, it splits the search space in 2, but with
michael@0 36 # a larger number of style structs to test -- particularly when the number is
michael@0 37 # closer to one power of two than the next higher one -- the average number of
michael@0 38 # comparisons can be reduced by splitting the top level check into more than 2.
michael@0 39
michael@0 40 import math
michael@0 41
michael@0 42 # List of style structs and their corresponding Check callback functions,
michael@0 43 # if any.
michael@0 44 STYLE_STRUCTS = [("INHERITED",) + x for x in [
michael@0 45 # Inherited style structs.
michael@0 46 ("Font", "CheckFontCallback"),
michael@0 47 ("Color", "CheckColorCallback"),
michael@0 48 ("List", "nullptr"),
michael@0 49 ("Text", "CheckTextCallback"),
michael@0 50 ("Visibility", "nullptr"),
michael@0 51 ("Quotes", "nullptr"),
michael@0 52 ("UserInterface", "nullptr"),
michael@0 53 ("TableBorder", "nullptr"),
michael@0 54 ("SVG", "nullptr"),
michael@0 55 ("Variables", "CheckVariablesCallback"),
michael@0 56 ]] + [("RESET",) + x for x in [
michael@0 57 # Reset style structs.
michael@0 58 ("Background", "nullptr"),
michael@0 59 ("Position", "nullptr"),
michael@0 60 ("TextReset", "nullptr"),
michael@0 61 ("Display", "nullptr"),
michael@0 62 ("Content", "nullptr"),
michael@0 63 ("UIReset", "nullptr"),
michael@0 64 ("Table", "nullptr"),
michael@0 65 ("Margin", "nullptr"),
michael@0 66 ("Padding", "nullptr"),
michael@0 67 ("Border", "nullptr"),
michael@0 68 ("Outline", "nullptr"),
michael@0 69 ("XUL", "nullptr"),
michael@0 70 ("SVGReset", "nullptr"),
michael@0 71 ("Column", "nullptr"),
michael@0 72 ]]
michael@0 73
michael@0 74 # How widely to branch on the outermost if statement.
michael@0 75 TOPLEVELBRANCHES = 4
michael@0 76
michael@0 77
michael@0 78 # ---- Generate nsStyleStructList.h ----
michael@0 79
michael@0 80 count = len(STYLE_STRUCTS)
michael@0 81
michael@0 82 def nextPowerOf2(x):
michael@0 83 return int(pow(2, math.ceil(math.log(x, 2))))
michael@0 84
michael@0 85 def printEntry(i):
michael@0 86 print "STYLE_STRUCT_%s(%s, %s)" % STYLE_STRUCTS[i]
michael@0 87
michael@0 88 def printTestTree(min, max, depth, branches):
michael@0 89 indent = " " * depth
michael@0 90 if min == count - 1 and max >= count:
michael@0 91 print " STYLE_STRUCT_TEST_CODE(%sNS_ASSERTION(STYLE_STRUCT_TEST == %d, \"out of range\");)" % (indent, min)
michael@0 92 printEntry(min)
michael@0 93 elif max - min == 2:
michael@0 94 print " STYLE_STRUCT_TEST_CODE(%sif (STYLE_STRUCT_TEST == %d) {)" % (indent, min)
michael@0 95 printEntry(min)
michael@0 96 print " STYLE_STRUCT_TEST_CODE(%s} else {)" % indent
michael@0 97 printEntry(min + 1)
michael@0 98 print " STYLE_STRUCT_TEST_CODE(%s})" % indent
michael@0 99 elif min < count:
michael@0 100 mid = min + (max - min) / branches
michael@0 101 print " STYLE_STRUCT_TEST_CODE(%sif (STYLE_STRUCT_TEST < %d) {)" % (indent, mid)
michael@0 102 printTestTree(min, mid, depth + 1, 2)
michael@0 103 for branch in range(1, branches):
michael@0 104 lo = min + branch * (max - min) / branches
michael@0 105 hi = min + (branch + 1) * (max - min) / branches
michael@0 106 if lo >= count:
michael@0 107 break
michael@0 108 if branch == branches - 1 or hi >= count:
michael@0 109 print " STYLE_STRUCT_TEST_CODE(%s} else {)" % indent
michael@0 110 else:
michael@0 111 print " STYLE_STRUCT_TEST_CODE(%s} else if (STYLE_STRUCT_TEST < %d) {)" % (indent, hi)
michael@0 112 printTestTree(lo, hi, depth + 1, 2)
michael@0 113 print " STYLE_STRUCT_TEST_CODE(%s})" % indent
michael@0 114
michael@0 115 HEADER = """/* THIS FILE IS AUTOGENERATED BY generate-stylestructlist.py - DO NOT EDIT */
michael@0 116
michael@0 117 // IWYU pragma: private, include "nsStyleStructFwd.h"
michael@0 118
michael@0 119 /*
michael@0 120 * list of structs that contain the data provided by nsStyleContext, the
michael@0 121 * internal API for computed style data for an element
michael@0 122 */
michael@0 123
michael@0 124 /*
michael@0 125 * This file is intended to be used by different parts of the code, with
michael@0 126 * the STYLE_STRUCT macro (or the STYLE_STRUCT_INHERITED and
michael@0 127 * STYLE_STRUCT_RESET pair of macros) defined in different ways.
michael@0 128 */
michael@0 129
michael@0 130 #ifndef STYLE_STRUCT_INHERITED
michael@0 131 #define STYLE_STRUCT_INHERITED(name, checkdata_cb) \\
michael@0 132 STYLE_STRUCT(name, checkdata_cb)
michael@0 133 #define UNDEF_STYLE_STRUCT_INHERITED
michael@0 134 #endif
michael@0 135
michael@0 136 #ifndef STYLE_STRUCT_RESET
michael@0 137 #define STYLE_STRUCT_RESET(name, checkdata_cb) \\
michael@0 138 STYLE_STRUCT(name, checkdata_cb)
michael@0 139 #define UNDEF_STYLE_STRUCT_RESET
michael@0 140 #endif
michael@0 141
michael@0 142 #ifdef STYLE_STRUCT_TEST
michael@0 143 #define STYLE_STRUCT_TEST_CODE(c) c
michael@0 144 #else
michael@0 145 #define STYLE_STRUCT_TEST_CODE(c)
michael@0 146 #endif
michael@0 147
michael@0 148 // The inherited structs are listed before the Reset structs.
michael@0 149 // nsStyleStructID assumes this is the case, and callers other than
michael@0 150 // nsStyleStructFwd.h that want the structs in id-order just define
michael@0 151 // STYLE_STRUCT rather than including the file twice.
michael@0 152
michael@0 153 """
michael@0 154 FOOTER = """
michael@0 155 #ifdef UNDEF_STYLE_STRUCT_INHERITED
michael@0 156 #undef STYLE_STRUCT_INHERITED
michael@0 157 #undef UNDEF_STYLE_STRUCT_INHERITED
michael@0 158 #endif
michael@0 159
michael@0 160 #ifdef UNDEF_STYLE_STRUCT_RESET
michael@0 161 #undef STYLE_STRUCT_RESET
michael@0 162 #undef UNDEF_STYLE_STRUCT_RESET
michael@0 163 #endif
michael@0 164
michael@0 165 #undef STYLE_STRUCT_TEST_CODE
michael@0 166 """
michael@0 167
michael@0 168 print HEADER
michael@0 169 printTestTree(0, nextPowerOf2(count), 0, TOPLEVELBRANCHES)
michael@0 170 print FOOTER

mercurial