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