gen-histogram-enum.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. # This Source Code Form is subject to the terms of the Mozilla Public
  2. # License, v. 2.0. If a copy of the MPL was not distributed with this
  3. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
  4. # Write out a C++ enum definition whose members are the names of
  5. # histograms as well as the following other members:
  6. #
  7. # - HistogramCount
  8. # - HistogramFirstUseCounter
  9. # - HistogramLastUseCounter
  10. # - HistogramUseCounterCount
  11. #
  12. # The histograms are defined in files provided as command-line arguments.
  13. from __future__ import print_function
  14. import histogram_tools
  15. import itertools
  16. import sys
  17. banner = """/* This file is auto-generated, see gen-histogram-enum.py. */
  18. """
  19. header = """
  20. #ifndef mozilla_TelemetryHistogramEnums_h
  21. #define mozilla_TelemetryHistogramEnums_h
  22. #include "mozilla/TemplateLib.h"
  23. namespace mozilla {
  24. namespace Telemetry {
  25. """
  26. footer = """
  27. } // namespace mozilla
  28. } // namespace Telemetry
  29. #endif // mozilla_TelemetryHistogramEnums_h"""
  30. def main(output, *filenames):
  31. # Print header.
  32. print(banner, file=output)
  33. print(header, file=output)
  34. # Load the histograms.
  35. all_histograms = list(histogram_tools.from_files(filenames))
  36. groups = itertools.groupby(all_histograms,
  37. lambda h: h.name().startswith("USE_COUNTER2_"))
  38. # Print the histogram enums.
  39. # Note that histogram_tools.py guarantees that all of the USE_COUNTER2_*
  40. # histograms are defined in a contiguous block. We therefore assume
  41. # that there's at most one group for which use_counter_group is true.
  42. print("enum ID : uint32_t {", file=output)
  43. seen_use_counters = False
  44. for (use_counter_group, histograms) in groups:
  45. if use_counter_group:
  46. seen_use_counters = True
  47. # The HistogramDUMMY* enum variables are used to make the computation
  48. # of Histogram{First,Last}UseCounter easier. Otherwise, we'd have to
  49. # special case the first and last histogram in the group.
  50. if use_counter_group:
  51. print(" HistogramFirstUseCounter,", file=output)
  52. print(" HistogramDUMMY1 = HistogramFirstUseCounter - 1,", file=output)
  53. for histogram in histograms:
  54. cpp_guard = histogram.cpp_guard()
  55. if cpp_guard:
  56. print("#if defined(%s)" % cpp_guard, file=output)
  57. print(" %s," % histogram.name(), file=output)
  58. if cpp_guard:
  59. print("#endif", file=output)
  60. if use_counter_group:
  61. print(" HistogramDUMMY2,", file=output)
  62. print(" HistogramLastUseCounter = HistogramDUMMY2 - 1,", file=output)
  63. print(" HistogramCount,", file=output)
  64. if seen_use_counters:
  65. print(" HistogramUseCounterCount = HistogramLastUseCounter - HistogramFirstUseCounter + 1", file=output)
  66. else:
  67. print(" HistogramFirstUseCounter = 0,", file=output)
  68. print(" HistogramLastUseCounter = 0,", file=output)
  69. print(" HistogramUseCounterCount = 0", file=output)
  70. print("};", file=output)
  71. # Write categorical label enums.
  72. categorical = filter(lambda h: h.kind() == "categorical", all_histograms)
  73. enums = [("LABELS_" + h.name(), h.labels(), h.name()) for h in categorical]
  74. for name,labels,_ in enums:
  75. print("\nenum class %s : uint32_t {" % name, file=output)
  76. print(" %s" % ",\n ".join(labels), file=output)
  77. print("};", file=output)
  78. print("\ntemplate<class T> struct IsCategoricalLabelEnum : FalseType {};", file=output)
  79. for name,_,_ in enums:
  80. print("template<> struct IsCategoricalLabelEnum<%s> : TrueType {};" % name, file=output)
  81. print("\ntemplate<class T> struct CategoricalLabelId {};", file=output)
  82. for name,_,id in enums:
  83. print("template<> struct CategoricalLabelId<%s> : IntegralConstant<uint32_t, %s> {};" % (name, id), file=output)
  84. # Footer.
  85. print(footer, file=output)
  86. if __name__ == '__main__':
  87. main(sys.stdout, *sys.argv[1:])