summaryrefslogtreecommitdiff
path: root/cpp/managementgen
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/managementgen')
-rwxr-xr-xcpp/managementgen/generate.py164
-rwxr-xr-xcpp/managementgen/main.py29
-rwxr-xr-xcpp/managementgen/schema.py64
-rw-r--r--cpp/managementgen/templates/Args.h1
-rw-r--r--cpp/managementgen/templates/Class.cpp1
-rw-r--r--cpp/managementgen/templates/Class.h1
6 files changed, 141 insertions, 119 deletions
diff --git a/cpp/managementgen/generate.py b/cpp/managementgen/generate.py
index 1d0987e685..4c042bd3f6 100755
--- a/cpp/managementgen/generate.py
+++ b/cpp/managementgen/generate.py
@@ -27,13 +27,18 @@ import os
import os.path
import filecmp
-#=====================================================================================
-#
-#=====================================================================================
class Template:
+ """
+ Expandable File Template - This class is instantiated each time a
+ template is to be expanded. It is instantiated with the "filename"
+ which is the full path to the template file and the "handler" which
+ is an object that is responsible for storing variables (setVariable)
+ and expanding tags (substHandler).
+ """
def __init__ (self, filename, handler):
self.filename = filename
self.handler = handler
+ self.handler.initExpansion ()
def expandLine (self, line, stream, object):
cursor = 0
@@ -47,29 +52,78 @@ class Template:
stream.write (line[cursor:sub])
cursor = subend + 2
- tag = line[sub:subend]
- dotPos = tag.find (".")
- if dotPos == -1:
- raise ValueError ("Invalid tag: %s" % tag)
- tagObject = tag[7:dotPos]
- tagName = tag[dotPos + 1:len (tag)]
-
- self.handler (object, stream, tagObject, tagName)
+ tag = line[sub:subend]
+ equalPos = tag.find ("=")
+ if equalPos == -1:
+ dotPos = tag.find (".")
+ if dotPos == -1:
+ raise ValueError ("Invalid tag: %s" % tag)
+ tagObject = tag[7:dotPos]
+ tagName = tag[dotPos + 1:len (tag)]
+ self.handler.substHandler (object, stream, tagObject, tagName)
+ else:
+ tagKey = tag[7:equalPos]
+ tagVal = tag[equalPos + 1:len (tag)]
+ self.handler.setVariable (tagKey, tagVal)
def expand (self, object):
fd = open (self.filename)
stream = StringIO ()
-
+
for line in fd:
self.expandLine (line, stream, object)
fd.close ()
return stream
-#=====================================================================================
-#
-#=====================================================================================
+
+class Makefile:
+ """ Object representing a makefile fragment """
+ def __init__ (self, filelists, templateFiles):
+ self.filelists = filelists
+ self.templateFiles = templateFiles
+
+ def genGenSources (self, stream, variables):
+ mdir = variables["mgenDir"]
+ sdir = variables["specDir"]
+ stream.write (mdir + "/main.py \\\n")
+ stream.write (" " + mdir + "/generate.py \\\n")
+ stream.write (" " + mdir + "/schema.py \\\n")
+ stream.write (" " + sdir + "/management-types.xml \\\n")
+ stream.write (" " + sdir + "/management-schema.xml \\\n")
+ first = True
+ for template in self.templateFiles:
+ if first:
+ first = False
+ stream.write (" ")
+ else:
+ stream.write (" \\\n ")
+ stream.write (mdir + "/templates/" + template)
+
+ def genGenCppFiles (self, stream, variables):
+ first = True
+ for file in self.filelists["cpp"]:
+ if first:
+ first = False
+ else:
+ stream.write (" \\\n ")
+ stream.write (file)
+
+ def genGenHFiles (self, stream, variables):
+ first = True
+ for file in self.filelists["h"]:
+ if first:
+ first = False
+ else:
+ stream.write (" \\\n ")
+ stream.write (file)
+
+
class Generator:
+ """
+ This class manages code generation using template files. It is instantiated
+ once for an entire code generation session.
+ """
def createPath (self, path):
exists = True
try:
@@ -99,10 +153,12 @@ class Generator:
self.filelists["cpp"] = []
self.filelists["mk"] = []
self.templateFiles = []
+ self.variables = {}
- def genDisclaimer (self, stream):
- stream.write ("// This source file was created by a code generator.\n")
- stream.write ("// Please do not edit.")
+ def genDisclaimer (self, stream, variables):
+ prefix = variables["commentPrefix"]
+ stream.write (prefix + " This source file was created by a code generator.\n")
+ stream.write (prefix + " Please do not edit.")
def fileExt (self, path):
dot = path.rfind (".")
@@ -150,29 +206,35 @@ class Generator:
path = self.dest + "Args" + method.getFullName () + extension
return path
+ def initExpansion (self):
+ self.variables = {}
+
def substHandler (self, object, stream, tagObject, tag):
if tagObject == "Root":
obj = "self"
else:
obj = "object" # MUST be the same as the 2nd formal parameter
- call = obj + ".gen" + tag + "(stream)"
+ call = obj + ".gen" + tag + "(stream, self.variables)"
eval (call)
- def makeClassFiles (self, templateFile, schema):
+ def setVariable (self, key, value):
+ self.variables[key] = value
+
+ def makeClassFiles (self, templateFile, schema, force=False):
""" Generate an expanded template per schema class """
classes = schema.getClasses ()
- template = Template (self.input + templateFile, self.substHandler)
+ template = Template (self.input + templateFile, self)
self.templateFiles.append (templateFile)
for _class in classes:
target = self.targetClassFile (_class, templateFile)
stream = template.expand (_class)
- self.writeIfChanged (stream, target)
+ self.writeIfChanged (stream, target, force)
- def makeMethodFiles (self, templateFile, schema):
+ def makeMethodFiles (self, templateFile, schema, force=False):
""" Generate an expanded template per method-with-arguments """
classes = schema.getClasses ()
- template = Template (self.input + templateFile, self.substHandler)
+ template = Template (self.input + templateFile, self)
self.templateFiles.append (templateFile)
for _class in classes:
methods = _class.getMethods ()
@@ -180,50 +242,12 @@ class Generator:
if method.getArgCount () > 0:
target = self.targetMethodFile (method, templateFile)
stream = template.expand (method)
- self.writeIfChanged (stream, target)
+ self.writeIfChanged (stream, target, force)
- def makeMakeFile (self, target):
- stream = StringIO ()
- stream.write ("# Generated makefile fragment.\n\n")
- stream.write ("mgen_generator=$(mgen_dir)/main.py \\\n")
- stream.write (" $(mgen_dir)/generate.py \\\n")
- stream.write (" $(mgen_dir)/schema.py \\\n")
- stream.write (" $(top_srcdir)/../specs/management-types.xml \\\n")
- stream.write (" $(top_srcdir)/../specs/management-schema.xml \\\n ")
- first = 1
- for template in self.templateFiles:
- if first == 1:
- first = 0
- else:
- stream.write (" \\\n ")
- stream.write ("$(mgen_dir)/templates/" + template)
-
- stream.write ("\n\nmgen_broker_cpp=")
- first = 1
- for file in self.filelists["cpp"]:
- if first == 1:
- first = 0
- else:
- stream.write (" \\\n ")
- stream.write (file.replace ("../src", "."))
- stream.write ("\n\n")
-
- stream.write ("# Header file install rules.\n")
- stream.write ("qpid_managementdir = $(includedir)/qpid/management\n")
- stream.write ("dist_qpid_management_HEADERS = ")
- first = 1
- for file in self.filelists["h"]:
- if first == 1:
- first = 0
- else:
- stream.write (" \\\n ")
- stream.write (file.replace ("../src", "."))
- stream.write ("\n\n")
-
- stream.write ("if GENERATE\n")
- stream.write ("$(srcdir)/managementgen.mk: $(mgen_generator)\n")
- stream.write ("\t$(mgen_cmd)\n")
- stream.write ("\n$(mgen_generator):\n")
- stream.write ("endif\n")
-
- self.writeIfChanged (stream, target, force=True)
+ def makeSingleFile (self, templateFile, target, force=False):
+ """ Generate a single expanded template """
+ makefile = Makefile (self.filelists, self.templateFiles)
+ template = Template (self.input + templateFile, self)
+ self.templateFiles.append (templateFile)
+ stream = template.expand (makefile)
+ self.writeIfChanged (stream, target, force)
diff --git a/cpp/managementgen/main.py b/cpp/managementgen/main.py
index ddf18ef873..de8ce4cbe6 100755
--- a/cpp/managementgen/main.py
+++ b/cpp/managementgen/main.py
@@ -24,32 +24,27 @@ from generate import Generator
from optparse import OptionParser
# Set command line options
-parser = OptionParser ()
-parser.add_option ("-o", "--outDir", dest="outdir", metavar="DIR",
- help="Destination directory for generated files")
-parser.add_option ("-t", "--typeFile", dest="typefile", metavar="FILE",
- help="Schema type document (XML file)")
-parser.add_option ("-s", "--schemaFile", dest="schemafile", metavar="FILE",
- help="Schema defintion document (XML file)")
-parser.add_option ("-i", "--templateDir", dest="templatedir", metavar="DIR",
- help="Directory where template files can be found")
+usage = "usage: %prog [options] schema-document type-document template-directory out-directory"
+parser = OptionParser (usage=usage)
parser.add_option ("-m", "--makefile", dest="makefile", metavar="FILE",
help="Makefile fragment")
(opts, args) = parser.parse_args ()
-if opts.outdir == None or \
- opts.typefile == None or \
- opts.schemafile == None or \
- opts.templatedir == None:
- parser.error ("Incorrect options, see --help for help")
+if len (args) < 4:
+ parser.error ("Too few arguments")
-gen = Generator (opts.outdir, opts.templatedir)
-schema = PackageSchema (opts.typefile, opts.schemafile)
+schemafile = args[0]
+typefile = args[1]
+templatedir = args[2]
+outdir = args[3]
+
+gen = Generator (outdir, templatedir)
+schema = PackageSchema (typefile, schemafile)
gen.makeClassFiles ("Class.h", schema)
gen.makeClassFiles ("Class.cpp", schema)
gen.makeMethodFiles ("Args.h", schema)
if opts.makefile != None:
- gen.makeMakeFile (opts.makefile)
+ gen.makeSingleFile ("Makefile.mk", opts.makefile, force=True)
diff --git a/cpp/managementgen/schema.py b/cpp/managementgen/schema.py
index 34121a2544..ef3fb50667 100755
--- a/cpp/managementgen/schema.py
+++ b/cpp/managementgen/schema.py
@@ -461,19 +461,19 @@ class SchemaMethod:
# Code Generation Functions. The names of these functions (minus the leading "gen")
# match the substitution keywords in the template files.
#===================================================================================
- def genNameUpper (self, stream):
+ def genNameUpper (self, stream, variables):
stream.write (self.getFullName ().upper ())
- def genNameCamel (self, stream):
+ def genNameCamel (self, stream, variables):
stream.write (self.getFullName ())
- def genArguments (self, stream):
+ def genArguments (self, stream, variables):
for arg in self.args:
ctype = arg.type.type.cpp
dirTag = arg.dir.lower() + "_"
stream.write (" " + ctype + " " + dirTag + arg.getName () + ";\n")
- def genSchema (self, stream):
+ def genSchema (self, stream, variables):
stream.write (" ft = FieldTable ();\n")
stream.write (" ft.setString (NAME, \"" + self.name + "\");\n")
stream.write (" ft.setInt (ARGCOUNT, " + str (len (self.args)) + ");\n")
@@ -571,25 +571,25 @@ class SchemaClass:
# Code Generation Functions. The names of these functions (minus the leading "gen")
# match the substitution keywords in the template files.
#===================================================================================
- def genAccessorMethods (self, stream):
+ def genAccessorMethods (self, stream, variables):
for config in self.configElements:
if config.access != "RC":
config.genAccessor (stream)
for inst in self.instElements:
inst.genAccessor (stream)
- def genConfigCount (self, stream):
+ def genConfigCount (self, stream, variables):
stream.write ("%d" % len (self.configElements))
- def genConfigDeclarations (self, stream):
+ def genConfigDeclarations (self, stream, variables):
for element in self.configElements:
element.genDeclaration (stream)
- def genConfigElementSchema (self, stream):
+ def genConfigElementSchema (self, stream, variables):
for config in self.configElements:
config.genSchema (stream)
- def genConstructorArgs (self, stream):
+ def genConstructorArgs (self, stream, variables):
# Constructor args are config elements with read-create access
result = ""
first = 1
@@ -601,12 +601,12 @@ class SchemaClass:
stream.write (", ")
element.genFormalParam (stream)
- def genConstructorInits (self, stream):
+ def genConstructorInits (self, stream, variables):
for element in self.configElements:
if element.isConstructorArg ():
stream.write ("," + element.getName () + "(_" + element.getName () + ")")
- def genDoMethodArgs (self, stream):
+ def genDoMethodArgs (self, stream, variables):
methodCount = 0
inArgCount = 0
for method in self.methods:
@@ -623,26 +623,26 @@ class SchemaClass:
else:
stream.write ("string methodName, Buffer& inBuf, Buffer& outBuf")
- def genEventCount (self, stream):
+ def genEventCount (self, stream, variables):
stream.write ("%d" % len (self.events))
- def genEventSchema (self, stream):
+ def genEventSchema (self, stream, variables):
pass ###########################################################################
- def genHiLoStatResets (self, stream):
+ def genHiLoStatResets (self, stream, variables):
for inst in self.instElements:
inst.genHiLoStatResets (stream)
- def genInitializeElements (self, stream):
+ def genInitializeElements (self, stream, variables):
for inst in self.instElements:
inst.genInitialize (stream)
- def genInstChangedStub (self, stream):
+ def genInstChangedStub (self, stream, variables):
if len (self.instElements) == 0:
stream.write (" // Stub for getInstChanged. There are no inst elements\n")
stream.write (" bool getInstChanged (void) { return false; }\n")
- def genInstCount (self, stream):
+ def genInstCount (self, stream, variables):
count = 0
for inst in self.instElements:
count = count + 1
@@ -650,24 +650,24 @@ class SchemaClass:
count = count + 2
stream.write ("%d" % count)
- def genInstDeclarations (self, stream):
+ def genInstDeclarations (self, stream, variables):
for element in self.instElements:
element.genDeclaration (stream)
- def genInstElementSchema (self, stream):
+ def genInstElementSchema (self, stream, variables):
for inst in self.instElements:
inst.genSchema (stream)
- def genMethodArgIncludes (self, stream):
+ def genMethodArgIncludes (self, stream, variables):
for method in self.methods:
if method.getArgCount () > 0:
stream.write ("#include \"qpid/management/Args" +\
method.getFullName () + ".h\"\n")
- def genMethodCount (self, stream):
+ def genMethodCount (self, stream, variables):
stream.write ("%d" % len (self.methods))
- def genMethodHandlers (self, stream):
+ def genMethodHandlers (self, stream, variables):
for method in self.methods:
stream.write ("\n if (methodName == \"" + method.getName () + "\")\n {\n")
if method.getArgCount () == 0:
@@ -694,44 +694,44 @@ class SchemaClass:
stream.write (" return;\n }\n")
- def genMethodIdDeclarations (self, stream):
+ def genMethodIdDeclarations (self, stream, variables):
number = 1
for method in self.methods:
stream.write (" static const uint32_t METHOD_" + method.getName().upper() +\
" = %d;\n" % number)
number = number + 1
- def genMethodSchema (self, stream):
+ def genMethodSchema (self, stream, variables):
for method in self.methods:
- method.genSchema (stream)
+ method.genSchema (stream, variables)
- def genNameCap (self, stream):
+ def genNameCap (self, stream, variables):
stream.write (self.name.capitalize ())
- def genNameLower (self, stream):
+ def genNameLower (self, stream, variables):
stream.write (self.name.lower ())
- def genNameUpper (self, stream):
+ def genNameUpper (self, stream, variables):
stream.write (self.name.upper ())
- def genParentArg (self, stream):
+ def genParentArg (self, stream, variables):
for config in self.configElements:
if config.isParentRef == 1:
stream.write (" _parent")
return
- def genParentRefAssignment (self, stream):
+ def genParentRefAssignment (self, stream, variables):
for config in self.configElements:
if config.isParentRef == 1:
stream.write (config.getName () + \
" = _parent->GetManagementObject ()->getObjectId ();")
return
- def genWriteConfig (self, stream):
+ def genWriteConfig (self, stream, variables):
for config in self.configElements:
config.genWrite (stream);
- def genWriteInst (self, stream):
+ def genWriteInst (self, stream, variables):
for inst in self.instElements:
inst.genWrite (stream);
diff --git a/cpp/managementgen/templates/Args.h b/cpp/managementgen/templates/Args.h
index 4a6413ddc9..576d891a3f 100644
--- a/cpp/managementgen/templates/Args.h
+++ b/cpp/managementgen/templates/Args.h
@@ -1,3 +1,4 @@
+/*MGEN:commentPrefix=//*/
#ifndef _ARGS_/*MGEN:Method.NameUpper*/_
#define _ARGS_/*MGEN:Method.NameUpper*/_
diff --git a/cpp/managementgen/templates/Class.cpp b/cpp/managementgen/templates/Class.cpp
index d3b95fd674..d87d11f767 100644
--- a/cpp/managementgen/templates/Class.cpp
+++ b/cpp/managementgen/templates/Class.cpp
@@ -1,3 +1,4 @@
+/*MGEN:commentPrefix=//*/
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
diff --git a/cpp/managementgen/templates/Class.h b/cpp/managementgen/templates/Class.h
index 6a54b2131c..ba6a1183e2 100644
--- a/cpp/managementgen/templates/Class.h
+++ b/cpp/managementgen/templates/Class.h
@@ -1,3 +1,4 @@
+/*MGEN:commentPrefix=//*/
#ifndef _MANAGEMENT_/*MGEN:Class.NameUpper*/_
#define _MANAGEMENT_/*MGEN:Class.NameUpper*/_