summaryrefslogtreecommitdiff
path: root/layout/style/generate-stylestructlist.py
diff options
context:
space:
mode:
Diffstat (limited to 'layout/style/generate-stylestructlist.py')
-rwxr-xr-xlayout/style/generate-stylestructlist.py165
1 files changed, 165 insertions, 0 deletions
diff --git a/layout/style/generate-stylestructlist.py b/layout/style/generate-stylestructlist.py
new file mode 100755
index 0000000000..346a7deaef
--- /dev/null
+++ b/layout/style/generate-stylestructlist.py
@@ -0,0 +1,165 @@
+#!/usr/bin/env python
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# This script generates nsStyleStructList.h, which contains macro invocations
+# that can be used for three things:
+#
+# 1. To generate code for each inherited style struct.
+# 2. To generate code for each reset style struct.
+# 3. To generate the dependency of each style struct.
+
+from __future__ import print_function
+
+import math
+
+NORMAL_DEP = ["Variables"]
+COLOR_DEP = ["Color"]
+LENGTH_DEP = ["Font", "Visibility"]
+
+# List of style structs and their corresponding Check callback functions,
+# if any.
+STYLE_STRUCTS = [("INHERITED",) + x for x in [
+ # Inherited style structs.
+ ("Font", "CheckFontCallback", NORMAL_DEP + ["Visibility"]),
+ ("Color", "CheckColorCallback", NORMAL_DEP),
+ ("List", "nullptr", NORMAL_DEP + LENGTH_DEP),
+ ("Text", "CheckTextCallback", NORMAL_DEP + LENGTH_DEP + COLOR_DEP),
+ ("Visibility", "nullptr", NORMAL_DEP),
+ ("UserInterface", "nullptr", NORMAL_DEP),
+ ("TableBorder", "nullptr", NORMAL_DEP + LENGTH_DEP),
+ ("SVG", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP),
+ ("Variables", "CheckVariablesCallback",[]),
+]] + [("RESET",) + x for x in [
+ # Reset style structs.
+ ("Background", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP),
+ ("Position", "nullptr", NORMAL_DEP + LENGTH_DEP),
+ ("TextReset", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP),
+ ("Display", "nullptr", NORMAL_DEP + LENGTH_DEP),
+ ("Content", "nullptr", NORMAL_DEP + LENGTH_DEP),
+ ("UIReset", "nullptr", NORMAL_DEP),
+ ("Table", "nullptr", NORMAL_DEP),
+ ("Margin", "nullptr", NORMAL_DEP + LENGTH_DEP),
+ ("Padding", "nullptr", NORMAL_DEP + LENGTH_DEP),
+ ("Border", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP),
+ ("Outline", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP),
+ ("XUL", "nullptr", NORMAL_DEP),
+ ("SVGReset", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP),
+ ("Column", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP),
+ ("Effects", "nullptr", NORMAL_DEP + LENGTH_DEP + COLOR_DEP),
+]]
+
+
+# ---- Generate nsStyleStructList.h ----
+
+count = len(STYLE_STRUCTS)
+
+# Check for problems with style struct dependencies
+resolved_items = []
+# This whole loop tries to sort the style structs in topological order
+# according to the dependencies. A topological order exists iff there
+# are no cyclic dependencies between the style structs. It resolves one
+# struct each iteration, and append the resolved one to |resolved_items|.
+for i in range(count):
+ # This inner loop picks one style struct which does not have
+ # unsolved dependencies. If nothing can be picked, then we
+ # must have some cyclic dependencies.
+ for j in range(count):
+ _, name, _, dependencies = STYLE_STRUCTS[j]
+ if name in resolved_items:
+ continue
+ # Check whether all dependencies of this item have been placed
+ for dep in dependencies:
+ if dep not in resolved_items:
+ break
+ else:
+ resolved_items.append(name)
+ break
+ else:
+ import sys
+ print("ERROR: Cannot resolve style struct dependencies", file=sys.stderr)
+ print("Resolved items:", " ".join(resolved_items), file=sys.stderr)
+ unsolved_items = [name for _, name, _, _ in STYLE_STRUCTS
+ if name not in resolved_items]
+ print("There exist cyclic dependencies between " +
+ "the following structs:", " ".join(unsolved_items), file=sys.stderr)
+ exit(1)
+
+def printEntry(header, i):
+ print("STYLE_STRUCT_%s(%s, %s)" % STYLE_STRUCTS[i][:3], file=header)
+ for dep in STYLE_STRUCTS[i][3]:
+ print("STYLE_STRUCT_DEP(%s)" % (dep,), file=header)
+ print("STYLE_STRUCT_END()", file=header)
+
+HEADER = """/* THIS FILE IS AUTOGENERATED BY generate-stylestructlist.py - DO NOT EDIT */
+
+// IWYU pragma: private, include "nsStyleStructFwd.h"
+
+/*
+ * list of structs that contain the data provided by nsStyleContext, the
+ * internal API for computed style data for an element
+ */
+
+/*
+ * This file is intended to be used by different parts of the code, with
+ * the STYLE_STRUCT macro (or the STYLE_STRUCT_INHERITED and
+ * STYLE_STRUCT_RESET pair of macros) defined in different ways.
+ */
+
+#ifndef STYLE_STRUCT_INHERITED
+#define STYLE_STRUCT_INHERITED(name, checkdata_cb) \\
+ STYLE_STRUCT(name, checkdata_cb)
+#define UNDEF_STYLE_STRUCT_INHERITED
+#endif
+
+#ifndef STYLE_STRUCT_RESET
+#define STYLE_STRUCT_RESET(name, checkdata_cb) \\
+ STYLE_STRUCT(name, checkdata_cb)
+#define UNDEF_STYLE_STRUCT_RESET
+#endif
+
+#ifndef STYLE_STRUCT_DEP
+#define STYLE_STRUCT_DEP(dep)
+#define UNDEF_STYLE_STRUCT_DEP
+#endif
+
+#ifndef STYLE_STRUCT_END
+#define STYLE_STRUCT_END()
+#define UNDEF_STYLE_STRUCT_END
+#endif
+
+// The inherited structs are listed before the Reset structs.
+// nsStyleStructID assumes this is the case, and callers other than
+// nsStyleStructFwd.h that want the structs in id-order just define
+// STYLE_STRUCT rather than including the file twice.
+
+"""
+FOOTER = """
+#ifdef UNDEF_STYLE_STRUCT_INHERITED
+#undef STYLE_STRUCT_INHERITED
+#undef UNDEF_STYLE_STRUCT_INHERITED
+#endif
+
+#ifdef UNDEF_STYLE_STRUCT_RESET
+#undef STYLE_STRUCT_RESET
+#undef UNDEF_STYLE_STRUCT_RESET
+#endif
+
+#ifdef UNDEF_STYLE_STRUCT_DEP
+#undef STYLE_STRUCT_DEP
+#undef UNDEF_STYLE_STRUCT_DEP
+#endif
+
+#ifdef UNDEF_STYLE_STRUCT_END
+#undef STYLE_STRUCT_END
+#undef UNDEF_STYLE_STRUCT_END
+#endif
+"""
+
+def main(header):
+ print(HEADER, file=header)
+ for i in range(count):
+ printEntry(header, i)
+ print(FOOTER, file=header)