blob: 9a07badb269bf5b0a33398526b2db851e95826d1 [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License
#
"""
Generate C code from the router schema.
"""
import re
from qpid_dispatch_internal.management.schema.qd_schema import EnumType, QdSchema
copyright="""/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
"""
class Generator(object):
def __init__(self):
self.schema = QdSchema()
self.prefix = ['qd_schema']
self.generate_enums()
def header(self, name, text):
with open(name+'.h', 'w') as f:
f.write("#ifndef __%s_h__\n#define __%s_h__\n"%(name, name) + copyright + text + "\n#endif\n")
def source(self, name, text):
with open(name+'.c', 'w') as f:
f.write(copyright + text)
def identifier(self, name):
return re.sub(r'\W','_', name)
def underscore(self, names):
return '_'.join([self.identifier(name) for name in names])
def prefix_name(self, names):
return self.underscore(self.prefix + names)
def type_name(self, names):
return self.prefix_name(names + ['t'])
class BaseEnumGenerator(object):
def decl(self):
tags = self.tags + ['ENUM_COUNT']
return "typedef enum {\n" + \
",\n".join([" " + self.name(tag) for tag in tags]) + \
"\n} %s;\n\n" % self.type_name + \
"extern const char *%s[%s];\n\n" % (self.array_name, self.count)
def defn(self):
return "const char *%s[%s] = {\n" % (self.array_name, self.count) + \
",\n".join(' "%s"'%(self.name(tag)) for tag in self.tags) + \
"\n};\n\n"
class EntityTypeEnumGenerator(object):
"""
Generates enums
"""
def __init__(self, generator, entity, name, tags):
self.generator, self.entity, self.tags = generator, entity, tags
self.enum_name = name
self.type_name = generator.type_name([entity.short_name, self.enum_name])
self.array_name = self.generator.prefix_name([entity.short_name, self.enum_name, 'names'])
self.count = self.name('ENUM_COUNT')
def name(self, tag):
return self.generator.prefix_name([self.entity.short_name, self.enum_name, tag]).upper()
def defn(self):
return "const char *%s[%s] = {\n" % (self.array_name, self.count) + \
",\n".join(' "%s"'%(tag) for tag in self.tags) + \
"\n};\n\n"
def decl(self):
tags = self.tags + ['ENUM_COUNT']
return "typedef enum {\n" + \
",\n".join([" " + self.name(tag) for tag in tags]) + \
"\n} %s;\n\n" % self.type_name + \
"extern const char *%s[%s];\n\n" % (self.array_name, self.count)
class OperationDefEnumGenerator(BaseEnumGenerator):
"""
Generates enums for the base entity operationDefs which include CREATE, READ, UPDATE, DELETE
"""
def __init__(self, generator, entity, name, tags):
self.generator, self.entity, self.tags = generator, entity, tags
self.enum_name = name
self.type_name = generator.type_name([entity.short_name, self.enum_name])
self.array_name = self.generator.prefix_name([entity.short_name, self.enum_name, 'names'])
self.count = self.name('ENUM_COUNT')
def name(self, tag):
return self.generator.prefix_name([self.entity.short_name, self.enum_name, tag]).upper()
class EnumTypeEnumGenerator(BaseEnumGenerator):
"""
Generates enums for all EnumTypes
"""
def __init__(self, generator, entity, attribute, tags):
self.generator, self.entity, self.attribute = generator, entity, attribute
self.tags = tags
self.type_name = generator.type_name([entity.short_name, attribute.name])
self.array_name = self.generator.prefix_name([entity.short_name, attribute.name, 'names'])
self.count = self.name('ENUM_COUNT')
def name(self, tag):
return self.generator.prefix_name([self.entity.short_name, self.attribute.name, tag]).upper()
def generate_enums(self):
enums = [self.EnumTypeEnumGenerator(self, entity, attribute, attribute.atype.tags)
for entity in self.schema.entity_types.itervalues()
for attribute in entity.attributes.itervalues()
if isinstance(attribute.atype, EnumType)]
# Create an enum for the operations CREATE, READ, UPDATE, DELETE, QUERY
base_entity = self.schema.entity_types.get(self.schema.prefixdot + 'entity')
enums.append(self.OperationDefEnumGenerator(self, base_entity, "operation",
self.schema.all_operation_defs.keys()))
# Create enum for entity types
entity_types = self.schema.entity_types.keys()
entity_types = [w.replace('org.apache.qpid.dispatch.', '') for w in entity_types]
enums.append(self.EntityTypeEnumGenerator(self, base_entity, "type", entity_types))
# Create enums for attributes of entities
entity_types = self.schema.entity_types
for entity_type in entity_types.values():
attribute_names = []
for attrib in entity_type.attributes.values():
attribute_names.append(attrib.name)
enums.append(self.EntityTypeEnumGenerator(self, entity_type, "attributes", attribute_names))
self.header('schema_enum', '\n'.join(e.decl() for e in enums))
self.source('schema_enum', '#include "schema_enum.h"\n\n' + '\n'.join(e.defn() for e in enums))
if __name__ == '__main__':
Generator()