generate-stylestructlist.py 5.8 KB

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