Home | History | Annotate | Download | only in ozone
      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 
      6 """Code generator for PlatformObject<> constructor list.
      7 
      8 This script takes as arguments a list of platform names as a text file and
      9 a list of types and generates a C++ source file containing a list of
     10 the constructors for that object in platform order.
     11 
     12 Example Output: ./ui/ozone/generate_constructor_list.py \
     13                     --platform test \
     14                     --platform dri \
     15                     --export OZONE_EXPORT \
     16                     --namespace ui \
     17                     --typename OzonePlatform \
     18                     --include '"ui/ozone/ozone_platform.h"'
     19 
     20   // DO NOT MODIFY. GENERATED BY generate_constructor_list.py
     21 
     22   #include "ui/ozone/platform_object_internal.h"
     23 
     24   #include "ui/ozone/ozone_platform.h"
     25 
     26   namespace ui {
     27 
     28   OzonePlatform* CreateOzonePlatformTest();
     29   OzonePlatform* CreateOzonePlatformDri();
     30 
     31   }  // namespace ui
     32 
     33   namespace ui {
     34 
     35   typedef ui::OzonePlatform* (*OzonePlatformConstructor)();
     36 
     37   template <> const OzonePlatformConstructor
     38   PlatformConstructorList<ui::OzonePlatform>::kConstructors[] = {
     39     &ui::CreateOzonePlatformTest,
     40     &ui::CreateOzonePlatformDri,
     41   };
     42 
     43   template class OZONE_EXPORT PlatformObject<ui::OzonePlatform>;
     44 
     45   }  // namespace ui
     46 """
     47 
     48 import optparse
     49 import os
     50 import collections
     51 import re
     52 import sys
     53 import string
     54 
     55 
     56 def GetTypedefName(typename):
     57   """Determine typedef name of constructor for typename.
     58 
     59   This is just typename + "Constructor".
     60   """
     61 
     62   return typename + 'Constructor'
     63 
     64 
     65 def GetConstructorName(typename, platform):
     66   """Determine name of static constructor function from platform name.
     67 
     68   This is just "Create" + typename + platform.
     69   """
     70 
     71   return 'Create' + typename + string.capitalize(platform)
     72 
     73 
     74 def GenerateConstructorList(out, namespace, export, typenames, platforms,
     75                             includes):
     76   """Generate static array containing a list of constructors."""
     77 
     78   out.write('// DO NOT MODIFY. GENERATED BY generate_constructor_list.py\n')
     79   out.write('\n')
     80 
     81   out.write('#include "ui/ozone/platform_object_internal.h"\n')
     82   out.write('\n')
     83 
     84   for include in includes:
     85     out.write('#include %(include)s\n' % {'include': include})
     86   out.write('\n')
     87 
     88   out.write('namespace %(namespace)s {\n' % {'namespace': namespace})
     89   out.write('\n')
     90 
     91   # Declarations of constructor functions.
     92   for typename in typenames:
     93     for platform in platforms:
     94       constructor = GetConstructorName(typename, platform)
     95       out.write('%(typename)s* %(constructor)s();\n'
     96                % {'typename': typename,
     97                   'constructor': constructor})
     98     out.write('\n')
     99 
    100   out.write('}  // namespace %(namespace)s\n' % {'namespace': namespace})
    101   out.write('\n')
    102 
    103   out.write('namespace ui {\n')
    104   out.write('\n')
    105 
    106   # Handy typedefs for constructor types.
    107   for typename in typenames:
    108     out.write('typedef %(typename)s* (*%(typedef)s)();\n'
    109               % {'typename': namespace + '::' + typename,
    110                  'typedef': GetTypedefName(typename)})
    111   out.write('\n')
    112 
    113   # The actual constructor lists.
    114   for typename in typenames:
    115     out.write('template <> const %(typedef)s\n'
    116               % {'typedef': GetTypedefName(typename)})
    117     out.write('PlatformConstructorList<%(typename)s>::kConstructors[] = {\n'
    118               % {'typename': namespace + '::' + typename})
    119     for platform in platforms:
    120       constructor = GetConstructorName(typename, platform)
    121       out.write('  &%(namespace)s::%(constructor)s,\n'
    122                 % {'namespace': namespace, 'constructor': constructor})
    123     out.write('};\n')
    124     out.write('\n')
    125 
    126   # Exported template instantiation.
    127   for typename in typenames:
    128     out.write('template class %(export)s PlatformObject<%(typename)s>;\n'
    129               % {'export': export, 'typename': namespace + '::' + typename})
    130   out.write('\n')
    131 
    132   out.write('}  // namespace ui\n')
    133   out.write('\n')
    134 
    135 
    136 def main(argv):
    137   parser = optparse.OptionParser()
    138   parser.add_option('--namespace', default='ozone')
    139   parser.add_option('--export', default='OZONE_EXPORT')
    140   parser.add_option('--platform_list')
    141   parser.add_option('--output_cc')
    142   parser.add_option('--include', action='append', default=[])
    143   parser.add_option('--platform', action='append', default=[])
    144   parser.add_option('--typename', action='append', default=[])
    145   options, _ = parser.parse_args(argv)
    146 
    147   platforms = list(options.platform)
    148   typenames = list(options.typename)
    149   includes = list(options.include)
    150 
    151   if options.platform_list:
    152     platforms = open(options.platform_list, 'r').read().strip().split('\n')
    153 
    154   # Write to standard output or file specified by --output_cc.
    155   out_cc = sys.stdout
    156   if options.output_cc:
    157     out_cc = open(options.output_cc, 'wb')
    158 
    159   GenerateConstructorList(out_cc, options.namespace, options.export,
    160                           typenames, platforms, includes)
    161 
    162   if options.output_cc:
    163     out_cc.close()
    164 
    165   return 0
    166 
    167 
    168 if __name__ == '__main__':
    169   sys.exit(main(sys.argv[1:]))
    170