summaryrefslogtreecommitdiff
path: root/qpid/cpp/managementgen/generate.py
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/cpp/managementgen/generate.py')
-rwxr-xr-xqpid/cpp/managementgen/generate.py229
1 files changed, 229 insertions, 0 deletions
diff --git a/qpid/cpp/managementgen/generate.py b/qpid/cpp/managementgen/generate.py
new file mode 100755
index 0000000000..1d0987e685
--- /dev/null
+++ b/qpid/cpp/managementgen/generate.py
@@ -0,0 +1,229 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+from xml.dom.minidom import parse, parseString, Node
+from cStringIO import StringIO
+from stat import *
+from errno import *
+import os
+import os.path
+import filecmp
+
+#=====================================================================================
+#
+#=====================================================================================
+class Template:
+ def __init__ (self, filename, handler):
+ self.filename = filename
+ self.handler = handler
+
+ def expandLine (self, line, stream, object):
+ cursor = 0
+ while 1:
+ sub = line.find ("/*MGEN:", cursor)
+ if sub == -1:
+ stream.write (line[cursor:len (line)])
+ return
+
+ subend = line.find("*/", sub)
+ 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)
+
+ def expand (self, object):
+ fd = open (self.filename)
+ stream = StringIO ()
+
+ for line in fd:
+ self.expandLine (line, stream, object)
+ fd.close ()
+
+ return stream
+
+#=====================================================================================
+#
+#=====================================================================================
+class Generator:
+ def createPath (self, path):
+ exists = True
+ try:
+ mode = os.stat (path)[ST_MODE]
+ except OSError, (err,text):
+ if err == ENOENT:
+ exists = False
+ else:
+ raise
+ if exists and not S_ISDIR (mode):
+ raise ValueError ("path is not directory: %s" % path)
+ if not exists:
+ pair = os.path.split (path)
+ self.createPath (pair[0])
+ os.mkdir (path)
+
+ def normalize (self, path):
+ newpath = os.path.normcase (os.path.normpath (path))
+ self.createPath (newpath)
+ return newpath + "/"
+
+ def __init__ (self, destDir, templateDir):
+ self.dest = self.normalize (destDir)
+ self.input = self.normalize (templateDir)
+ self.filelists = {}
+ self.filelists["h"] = []
+ self.filelists["cpp"] = []
+ self.filelists["mk"] = []
+ self.templateFiles = []
+
+ def genDisclaimer (self, stream):
+ stream.write ("// This source file was created by a code generator.\n")
+ stream.write ("// Please do not edit.")
+
+ def fileExt (self, path):
+ dot = path.rfind (".")
+ if dot == -1:
+ return ""
+ return path[dot + 1:]
+
+ def writeIfChanged (self, stream, target, force=False):
+ ext = self.fileExt (target)
+ self.filelists[ext].append (target)
+ tempFile = self.dest + "gen.tmp"
+ fd = open (tempFile, "w")
+ fd.write (stream.getvalue ())
+ fd.close ()
+
+ try:
+ if not force and filecmp.cmp (target, tempFile):
+ os.remove (tempFile)
+ return
+ except:
+ pass
+
+ try:
+ os.remove (target)
+ except:
+ pass
+
+ os.rename (tempFile, target)
+ print "Generated:", target
+
+ def targetClassFile (self, _class, templateFile):
+ dot = templateFile.find(".")
+ if dot == -1:
+ raise ValueError ("Invalid template file name %s" % templateFile)
+ extension = templateFile[dot:len (templateFile)]
+ path = self.dest + _class.getName ().capitalize () + extension
+ return path
+
+ def targetMethodFile (self, method, templateFile):
+ """ Return the file name for a method file """
+ dot = templateFile.rfind(".")
+ if dot == -1:
+ raise ValueError ("Invalid template file name %s" % templateFile)
+ extension = templateFile[dot:]
+ path = self.dest + "Args" + method.getFullName () + extension
+ return path
+
+ 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)"
+ eval (call)
+
+ def makeClassFiles (self, templateFile, schema):
+ """ Generate an expanded template per schema class """
+ classes = schema.getClasses ()
+ template = Template (self.input + templateFile, self.substHandler)
+ self.templateFiles.append (templateFile)
+ for _class in classes:
+ target = self.targetClassFile (_class, templateFile)
+ stream = template.expand (_class)
+ self.writeIfChanged (stream, target)
+
+ def makeMethodFiles (self, templateFile, schema):
+ """ Generate an expanded template per method-with-arguments """
+ classes = schema.getClasses ()
+ template = Template (self.input + templateFile, self.substHandler)
+ self.templateFiles.append (templateFile)
+ for _class in classes:
+ methods = _class.getMethods ()
+ for method in methods:
+ if method.getArgCount () > 0:
+ target = self.targetMethodFile (method, templateFile)
+ stream = template.expand (method)
+ self.writeIfChanged (stream, target)
+
+ 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)