123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- #!@PYTHON@
- # Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
- #
- # Permission to use, copy, modify, and/or distribute this software for any
- # purpose with or without fee is hereby granted, provided that the above
- # copyright notice and this permission notice appear in all copies.
- #
- # THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- # REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- # AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- # LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- # PERFORMANCE OF THIS SOFTWARE.
- # $Id$
- """\
- This is a supplemental script to (half) auto-generate DNS Rdata related
- classes and constants.
- """
- import os
- import re
- import sys
- re_typecode = re.compile('([a-z]+)_(\d+)')
- classcode2txt = {}
- typecode2txt = {}
- typeandclass = []
- generic_code = 65536 # something larger than any code value
- class_declarations = ''
- class_definitions = ''
- copyright_file = '@top_srcdir@' + os.sep + 'COPYING'
- def import_classdef(class_txt, file):
- rdata_source = open(file, 'r')
- content = ''
- for line in rdata_source.readlines():
- if re.match('// BEGIN_ISC_NAMESPACE', line):
- content += 'namespace isc {\n'
- content += 'namespace dns {\n'
- continue
- if re.match('// BEGIN_RDATA_NAMESPACE', line):
- content += 'namespace rdata {\n'
- content += 'namespace ' + class_txt + ' {\n'
- continue
- if re.match('// END_ISC_NAMESPACE', line):
- content += '} // end of namespace "dns"\n'
- content += '} // end of namespace "isc"\n'
- continue
- if re.match('// END_RDATA_NAMESPACE', line):
- content += '} // end of namespace "' + class_txt +'"\n'
- content += '} // end of namespace "rdata"\n'
- continue
- content += line
- rdata_source.close()
- return content
- def import_classheader(class_txt, type_txt, type_code, file):
- # for each CLASS_n/TYPE_m.h
- rdata_header = open(file, 'r')
- content = ''
- guard_macro = '__' + class_txt.upper() + '_' + type_txt.upper()
- guard_macro += '_' + type_code + '_H'
- for line in rdata_header.readlines():
- if re.match('// BEGIN_HEADER_GUARD', line):
- content += '#ifndef ' + guard_macro + '\n'
- content += '#define ' + guard_macro + ' 1\n'
- continue
- if re.match('// END_HEADER_GUARD', line):
- content += '#endif // ' + guard_macro + '\n'
- continue
- if re.match('// BEGIN_ISC_NAMESPACE', line):
- content += 'namespace isc {\n'
- content += 'namespace dns {\n'
- continue
- if re.match('// BEGIN_RDATA_NAMESPACE', line):
- content += 'namespace rdata {\n'
- content += 'namespace ' + class_txt + ' {\n'
- continue
- if re.match('// END_ISC_NAMESPACE', line):
- content += '} // end of namespace "dns"\n'
- content += '} // end of namespace "isc"\n'
- continue
- if re.match('// END_RDATA_NAMESPACE', line):
- content += '} // end of namespace "' + class_txt +'"\n'
- content += '} // end of namespace "rdata"\n'
- continue
- if re.match('// Local Variables:', line):
- break
- content += line
- if re.match('// BEGIN_COMMON_DECLARATIONS', line):
- content += '''
- class InputBuffer;
- class OutputBuffer;
- class MessageRenderer;\n\n'''
- if re.match('\s+// BEGIN_COMMON_MEMBERS$', line):
- content += '''
- explicit ''' + type_utxt + '''(const std::string& type_str);
- explicit ''' + type_utxt + '''(InputBuffer& buffer, size_t rdata_len);
- ''' + type_utxt + '''(const ''' + type_utxt + '''& other);
- virtual std::string toText() const;
- virtual void toWire(OutputBuffer& buffer) const;
- virtual void toWire(MessageRenderer& renderer) const;
- virtual int compare(const Rdata& other) const;\n\n'''
- rdata_header.close()
- return content
- def import_copyright():
- copyright_txt = ''
- f = open(copyright_file, 'r')
- for line in f.readlines():
- copyright_txt += '// ' + line
- f.close()
- copyright_txt += '''
- ///////////////
- ///////////////
- /////////////// THIS FILE IS AUTOMATICALLY GENERATED BY gen-rdatacode.py.
- /////////////// DO NOT EDIT!
- ///////////////
- ///////////////
- '''
- return copyright_txt
- if __name__ == "__main__":
- copyright_txt = import_copyright()
- for dir in list(os.listdir('@srcdir@/rdata')):
- classdir = '@srcdir@/rdata' + os.sep + dir
- m = re_typecode.match(dir)
- if os.path.isdir(classdir) and (m != None or dir == 'generic'):
- if dir == 'generic':
- class_txt = 'generic'
- class_code = generic_code
- else:
- class_txt = m.group(1)
- class_code = m.group(2)
- if not class_code in classcode2txt:
- classcode2txt[class_code] = class_txt
- for file in list(os.listdir(classdir)):
- file = classdir + os.sep + file
- m = re_typecode.match(os.path.split(file)[1])
- if m != None:
- type_txt = m.group(1)
- type_code = m.group(2)
- type_utxt = type_txt.upper()
- class_utxt = class_txt.upper()
- if not type_code in typecode2txt:
- typecode2txt[type_code] = type_txt
- if re.search('\cc$', file):
- class_definitions += import_classdef(class_txt, file)
- elif re.search('\h$', file):
- class_declarations += import_classheader(class_txt,
- type_txt,
- type_code,
- file)
- typeandclass.append((type_txt, int(type_code),
- (class_txt, class_txt),
- int(class_code)))
- if class_txt == 'generic':
- typeandclass.append((type_txt, int(type_code),
- (class_txt, 'in'), 1))
- rdata_deffile = open('rdataclass.cc', 'w')
- rdata_deffile.write(copyright_txt)
- rdata_deffile.write(class_definitions)
- rdata_deffile.close()
- class_declarations += '''
- // Local Variables:
- // mode: c++
- // End:
- '''
- rdata_header = open('rdataclass.h', 'w')
- rdata_header.write(copyright_txt)
- rdata_header.write(class_declarations)
- rdata_header.close()
-
- declarationtxt = ''
- deftxt = ''
- for code in typecode2txt.keys():
- # for rrtype.h
- rrtype = typecode2txt[code].upper()
- declarationtxt += ' ' * 4 + 'static const RRType& ' + rrtype + '();\n'
- deftxt += '''inline const RRType&
- RRType::''' + rrtype + '''()
- {
- static RRType rrtype(''' + code + ''');
- return (rrtype);
- }\n
- '''
- rrtype_header_temp = open('@srcdir@/rrtype-placeholder.h', 'r')
- rrtype_header_out = open('rrtype.h', 'w')
- rrtype_header_out.write(copyright_txt)
- for line in rrtype_header_temp.readlines():
- rrtype_header_out.write(line)
- if re.match('\s+// BEGIN_WELL_KNOWN_TYPE_DECLARATIONS$', line):
- rrtype_header_out.write(declarationtxt)
- if re.match('// BEGIN_WELL_KNOWN_TYPE_DEFINITIONS$', line):
- rrtype_header_out.write('\n' + deftxt)
- rrtype_header_out.close()
- rrtype_header_temp.close()
- declarationtxt = ''
- deftxt = ''
- for code in classcode2txt.keys():
- # for rrclass.h
- rrclass = classcode2txt[code].upper()
- declarationtxt += ' ' * 4 + 'static const RRClass& ' + rrclass + '();\n'
- deftxt += '''inline const RRClass&
- RRClass::''' + rrclass + '''()
- {
- static RRClass rrclass(''' + code + ''');
- return (rrclass);
- }\n
- '''
- rrclass_header_temp = open('@srcdir@/rrclass-placeholder.h', 'r')
- rrclass_header_out = open('rrclass.h', 'w')
- rrclass_header_out.write(copyright_txt)
- for line in rrclass_header_temp.readlines():
- rrclass_header_out.write(line)
- if re.match('\s+// BEGIN_WELL_KNOWN_CLASS_DECLARATIONS$', line):
- rrclass_header_out.write(declarationtxt)
- if re.match('// BEGIN_WELL_KNOWN_CLASS_DEFINITIONS$', line):
- rrclass_header_out.write('\n' + deftxt)
- rrclass_header_out.close()
- rrclass_header_temp.close()
- # sort by class, then by type
- typeandclassparams = ''
- typeandclass.sort(key = lambda x: (x[3], x[1]))
- for param in typeandclass:
- # for rdata.cc
- # each param is a tuple of (type_txt, type_code, class_tuple, class_code)
- (type_txt, type_code, class_tuple, class_code) = param
- type_utxt = type_txt.upper()
- class_txt = class_tuple[0]
- class_utxt = class_tuple[1].upper()
- indent = ' ' * 8
- typeandclassparams += indent
- if class_tuple[1] != 'generic':
- typeandclassparams += 'add("' + type_utxt + '", '
- typeandclassparams += str(type_code) + ', "' + class_utxt
- typeandclassparams += '", ' + str(class_code)
- typeandclassparams += ', RdataFactoryPtr(new RdataFactory<'
- typeandclassparams += class_txt + '::' + type_utxt + '>()));\n'
- else:
- typeandclassparams += 'add("' + type_utxt + '", ' + str(type_code)
- typeandclassparams += ', RdataFactoryPtr(new RdataFactory<'
- typeandclassparams += class_txt + '::' + type_utxt + '>()));\n'
- rrparam_temp = open('@srcdir@/rrparamregistry-placeholder.cc', 'r')
- rrparam_out = open('rrparamregistry.cc', 'w')
- rrparam_out.write(copyright_txt)
- for line in rrparam_temp.readlines():
- rrparam_out.write(line)
- if re.match('\s+// BEGIN_WELL_KNOWN_PARAMS', line):
- rrparam_out.write(typeandclassparams)
- rrparam_temp.close()
- rrparam_out.close()
|