| # |
| # 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() |