layout/style/generate-stylestructlist.py

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/style/generate-stylestructlist.py	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,170 @@
     1.4 +#!/usr/bin/env python
     1.5 +
     1.6 +# This Source Code Form is subject to the terms of the Mozilla Public
     1.7 +# License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 +# file, You can obtain one at http://mozilla.org/MPL/2.0/.
     1.9 +
    1.10 +# This script generates nsStyleStructList.h, which contains macro invocations
    1.11 +# that can be used for three things:
    1.12 +#
    1.13 +# 1. To generate code for each inherited style struct.
    1.14 +# 2. To generate code for each reset style struct.
    1.15 +# 3. To generate a tree of nested if statements that can be used to run
    1.16 +#    some code on each style struct.
    1.17 +#
    1.18 +# As an example, if we assume that we have only four style structs, the
    1.19 +# generated tree of nested if statements looks like this:
    1.20 +#
    1.21 +#   if (STYLE_STRUCT_TEST < 4) {
    1.22 +#     if (STYLE_STRUCT_TEST < 2) {
    1.23 +#       if (STYLE_STRUCT_TEST == 0) {
    1.24 +#         ... code for style struct with id 0 ...
    1.25 +#       } else {
    1.26 +#         ... code for style struct with id 1 ...
    1.27 +#       }
    1.28 +#     } else {
    1.29 +#       if (STYLE_STRUCT_TEST == 2) {
    1.30 +#         ... code for style struct with id 2 ...
    1.31 +#       } else {
    1.32 +#         ... code for style struct with id 3 ...
    1.33 +#       }
    1.34 +#     }
    1.35 +#   }
    1.36 +#
    1.37 +# The TOPLEVELBRANCHES variable controls how widely we branch on the outermost
    1.38 +# if statement.  In the example above, it splits the search space in 2, but with
    1.39 +# a larger number of style structs to test -- particularly when the number is
    1.40 +# closer to one power of two than the next higher one -- the average number of
    1.41 +# comparisons can be reduced by splitting the top level check into more than 2.
    1.42 +
    1.43 +import math
    1.44 +
    1.45 +# List of style structs and their corresponding Check callback functions,
    1.46 +# if any.
    1.47 +STYLE_STRUCTS = [("INHERITED",) + x for x in [
    1.48 +    # Inherited style structs.
    1.49 +    ("Font",           "CheckFontCallback"),
    1.50 +    ("Color",          "CheckColorCallback"),
    1.51 +    ("List",           "nullptr"),
    1.52 +    ("Text",           "CheckTextCallback"),
    1.53 +    ("Visibility",     "nullptr"),
    1.54 +    ("Quotes",         "nullptr"),
    1.55 +    ("UserInterface",  "nullptr"),
    1.56 +    ("TableBorder",    "nullptr"),
    1.57 +    ("SVG",            "nullptr"),
    1.58 +    ("Variables",      "CheckVariablesCallback"),
    1.59 +]] + [("RESET",) + x for x in [
    1.60 +    # Reset style structs.
    1.61 +    ("Background",     "nullptr"),
    1.62 +    ("Position",       "nullptr"),
    1.63 +    ("TextReset",      "nullptr"),
    1.64 +    ("Display",        "nullptr"),
    1.65 +    ("Content",        "nullptr"),
    1.66 +    ("UIReset",        "nullptr"),
    1.67 +    ("Table",          "nullptr"),
    1.68 +    ("Margin",         "nullptr"),
    1.69 +    ("Padding",        "nullptr"),
    1.70 +    ("Border",         "nullptr"),
    1.71 +    ("Outline",        "nullptr"),
    1.72 +    ("XUL",            "nullptr"),
    1.73 +    ("SVGReset",       "nullptr"),
    1.74 +    ("Column",         "nullptr"),
    1.75 +]]
    1.76 +
    1.77 +# How widely to branch on the outermost if statement.
    1.78 +TOPLEVELBRANCHES = 4
    1.79 +
    1.80 +
    1.81 +# ---- Generate nsStyleStructList.h ----
    1.82 +
    1.83 +count = len(STYLE_STRUCTS)
    1.84 +
    1.85 +def nextPowerOf2(x):
    1.86 +    return int(pow(2, math.ceil(math.log(x, 2))))
    1.87 +
    1.88 +def printEntry(i):
    1.89 +    print "STYLE_STRUCT_%s(%s, %s)" % STYLE_STRUCTS[i]
    1.90 +
    1.91 +def printTestTree(min, max, depth, branches):
    1.92 +    indent = "  " * depth
    1.93 +    if min == count - 1 and max >= count:
    1.94 +        print "  STYLE_STRUCT_TEST_CODE(%sNS_ASSERTION(STYLE_STRUCT_TEST == %d, \"out of range\");)" % (indent, min)
    1.95 +        printEntry(min)
    1.96 +    elif max - min == 2:
    1.97 +        print "  STYLE_STRUCT_TEST_CODE(%sif (STYLE_STRUCT_TEST == %d) {)" % (indent, min)
    1.98 +        printEntry(min)
    1.99 +        print "  STYLE_STRUCT_TEST_CODE(%s} else {)" % indent
   1.100 +        printEntry(min + 1)
   1.101 +        print "  STYLE_STRUCT_TEST_CODE(%s})" % indent
   1.102 +    elif min < count:
   1.103 +        mid = min + (max - min) / branches
   1.104 +        print "  STYLE_STRUCT_TEST_CODE(%sif (STYLE_STRUCT_TEST < %d) {)" % (indent, mid)
   1.105 +        printTestTree(min, mid, depth + 1, 2)
   1.106 +        for branch in range(1, branches):
   1.107 +            lo = min + branch * (max - min) / branches
   1.108 +            hi = min + (branch + 1) * (max - min) / branches
   1.109 +            if lo >= count:
   1.110 +                break
   1.111 +            if branch == branches - 1 or hi >= count:
   1.112 +                print "  STYLE_STRUCT_TEST_CODE(%s} else {)" % indent
   1.113 +            else:
   1.114 +                print "  STYLE_STRUCT_TEST_CODE(%s} else if (STYLE_STRUCT_TEST < %d) {)" % (indent, hi)
   1.115 +            printTestTree(lo, hi, depth + 1, 2)
   1.116 +        print "  STYLE_STRUCT_TEST_CODE(%s})" % indent
   1.117 +
   1.118 +HEADER = """/* THIS FILE IS AUTOGENERATED BY generate-stylestructlist.py - DO NOT EDIT */
   1.119 +
   1.120 +// IWYU pragma: private, include "nsStyleStructFwd.h"
   1.121 +
   1.122 +/*
   1.123 + * list of structs that contain the data provided by nsStyleContext, the
   1.124 + * internal API for computed style data for an element
   1.125 + */
   1.126 +
   1.127 +/*
   1.128 + * This file is intended to be used by different parts of the code, with
   1.129 + * the STYLE_STRUCT macro (or the STYLE_STRUCT_INHERITED and
   1.130 + * STYLE_STRUCT_RESET pair of macros) defined in different ways.
   1.131 + */
   1.132 +
   1.133 +#ifndef STYLE_STRUCT_INHERITED
   1.134 +#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \\
   1.135 +  STYLE_STRUCT(name, checkdata_cb)
   1.136 +#define UNDEF_STYLE_STRUCT_INHERITED
   1.137 +#endif
   1.138 +
   1.139 +#ifndef STYLE_STRUCT_RESET
   1.140 +#define STYLE_STRUCT_RESET(name, checkdata_cb) \\
   1.141 +  STYLE_STRUCT(name, checkdata_cb)
   1.142 +#define UNDEF_STYLE_STRUCT_RESET
   1.143 +#endif
   1.144 +
   1.145 +#ifdef STYLE_STRUCT_TEST
   1.146 +#define STYLE_STRUCT_TEST_CODE(c) c
   1.147 +#else
   1.148 +#define STYLE_STRUCT_TEST_CODE(c)
   1.149 +#endif
   1.150 +
   1.151 +// The inherited structs are listed before the Reset structs.
   1.152 +// nsStyleStructID assumes this is the case, and callers other than
   1.153 +// nsStyleStructFwd.h that want the structs in id-order just define
   1.154 +// STYLE_STRUCT rather than including the file twice.
   1.155 +
   1.156 +"""
   1.157 +FOOTER = """
   1.158 +#ifdef UNDEF_STYLE_STRUCT_INHERITED
   1.159 +#undef STYLE_STRUCT_INHERITED
   1.160 +#undef UNDEF_STYLE_STRUCT_INHERITED
   1.161 +#endif
   1.162 +
   1.163 +#ifdef UNDEF_STYLE_STRUCT_RESET
   1.164 +#undef STYLE_STRUCT_RESET
   1.165 +#undef UNDEF_STYLE_STRUCT_RESET
   1.166 +#endif
   1.167 +
   1.168 +#undef STYLE_STRUCT_TEST_CODE
   1.169 +"""
   1.170 +
   1.171 +print HEADER
   1.172 +printTestTree(0, nextPowerOf2(count), 0, TOPLEVELBRANCHES)
   1.173 +print FOOTER

mercurial