Browse Source

[1866] update gen_rdatacode to autogenerate C++ code for some python wrapper.

specifically, it generates code to create RRType and RRClass constants.
JINMEI Tatuya 12 years ago
parent
commit
62bb1c4ddc
3 changed files with 40 additions and 12 deletions
  1. 4 0
      src/lib/dns/Makefile.am
  2. 32 12
      src/lib/dns/gen-rdatacode.py.in
  3. 4 0
      src/lib/dns/python/pydnspp.cc

+ 4 - 0
src/lib/dns/Makefile.am

@@ -8,6 +8,10 @@ AM_CXXFLAGS = $(B10_CXXFLAGS)
 
 CLEANFILES = *.gcno *.gcda
 CLEANFILES += rrclass.h rrtype.h rrparamregistry.cc rdataclass.h rdataclass.cc
+# These two are created with rrtype/class.h, so not explicitly listed in
+# BUILT_SOURCES.
+CLEANFILES += python/rrtype_constants_inc.cc
+CLEANFILES += python/rrclass_constants_inc.cc
 
 EXTRA_DIST = rrclass-placeholder.h
 EXTRA_DIST += rrparamregistry-placeholder.cc

+ 32 - 12
src/lib/dns/gen-rdatacode.py.in

@@ -255,16 +255,22 @@ class MasterLoaderCallbacks;
 def generate_typeclasscode(fileprefix, basemtime, code2txt, type_or_class):
     placeholder = '@srcdir@/' + fileprefix + '-placeholder.h'
     outputfile = '@builddir@/' + fileprefix + '.h'
+    py_outputfile = '@builddir@/python/' + fileprefix + '_constants_inc.cc'
     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):
+    # We only decide whether to generate files for libdns++ files; Python
+    # files are generated if and only if libdns++ files are generated.
+    # In practice it should be sufficient.
+    if (not need_generate(outputfile, basemtime) and
+        getmtime(outputfile) > getmtime(placeholder)):
         print('skip generating ' + outputfile)
         return
 
     declarationtxt = ''
     deftxt = ''
+    pydef_txt = ''
     for code in code2txt.keys():
         codetxt = code2txt[code].upper()
         declarationtxt += ' ' * 4 + 'static const RR' + cap_key + '& ' + codetxt + '();\n'
@@ -274,17 +280,31 @@ RR''' + cap_key + '''::''' + codetxt + '''() {
     return (''' + lower_key + ''');
 }\n
 '''
-    header_temp = open(placeholder, 'r')
-    header_out = open(outputfile, 'w')
-    header_out.write(heading_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()
+        pydef_txt += '''\
+    installClassVariable(''' + lower_key + '''_type, "''' + codetxt + '''",
+                         createRR''' + cap_key + '''Object(RR''' + \
+        cap_key + '''::''' + codetxt + '''()));
+'''
+
+    # Dump source code for libdns++
+    with  open(placeholder, 'r') as header_temp:
+        with open(outputfile, 'w') as header_out:
+            header_out.write(heading_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)
+
+    # Dump source code snippet for isc.dns Python module
+    with open(py_outputfile, 'w') as py_out:
+        py_out.write("    // auto-generated by ../gen-rdatacode.py."
+                     "  Don't edit this file.\n")
+        py_out.write("\n")
+        py_out.write(pydef_txt)
 
 def generate_rrparam(fileprefix, basemtime):
     placeholder = '@srcdir@/' + fileprefix + '-placeholder.cc'

+ 4 - 0
src/lib/dns/python/pydnspp.cc

@@ -432,6 +432,8 @@ initModulePart_RRClass(PyObject* mod) {
                                                   NULL, NULL);
         PyObjectContainer(po_IncompleteRRClass).installToModule(
             mod, "IncompleteRRClass");
+
+#include <dns/python/rrclass_constants_inc.cc>
     } catch (const std::exception& ex) {
         const std::string ex_what =
             "Unexpected failure in RRClass initialization: " +
@@ -518,6 +520,8 @@ initModulePart_RRType(PyObject* mod) {
                                                  NULL, NULL);
         PyObjectContainer(po_IncompleteRRType).installToModule(
             mod, "IncompleteRRType");
+
+#include <dns/python/rrtype_constants_inc.cc>
     } catch (const std::exception& ex) {
         const std::string ex_what =
             "Unexpected failure in RRType initialization: " +