[svn] commit: r744 - /branches/jinmei-dnsrdata2/src/lib/dns/cpp/gen-rdatacode.py.in
BIND 10 source code commits
bind10-changes at lists.isc.org
Sat Feb 6 07:40:52 UTC 2010
Author: jinmei
Date: Sat Feb 6 07:40:52 2010
New Revision: 744
Log:
- avoided unnecessary file generation based on time stamps
- handle exceptions in a more sophisticated way
- made it more modular
Modified:
branches/jinmei-dnsrdata2/src/lib/dns/cpp/gen-rdatacode.py.in (contents, props changed)
Modified: branches/jinmei-dnsrdata2/src/lib/dns/cpp/gen-rdatacode.py.in
==============================================================================
--- branches/jinmei-dnsrdata2/src/lib/dns/cpp/gen-rdatacode.py.in (original)
+++ branches/jinmei-dnsrdata2/src/lib/dns/cpp/gen-rdatacode.py.in Sat Feb 6 07:40:52 2010
@@ -22,6 +22,7 @@
"""
import os
+from os.path import getmtime
import re
import sys
@@ -30,13 +31,16 @@
typecode2txt = {}
typeandclass = []
generic_code = 65536 # something larger than any code value
-class_declarations = ''
+rdata_declarations = ''
class_definitions = ''
+classdir_mtime = 0
+rdatadef_mtime = 0
+rdatahdr_mtime = 0
copyright_file = '@top_srcdir@' + os.sep + 'COPYING'
def import_classdef(class_txt, file):
+ content = ''
rdata_source = open(file, 'r')
- content = ''
for line in rdata_source.readlines():
if re.match('// BEGIN_ISC_NAMESPACE', line):
content += 'namespace isc {\n'
@@ -59,6 +63,9 @@
return content
def import_classheader(class_txt, type_txt, type_code, file):
+ type_utxt = type_txt.upper()
+ class_utxt = class_txt.upper()
+
# for each CLASS_n/TYPE_m.h
rdata_header = open(file, 'r')
content = ''
@@ -125,12 +132,19 @@
'''
return copyright_txt
-if __name__ == "__main__":
- copyright_txt = import_copyright()
+def import_definitions(classcode2txt, typecode2txt, typeandclass):
+ global rdata_declarations
+ global class_definitions
+ global classdir_mtime
+ global rdatadef_mtime
+ global rdatahdr_mtime
+
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 classdir_mtime < getmtime(classdir):
+ classdir_mtime = getmtime(classdir)
if dir == 'generic':
class_txt = 'generic'
class_code = generic_code
@@ -145,15 +159,16 @@
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):
+ if rdatadef_mtime < getmtime(file):
+ rdatadef_mtime = getmtime(file)
class_definitions += import_classdef(class_txt, file)
elif re.search('\h$', file):
- class_declarations += import_classheader(class_txt,
+ if rdatahdr_mtime < getmtime(file):
+ rdatahdr_mtime = getmtime(file)
+ rdata_declarations += import_classheader(class_txt,
type_txt,
type_code,
file)
@@ -163,78 +178,89 @@
if class_txt == 'generic':
typeandclass.append((type_txt, int(type_code),
(class_txt, 'in'), 1))
- rdata_deffile = open('@srcdir@/rdataclass.cc', 'w')
+
+def need_generate(file, mtime):
+ '''Check if we need to generate the specified file.
+
+ To avoid unnecessary compilation, we skip (re)generating the file when
+ the file already exists and newer than the base file.
+ '''
+ if os.path.exists(file) and getmtime(file) > mtime:
+ return False
+ return True
+
+def generate_rdatadef(file, copyright_txt, basemtime):
+ if not need_generate(file, basemtime):
+ print('skip generating ' + file);
+ return
+ rdata_deffile = open(file, 'w')
rdata_deffile.write(copyright_txt)
rdata_deffile.write(class_definitions)
rdata_deffile.close()
- class_declarations += '''
+def generate_rdatahdr(file, copyright_txt, declarations, basemtime):
+ if not need_generate(file, basemtime):
+ print('skip generating ' + file);
+ return
+ declarations += '''
// Local Variables:
// mode: c++
// End:
'''
- rdata_header = open('@srcdir@/rdataclass.h', 'w')
+ rdata_header = open(file, 'w')
rdata_header.write(copyright_txt)
- rdata_header.write(class_declarations)
+ rdata_header.write(declarations)
rdata_header.close()
-
+
+def generate_typeclasscode(fileprefix, basemtime, code2txt, type_or_class):
+ placeholder = fileprefix + '-placeholder.h'
+ outputfile = fileprefix + '.h'
+ upper_key = type_or_class.upper() # TYPE or CLASS
+ lower_key = 'rr' + type_or_class.lower() # rrtype or rrclass
+ cap_key = type_or_class # Type or Class
+
+ if not need_generate(outputfile, basemtime) and getmtime(outputfile) > getmtime(placeholder):
+ print('skip generating ' + outputfile)
+ return
+
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 + '''()
+ for code in code2txt.keys():
+ codetxt = code2txt[code].upper()
+ declarationtxt += ' ' * 4 + 'static const RR' + cap_key + '& ' + codetxt + '();\n'
+ deftxt += '''inline const RR''' + cap_key + '''&
+RR''' + cap_key + '''::''' + codetxt + '''()
{
- static RRType rrtype(''' + code + ''');
- return (rrtype);
+ static RR''' + cap_key + ''' ''' + lower_key + '''(''' + code + ''');
+ return (''' + lower_key + ''');
}\n
'''
- rrtype_header_temp = open('@srcdir@/rrtype-placeholder.h', 'r')
- rrtype_header_out = open('@srcdir@/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('@srcdir@/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()
+ header_temp = open(placeholder, 'r')
+ header_out = open(outputfile, 'w')
+ header_out.write(copyright_txt)
+ for line in header_temp.readlines():
+ header_out.write(line)
+ if re.match('\s+// BEGIN_WELL_KNOWN_' + upper_key + '_DECLARATIONS$', line):
+ header_out.write(declarationtxt)
+ if re.match('// BEGIN_WELL_KNOWN_' + upper_key + '_DEFINITIONS$', line):
+ header_out.write('\n' + deftxt)
+ header_out.close()
+ header_temp.close()
+
+def generate_rrparam(fileprefix, basemtime):
+ placeholder = fileprefix + '-placeholder.cc'
+ outputfile = fileprefix + '.cc'
+ if not need_generate(outputfile, basemtime) and getmtime(outputfile) > getmtime(placeholder):
+ print('skip generating ' + outputfile)
+ return
# 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)
+ # for rrparamregistry.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]
@@ -252,8 +278,8 @@
typeandclassparams += ', RdataFactoryPtr(new RdataFactory<'
typeandclassparams += class_txt + '::' + type_utxt + '>()));\n'
- rrparam_temp = open('@srcdir@/rrparamregistry-placeholder.cc', 'r')
- rrparam_out = open('@srcdir@/rrparamregistry.cc', 'w')
+ rrparam_temp = open(placeholder, 'r')
+ rrparam_out = open(outputfile, 'w')
rrparam_out.write(copyright_txt)
for line in rrparam_temp.readlines():
rrparam_out.write(line)
@@ -261,3 +287,22 @@
rrparam_out.write(typeandclassparams)
rrparam_temp.close()
rrparam_out.close()
+
+if __name__ == "__main__":
+ try:
+ copyright_txt = import_copyright()
+ import_definitions(classcode2txt, typecode2txt, typeandclass)
+ generate_rdatadef('@srcdir@/rdataclass.cc', copyright_txt,
+ rdatadef_mtime)
+ generate_rdatahdr('@srcdir@/rdataclass.h', copyright_txt,
+ rdata_declarations, rdatahdr_mtime)
+ generate_typeclasscode('@srcdir@/rrtype',
+ max(rdatadef_mtime, rdatahdr_mtime),
+ typecode2txt, 'Type')
+ generate_typeclasscode('@srcdir@/rrclass', classdir_mtime,
+ classcode2txt, 'Class')
+ generate_rrparam('@srcdir@/rrparamregistry', rdatahdr_mtime)
+ except:
+ sys.stderr.write('Code generation failed due to exception: %s\n' %
+ sys.exc_info()[1])
+ exit(1)
More information about the bind10-changes
mailing list