generate_constructor_list.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #!/usr/bin/env python
  2. # Copyright 2014 The Chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. """Code generator for PlatformObject<> constructor list.
  6. This script takes as arguments a list of platform names as a text file and
  7. a list of types and generates a C++ source file containing a list of
  8. the constructors for that object in platform order.
  9. Example Output: ./ui/ozone/generate_constructor_list.py \
  10. --platform test \
  11. --platform dri \
  12. --export OZONE \
  13. --namespace ui \
  14. --typename OzonePlatform \
  15. --include '"ui/ozone/ozone_platform.h"'
  16. // DO NOT MODIFY. GENERATED BY generate_constructor_list.py
  17. #include "ui/ozone/platform_object_internal.h"
  18. #include "ui/ozone/ozone_platform.h"
  19. namespace ui {
  20. OzonePlatform* CreateOzonePlatformTest();
  21. OzonePlatform* CreateOzonePlatformDri();
  22. } // namespace ui
  23. namespace ui {
  24. typedef ui::OzonePlatform* (*OzonePlatformConstructor)();
  25. template <> const OzonePlatformConstructor
  26. PlatformConstructorList<ui::OzonePlatform>::kConstructors[] = {
  27. &ui::CreateOzonePlatformTest,
  28. &ui::CreateOzonePlatformDri,
  29. };
  30. template class COMPONENT_EXPORT(OZONE) PlatformObject<ui::OzonePlatform>;
  31. } // namespace ui
  32. """
  33. try:
  34. from StringIO import StringIO # for Python 2
  35. except ImportError:
  36. from io import StringIO # for Python 3
  37. import optparse
  38. import os
  39. import collections
  40. import re
  41. import sys
  42. def GetTypedefName(typename):
  43. """Determine typedef name of constructor for typename.
  44. This is just typename + "Constructor".
  45. """
  46. return typename + 'Constructor'
  47. def GetConstructorName(typename, platform):
  48. """Determine name of static constructor function from platform name.
  49. This is just "Create" + typename + platform.
  50. """
  51. return 'Create' + typename + platform.capitalize()
  52. def GenerateConstructorList(out, namespace, export, typenames, platforms,
  53. includes, usings):
  54. """Generate static array containing a list of constructors."""
  55. out.write('// DO NOT MODIFY. GENERATED BY generate_constructor_list.py\n')
  56. out.write('\n')
  57. out.write('#include "ui/ozone/platform_object_internal.h"\n')
  58. out.write('\n')
  59. for include in includes:
  60. out.write('#include %(include)s\n' % {'include': include})
  61. out.write('\n')
  62. for using in usings:
  63. out.write('using %(using)s;\n' % {'using': using})
  64. out.write('\n')
  65. out.write('namespace %(namespace)s {\n' % {'namespace': namespace})
  66. out.write('\n')
  67. # Declarations of constructor functions.
  68. for typename in typenames:
  69. for platform in platforms:
  70. constructor = GetConstructorName(typename, platform)
  71. out.write('%(typename)s* %(constructor)s();\n'
  72. % {'typename': typename,
  73. 'constructor': constructor})
  74. out.write('\n')
  75. out.write('} // namespace %(namespace)s\n' % {'namespace': namespace})
  76. out.write('\n')
  77. out.write('namespace ui {\n')
  78. out.write('\n')
  79. # Handy typedefs for constructor types.
  80. for typename in typenames:
  81. out.write('typedef %(typename)s* (*%(typedef)s)();\n'
  82. % {'typename': typename,
  83. 'typedef': GetTypedefName(typename)})
  84. out.write('\n')
  85. # The actual constructor lists.
  86. for typename in typenames:
  87. out.write('template <> const %(typedef)s\n'
  88. % {'typedef': GetTypedefName(typename)})
  89. out.write('PlatformConstructorList<%(typename)s>::kConstructors[] = {\n'
  90. % {'typename': typename})
  91. for platform in platforms:
  92. constructor = GetConstructorName(typename, platform)
  93. out.write(' &%(namespace)s::%(constructor)s,\n'
  94. % {'namespace': namespace, 'constructor': constructor})
  95. out.write('};\n')
  96. out.write('\n')
  97. # Exported template instantiation.
  98. for typename in typenames:
  99. out.write('template class COMPONENT_EXPORT(%(export)s)' \
  100. ' PlatformObject<%(typename)s>;\n'
  101. % {'export': export, 'typename': typename})
  102. out.write('\n')
  103. out.write('} // namespace ui\n')
  104. out.write('\n')
  105. def main(argv):
  106. parser = optparse.OptionParser()
  107. parser.add_option('--namespace', default='ozone')
  108. parser.add_option('--export', default='OZONE')
  109. parser.add_option('--platform_list')
  110. parser.add_option('--output_cc')
  111. parser.add_option('--include', action='append', default=[])
  112. parser.add_option('--platform', action='append', default=[])
  113. parser.add_option('--typename', action='append', default=[])
  114. parser.add_option('--using', action='append', default=[])
  115. options, _ = parser.parse_args(argv)
  116. platforms = list(options.platform)
  117. typenames = list(options.typename)
  118. includes = list(options.include)
  119. usings = list(options.using)
  120. if options.platform_list:
  121. platforms = open(options.platform_list, 'r').read().strip().split('\n')
  122. if not platforms:
  123. sys.stderr.write('No platforms are selected!')
  124. sys.exit(1)
  125. # Write to standard output or file specified by --output_cc.
  126. out_cc = getattr(sys.stdout, 'buffer', sys.stdout)
  127. if options.output_cc:
  128. out_cc = open(options.output_cc, 'wb')
  129. out_cc_str = StringIO()
  130. GenerateConstructorList(out_cc_str, options.namespace, options.export,
  131. typenames, platforms, includes, usings)
  132. out_cc.write(out_cc_str.getvalue().encode('utf-8'))
  133. if options.output_cc:
  134. out_cc.close()
  135. return 0
  136. if __name__ == '__main__':
  137. sys.exit(main(sys.argv[1:]))