2 # Copyright 2012 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.
6 # Format for the JSON schema file:
8 # "type_name": "DesiredCStructName",
9 # "headers": [ // Optional list of headers to be included by the .h.
12 # "schema": [ // Fields of the generated structure.
14 # "field": "my_enum_field",
15 # "type": "enum", // Either: int, string, string16, enum, array.
16 # "default": "RED", // Optional. Cannot be used for array.
17 # "ctype": "Color" // Only for enum, specify the C type.
20 # "field": "my_int_array_field", // my_int_array_field_size will also
21 # "type": "array", // be generated.
23 # "type": "int" // Either: int, string, string16, enum, array.
30 # Format for the JSON description file:
32 # "int_variables": { // An optional list of constant int variables.
33 # "kDesiredConstantName": 45
35 # "elements": { // All the elements for which to create static
36 # // initialization code in the .cc file.
37 # "my_const_variable": {
39 # "my_string_field": "foo bar",
40 # "my_enum_field": "BLACK",
41 # "my_int_array_field": [ 1, 2, 3, 5, 7 ],
43 # "my_other_const_variable": {
50 from datetime
import datetime
55 _script_path
= os
.path
.realpath(__file__
)
57 sys
.path
.insert(0, os
.path
.normpath(_script_path
+ "/../../json_comment_eater"))
59 import json_comment_eater
63 import struct_generator
64 import element_generator
66 HEAD
= """// Copyright %d The Chromium Authors. All rights reserved.
67 // Use of this source code is governed by a BSD-style license that can be
68 // found in the LICENSE file.
70 // GENERATED FROM THE SCHEMA DEFINITION AND DESCRIPTION IN
77 def _GenerateHeaderGuard(h_filename
):
78 """Generates the string used in #ifndef guarding the header file.
80 result
= re
.sub('[%s\\\\.]' % os
.sep
, '_', h_filename
.upper())
81 return re
.sub('^_*', '', result
) + '_' # Remove leading underscores.
83 def _GenerateH(basepath
, fileroot
, head
, namespace
, schema
, description
):
84 """Generates the .h file containing the definition of the structure specified
88 basepath: The base directory in which files are generated.
89 fileroot: The filename and path, relative to basepath, of the file to
90 create, without an extension.
91 head: The string to output as the header of the .h file.
92 namespace: A string corresponding to the C++ namespace to use.
93 schema: A dict containing the schema. See comment at the top of this file.
94 description: A dict containing the description. See comment at the top of
98 h_filename
= fileroot
+ '.h'
99 with
open(os
.path
.join(basepath
, h_filename
), 'w') as f
:
102 header_guard
= _GenerateHeaderGuard(h_filename
)
103 f
.write('#ifndef %s\n' % header_guard
)
104 f
.write('#define %s\n' % header_guard
)
107 f
.write('#include <cstddef>\n')
110 for header
in schema
.get('headers', []):
111 f
.write('#include "%s"\n' % header
)
115 f
.write('namespace %s {\n' % namespace
)
118 f
.write(struct_generator
.GenerateStruct(
119 schema
['type_name'], schema
['schema']))
122 for var_name
, value
in description
.get('int_variables', []).items():
123 f
.write('extern const int %s;\n' % var_name
)
126 for element_name
, element
in description
['elements'].items():
127 f
.write('extern const %s %s;\n' % (schema
['type_name'], element_name
))
131 f
.write('} // namespace %s\n' % namespace
)
134 f
.write( '#endif // %s\n' % header_guard
)
136 def _GenerateCC(basepath
, fileroot
, head
, namespace
, schema
, description
):
137 """Generates the .cc file containing the static initializers for the
138 of the elements specified in the description.
141 basepath: The base directory in which files are generated.
142 fileroot: The filename and path, relative to basepath, of the file to
143 create, without an extension.
144 head: The string to output as the header of the .cc file.
145 namespace: A string corresponding to the C++ namespace to use.
146 schema: A dict containing the schema. See comment at the top of this file.
147 description: A dict containing the description. See comment at the top of
151 with
open(os
.path
.join(basepath
, fileroot
+ '.cc'), 'w') as f
:
154 f
.write('#include "%s"\n' % (fileroot
+ '.h'))
158 f
.write('namespace %s {\n' % namespace
)
161 f
.write(element_generator
.GenerateElements(schema
['type_name'],
162 schema
['schema'], description
))
166 f
.write('} // namespace %s\n' % namespace
)
169 """Loads a JSON file int a Python object and return this object.
171 # TODO(beaudoin): When moving to Python 2.7 use object_pairs_hook=OrderedDict.
172 with
open(filename
, 'r') as handle
:
173 result
= json
.loads(json_comment_eater
.Nom(handle
.read()))
176 if __name__
== '__main__':
177 parser
= optparse
.OptionParser(
178 description
='Generates an C++ array of struct from a JSON description.',
179 usage
='usage: %prog [option] -s schema description')
180 parser
.add_option('-b', '--destbase',
181 help='base directory of generated files.')
182 parser
.add_option('-d', '--destdir',
183 help='directory to output generated files, relative to destbase.')
184 parser
.add_option('-n', '--namespace',
185 help='C++ namespace for generated files. e.g search_providers.')
186 parser
.add_option('-s', '--schema', help='path to the schema file, '
188 (opts
, args
) = parser
.parse_args()
191 parser
.error('You must specify a --schema.')
193 description_filename
= os
.path
.normpath(args
[0])
194 root
, ext
= os
.path
.splitext(description_filename
)
195 shortroot
= os
.path
.split(root
)[1]
197 output_root
= os
.path
.join(os
.path
.normpath(opts
.destdir
), shortroot
)
199 output_root
= shortroot
202 basepath
= os
.path
.normpath(opts
.destbase
)
206 schema
= _Load(opts
.schema
)
207 description
= _Load(description_filename
)
209 head
= HEAD
% (datetime
.now().year
, opts
.schema
, description_filename
)
210 _GenerateH(basepath
, output_root
, head
, opts
.namespace
, schema
, description
)
211 _GenerateCC(basepath
, output_root
, head
, opts
.namespace
, schema
, description
)