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 the dependency of each style struct. 13 14from __future__ import print_function 15 16import math 17 18NORMAL_DEP = ["Variables"] 19COLOR_DEP = ["Color"] 20LENGTH_DEP = ["Font", "Visibility"] 21 22# List of style structs and their corresponding Check callback functions, 23# if any. 24STYLE_STRUCTS = [("INHERITED",) + x for x in [ 25 # Inherited style structs. 26 ("Font", "CheckFontCallback", NORMAL_DEP + ["Visibility"]), 27 ("Color", "CheckColorCallback", NORMAL_DEP), 28 ("List", "nullptr", NORMAL_DEP + LENGTH_DEP), 29 ("Text", "CheckTextCallback", NORMAL_DEP + LENGTH_DEP + COLOR_DEP), 30 ("Visibility", "nullptr", NORMAL_DEP), 31 ("UserInterface", "nullptr", NORMAL_DEP), 32 ("TableBorder", "nullptr", NORMAL_DEP + LENGTH_DEP), 33 ("SVG", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP), 34 ("Variables", "CheckVariablesCallback",[]), 35]] + [("RESET",) + x for x in [ 36 # Reset style structs. 37 ("Background", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP), 38 ("Position", "nullptr", NORMAL_DEP + LENGTH_DEP), 39 ("TextReset", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP), 40 ("Display", "nullptr", NORMAL_DEP + LENGTH_DEP), 41 ("Content", "nullptr", NORMAL_DEP + LENGTH_DEP), 42 ("UIReset", "nullptr", NORMAL_DEP), 43 ("Table", "nullptr", NORMAL_DEP), 44 ("Margin", "nullptr", NORMAL_DEP + LENGTH_DEP), 45 ("Padding", "nullptr", NORMAL_DEP + LENGTH_DEP), 46 ("Border", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP), 47 ("Outline", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP), 48 ("XUL", "nullptr", NORMAL_DEP), 49 ("SVGReset", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP), 50 ("Column", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP), 51 ("Effects", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP), 52]] 53 54 55# ---- Generate nsStyleStructList.h ---- 56 57count = len(STYLE_STRUCTS) 58 59# Check for problems with style struct dependencies 60resolved_items = [] 61# This whole loop tries to sort the style structs in topological order 62# according to the dependencies. A topological order exists iff there 63# are no cyclic dependencies between the style structs. It resolves one 64# struct each iteration, and append the resolved one to |resolved_items|. 65for i in range(count): 66 # This inner loop picks one style struct which does not have 67 # unsolved dependencies. If nothing can be picked, then we 68 # must have some cyclic dependencies. 69 for j in range(count): 70 _, name, _, dependencies = STYLE_STRUCTS[j] 71 if name in resolved_items: 72 continue 73 # Check whether all dependencies of this item have been placed 74 for dep in dependencies: 75 if dep not in resolved_items: 76 break 77 else: 78 resolved_items.append(name) 79 break 80 else: 81 import sys 82 print("ERROR: Cannot resolve style struct dependencies", file=sys.stderr) 83 print("Resolved items:", " ".join(resolved_items), file=sys.stderr) 84 unsolved_items = [name for _, name, _, _ in STYLE_STRUCTS 85 if name not in resolved_items] 86 print("There exist cyclic dependencies between " + 87 "the following structs:", " ".join(unsolved_items), file=sys.stderr) 88 exit(1) 89 90def printEntry(header, i): 91 print("STYLE_STRUCT_%s(%s, %s)" % STYLE_STRUCTS[i][:3], file=header) 92 for dep in STYLE_STRUCTS[i][3]: 93 print("STYLE_STRUCT_DEP(%s)" % (dep,), file=header) 94 print("STYLE_STRUCT_END()", file=header) 95 96HEADER = """/* THIS FILE IS AUTOGENERATED BY generate-stylestructlist.py - DO NOT EDIT */ 97 98// IWYU pragma: private, include "nsStyleStructFwd.h" 99 100/* 101 * list of structs that contain the data provided by nsStyleContext, the 102 * internal API for computed style data for an element 103 */ 104 105/* 106 * This file is intended to be used by different parts of the code, with 107 * the STYLE_STRUCT macro (or the STYLE_STRUCT_INHERITED and 108 * STYLE_STRUCT_RESET pair of macros) defined in different ways. 109 */ 110 111#ifndef STYLE_STRUCT_INHERITED 112#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \\ 113 STYLE_STRUCT(name, checkdata_cb) 114#define UNDEF_STYLE_STRUCT_INHERITED 115#endif 116 117#ifndef STYLE_STRUCT_RESET 118#define STYLE_STRUCT_RESET(name, checkdata_cb) \\ 119 STYLE_STRUCT(name, checkdata_cb) 120#define UNDEF_STYLE_STRUCT_RESET 121#endif 122 123#ifndef STYLE_STRUCT_DEP 124#define STYLE_STRUCT_DEP(dep) 125#define UNDEF_STYLE_STRUCT_DEP 126#endif 127 128#ifndef STYLE_STRUCT_END 129#define STYLE_STRUCT_END() 130#define UNDEF_STYLE_STRUCT_END 131#endif 132 133// The inherited structs are listed before the Reset structs. 134// nsStyleStructID assumes this is the case, and callers other than 135// nsStyleStructFwd.h that want the structs in id-order just define 136// STYLE_STRUCT rather than including the file twice. 137 138""" 139FOOTER = """ 140#ifdef UNDEF_STYLE_STRUCT_INHERITED 141#undef STYLE_STRUCT_INHERITED 142#undef UNDEF_STYLE_STRUCT_INHERITED 143#endif 144 145#ifdef UNDEF_STYLE_STRUCT_RESET 146#undef STYLE_STRUCT_RESET 147#undef UNDEF_STYLE_STRUCT_RESET 148#endif 149 150#ifdef UNDEF_STYLE_STRUCT_DEP 151#undef STYLE_STRUCT_DEP 152#undef UNDEF_STYLE_STRUCT_DEP 153#endif 154 155#ifdef UNDEF_STYLE_STRUCT_END 156#undef STYLE_STRUCT_END 157#undef UNDEF_STYLE_STRUCT_END 158#endif 159""" 160 161def main(header): 162 print(HEADER, file=header) 163 for i in range(count): 164 printEntry(header, i) 165 print(FOOTER, file=header) 166