From be0313393ec53394472b033c83ec8780fe4c5d2b Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Fri, 23 Nov 2007 13:37:42 +0000 Subject: QPID-689 from tross@redhat.com. This patch introduces formal schema specification for management and code generation for management classes. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@597662 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/generate.py | 229 +++++++++ qpid/cpp/managementgen/main.py | 54 +++ qpid/cpp/managementgen/schema.py | 748 +++++++++++++++++++++++++++++ qpid/cpp/managementgen/templates/Args.h | 39 ++ qpid/cpp/managementgen/templates/Class.cpp | 108 +++++ qpid/cpp/managementgen/templates/Class.h | 69 +++ 6 files changed, 1247 insertions(+) create mode 100755 qpid/cpp/managementgen/generate.py create mode 100755 qpid/cpp/managementgen/main.py create mode 100755 qpid/cpp/managementgen/schema.py create mode 100644 qpid/cpp/managementgen/templates/Args.h create mode 100644 qpid/cpp/managementgen/templates/Class.cpp create mode 100644 qpid/cpp/managementgen/templates/Class.h (limited to 'qpid/cpp/managementgen') 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) diff --git a/qpid/cpp/managementgen/main.py b/qpid/cpp/managementgen/main.py new file mode 100755 index 0000000000..2f70639482 --- /dev/null +++ b/qpid/cpp/managementgen/main.py @@ -0,0 +1,54 @@ +#!/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 schema import PackageSchema, SchemaClass +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") +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 or \ + opts.makefile == None: + parser.error ("Incorrect options, see --help for help") + +gen = Generator (opts.outdir, opts.templatedir) +schema = PackageSchema (opts.typefile, opts.schemafile) + +gen.makeClassFiles ("Class.h", schema) +gen.makeClassFiles ("Class.cpp", schema) +gen.makeMethodFiles ("Args.h", schema) +gen.makeMakeFile (opts.makefile) diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py new file mode 100755 index 0000000000..c3db4eaf53 --- /dev/null +++ b/qpid/cpp/managementgen/schema.py @@ -0,0 +1,748 @@ +#!/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 + +#===================================================================================== +# +#===================================================================================== +class SchemaType: + def __init__ (self, node): + self.name = None + self.base = None + self.cpp = None + self.encode = None + self.decode = None + self.style = "normal" + self.accessor = None + self.init = "0" + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'base': + self.base = val + + elif key == 'cpp': + self.cpp = val + + elif key == 'encode': + self.encode = val + + elif key == 'decode': + self.decode = val + + elif key == 'style': + self.style = val + + elif key == 'accessor': + self.accessor = val + + elif key == 'init': + self.init = val + + else: + raise ValueError ("Unknown attribute in type '%s'" % key) + + if self.name == None or self.base == None or self.cpp == None or \ + self.encode == None or self.decode == None: + raise ValueError ("Missing required attribute(s) in type") + + def getName (self): + return self.name + + def genAccessor (self, stream, varName, changeFlag = None): + if self.accessor == "direct": + stream.write (" inline void set_" + varName + " (" + self.cpp + " val){\n"); + stream.write (" " + varName + " = val;\n"); + if self.style == "wm": + stream.write (" if (" + varName + "Low > val)\n") + stream.write (" " + varName + "Low = val;\n"); + stream.write (" if (" + varName + "High < val)\n") + stream.write (" " + varName + "High = val;\n"); + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); + elif self.accessor == "counter": + stream.write (" inline void inc_" + varName + " (" + self.cpp + " by = 1){\n"); + stream.write (" " + varName + " += by;\n") + if self.style == "wm": + stream.write (" if (" + varName + "High < " + varName + ")\n") + stream.write (" " + varName + "High = " + varName + ";\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); + stream.write (" inline void dec_" + varName + " (" + self.cpp + " by = 1){\n"); + stream.write (" " + varName + " -= by;\n") + if self.style == "wm": + stream.write (" if (" + varName + "Low > " + varName + ")\n") + stream.write (" " + varName + "Low = " + varName + ";\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); + + def genHiLoStatResets (self, stream, varName): + if self.style == "wm": + stream.write (" " + varName + "High = " + varName + ";\n") + stream.write (" " + varName + "Low = " + varName + ";\n") + + def genWrite (self, stream, varName): + stream.write (" " + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") + if self.style == "wm": + stream.write (" " + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "High") + ";\n") + stream.write (" " + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Low") + ";\n") + + def getReadCode (self, varName, bufName): + result = self.decode.replace ("@", bufName).replace ("#", varName) + return result + + def getWriteCode (self, varName, bufName): + result = self.encode.replace ("@", bufName).replace ("#", varName) + return result + +#===================================================================================== +# +#===================================================================================== +class TypeSpec: + def __init__ (self, file): + self.types = {} + dom = parse (file) + document = dom.documentElement + if document.tagName != 'schema-types': + raise ValueError ("Expected 'schema-types' in type file") + + for child in document.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'type': + stype = SchemaType (child) + self.types[stype.getName ()] = stype + else: + raise ValueError ("Unknown type tag '%s'" % child.nodeName) + + def getType (self, name): + return self.types[name] + + +#===================================================================================== +# +#===================================================================================== +class Type: + def __init__ (self, name, typespec): + self.type = typespec.getType (name) + +#===================================================================================== +# +#===================================================================================== +class SchemaConfig: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.access = "RO" + self.isIndex = 0 + self.isParentRef = 0 + self.unit = None + self.min = None + self.max = None + self.maxLen = None + self.desc = None + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'type': + self.type = Type (val, typespec) + + elif key == 'access': + self.access = val + + elif key == 'index': + if val != 'y': + raise ValueError ("Expected 'y' in index attribute") + self.isIndex = 1 + + elif key == 'parentRef': + if val != 'y': + raise ValueError ("Expected 'y' in parentRef attribute") + self.isParentRef = 1 + + elif key == 'unit': + self.unit = val + + elif key == 'min': + self.min = val + + elif key == 'max': + self.max = val + + elif key == 'maxlen': + self.maxLen = val + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in configElement '%s'" % key) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in configElement") + if self.type == None: + raise ValueError ("Missing 'type' attribute in configElement") + + def getName (self): + return self.name + + def isConstructorArg (self): + if self.access == "RC" and self.isParentRef == 0: + return 1 + return 0 + + def genDeclaration (self, stream): + stream.write (" " + self.type.type.cpp + " " + self.name + ";\n") + + def genFormalParam (self, stream): + stream.write (self.type.type.cpp + " _" + self.name) + + def genAccessor (self, stream): + self.type.type.genAccessor (stream, self.name, "configChanged") + + def genSchema (self, stream): + stream.write (" ft = FieldTable ();\n") + stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") + stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + stream.write (" ft.setInt (ACCESS, ACCESS_" + self.access + ");\n") + stream.write (" ft.setInt (INDEX, " + str (self.isIndex) + ");\n") + if self.unit != None: + stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + if self.min != None: + stream.write (" ft.setInt (MIN, " + self.min + ");\n") + if self.max != None: + stream.write (" ft.setInt (MAX, " + self.max + ");\n") + if self.maxLen != None: + stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") + if self.desc != None: + stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + + def genWrite (self, stream): + self.type.type.genWrite (stream, self.name) + + +#===================================================================================== +# +#===================================================================================== +class SchemaInst: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.unit = None + self.desc = None + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'type': + self.type = Type (val, typespec) + + elif key == 'unit': + self.unit = val + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in instElement '%s'" % key) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in instElement") + if self.type == None: + raise ValueError ("Missing 'type' attribute in instElement") + + def getName (self): + return self.name + + def genDeclaration (self, stream): + stream.write (" " + self.type.type.cpp + " " + self.name + ";\n") + if self.type.type.style == 'wm': + stream.write (" " + self.type.type.cpp + " " + self.name + "High;\n") + stream.write (" " + self.type.type.cpp + " " + self.name + "Low;\n") + + def genAccessor (self, stream): + self.type.type.genAccessor (stream, self.name, "instChanged") + + def genHiLoStatResets (self, stream): + self.type.type.genHiLoStatResets (stream, self.name) + + def genSchemaText (self, stream, name, desc): + stream.write (" ft = FieldTable ();\n") + stream.write (" ft.setString (NAME, \"" + name + "\");\n") + stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + if self.unit != None: + stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + if desc != None: + stream.write (" ft.setString (DESC, \"" + desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + + def genSchema (self, stream): + self.genSchemaText (stream, self.name, self.desc) + if self.type.type.style == "wm": + descHigh = self.desc + descLow = self.desc + if self.desc != None: + descHigh = descHigh + " (High)" + descLow = descLow + " (Low)" + self.genSchemaText (stream, self.name + "High", descHigh) + self.genSchemaText (stream, self.name + "Low", descLow) + + def genWrite (self, stream): + self.type.type.genWrite (stream, self.name) + + def genInitialize (self, stream): + val = self.type.type.init + stream.write (" " + self.name + " = " + val + ";\n") + if self.type.type.style == "wm": + stream.write (" " + self.name + "High = " + val + ";\n") + stream.write (" " + self.name + "Low = " + val + ";\n") + + +#===================================================================================== +# +#===================================================================================== +class SchemaArg: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.unit = None + self.dir = "I" + self.min = None + self.max = None + self.maxLen = None + self.desc = None + self.default = None + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'type': + self.type = Type (val, typespec) + + elif key == 'unit': + self.unit = val + + elif key == 'dir': + self.dir = val.upper () + + elif key == 'min': + self.min = val + + elif key == 'max': + self.max = val + + elif key == 'maxlen': + self.maxLen = val + + elif key == 'desc': + self.desc = val + + elif key == 'default': + self.default = val + + else: + raise ValueError ("Unknown attribute in arg '%s'" % key) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in arg") + if self.type == None: + raise ValueError ("Missing 'type' attribute in arg") + + def getName (self): + return self.name + + def getDir (self): + return self.dir + + +#===================================================================================== +# +#===================================================================================== +class SchemaMethod: + def __init__ (self, parent, node, typespec): + self.parent = parent + self.name = None + self.desc = None + self.args = [] + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in method '%s'" % key) + + for child in node.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'arg': + arg = SchemaArg (child, typespec) + self.args.append (arg) + else: + raise ValueError ("Unknown method tag '%s'" % child.nodeName) + + def getName (self): + return self.name + + def getFullName (self): + return self.parent.getName().capitalize() + self.name[0:1].upper() +\ + self.name[1:] + + def getArgCount (self): + return len (self.args) + + #=================================================================================== + # Code Generation Functions. The names of these functions (minus the leading "gen") + # match the substitution keywords in the template files. + #=================================================================================== + def genNameUpper (self, stream): + stream.write (self.getFullName ().upper ()) + + def genNameCamel (self, stream): + stream.write (self.getFullName ()) + + def genArguments (self, stream): + for arg in self.args: + ctype = arg.type.type.cpp + dirTag = arg.dir.lower() + "_" + stream.write (" " + ctype + " " + dirTag + arg.getName () + ";\n") + +#===================================================================================== +# +#===================================================================================== +class SchemaEvent: + def __init__ (self, parent, node, typespec): + self.parent = parent + self.name = None + self.desc = None + self.args = [] + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in event '%s'" % key) + + for child in node.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'arg': + arg = SchemaArg (child, typespec) + self.args.append (arg) + else: + raise ValueError ("Unknown event tag '%s'" % child.nodeName) + + def getName (self): + return self.name + + def getFullName (self): + return self.parent.getName ().capitalize() + self.name.capitalize () + + def getArgCount (self): + return len (self.args) + +#===================================================================================== +# +#===================================================================================== +class SchemaClass: + def __init__ (self, node, typespec): + self.configElements = [] + self.instElements = [] + self.methods = [] + self.events = [] + + attrs = node.attributes + self.name = attrs['name'].nodeValue + + children = node.childNodes + for child in children: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'configElement': + sub = SchemaConfig (child, typespec) + self.configElements.append (sub) + + elif child.nodeName == 'instElement': + sub = SchemaInst (child, typespec) + self.instElements.append (sub) + + elif child.nodeName == 'method': + sub = SchemaMethod (self, child, typespec) + self.methods.append (sub) + + elif child.nodeName == 'event': + sub = SchemaEvent (self, child, typespec) + self.events.append (sub) + + else: + raise ValueError ("Unknown class tag '%s'" % child.nodeName) + + def getName (self): + return self.name + + def getMethods (self): + return self.methods + + def getEvents (self): + return self.events + + #=================================================================================== + # Code Generation Functions. The names of these functions (minus the leading "gen") + # match the substitution keywords in the template files. + #=================================================================================== + def genAccessorMethods (self, stream): + for config in self.configElements: + if config.access != "RC": + config.genAccessor (stream) + for inst in self.instElements: + inst.genAccessor (stream) + + def genArgDeclaration (self, stream): + argsFound = 0 + for method in self.methods: + argsFound = argsFound + len (method.args) + for event in self.events: + argsFound = argsFound + len (event.args) + if argsFound > 0: + stream.write ("FieldTable arg;"); + + def genConfigCount (self, stream): + stream.write ("%d" % len (self.configElements)) + + def genConfigDeclarations (self, stream): + for element in self.configElements: + element.genDeclaration (stream) + + def genConfigElementSchema (self, stream): + for config in self.configElements: + config.genSchema (stream) + + def genConstructorArgs (self, stream): + # Constructor args are config elements with read-create access + result = "" + first = 1 + for element in self.configElements: + if element.isConstructorArg (): + if first == 1: + first = 0 + else: + stream.write (", ") + element.genFormalParam (stream) + + def genConstructorInits (self, stream): + for element in self.configElements: + if element.isConstructorArg (): + stream.write ("," + element.getName () + "(_" + element.getName () + ")") + + def genDoMethodArgs (self, stream): + methodCount = 0 + inArgCount = 0 + for method in self.methods: + methodCount = methodCount + 1 + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + inArgCount = inArgCount + 1 + + if methodCount == 0: + stream.write ("string, Buffer&, Buffer& outBuf") + else: + if inArgCount == 0: + stream.write ("string methodName, Buffer&, Buffer& outBuf") + else: + stream.write ("string methodName, Buffer& inBuf, Buffer& outBuf") + + def genEventCount (self, stream): + stream.write ("%d" % len (self.events)) + + def genEventSchema (self, stream): + pass ########################################################################### + + def genHiLoStatResets (self, stream): + for inst in self.instElements: + inst.genHiLoStatResets (stream) + + def genInitializeElements (self, stream): + for inst in self.instElements: + inst.genInitialize (stream) + + def genInstChangedStub (self, stream): + 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): + count = 0 + for inst in self.instElements: + count = count + 1 + if inst.type.type.style == "wm": + count = count + 2 + stream.write ("%d" % count) + + def genInstDeclarations (self, stream): + for element in self.instElements: + element.genDeclaration (stream) + + def genInstElementSchema (self, stream): + for inst in self.instElements: + inst.genSchema (stream) + + def genMethodArgIncludes (self, stream): + for method in self.methods: + if method.getArgCount () > 0: + stream.write ("#include \"qpid/management/Args" +\ + method.getFullName () + ".h\"\n") + + def genMethodCount (self, stream): + stream.write ("%d" % len (self.methods)) + + def genMethodHandlers (self, stream): + for method in self.methods: + stream.write ("\n if (methodName == \"" + method.getName () + "\")\n {\n") + if method.getArgCount () == 0: + stream.write (" ArgsNone ioArgs;\n") + else: + stream.write (" Args" + method.getFullName () + " ioArgs;\n") + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + stream.write (" " +\ + arg.type.type.getReadCode ("ioArgs." +\ + arg.dir.lower () + "_" +\ + arg.name, "inBuf") + ";\n") + + stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ + method.getName().upper() + ", ioArgs);\n") + stream.write (" outBuf.putLong (status);\n") + stream.write (" outBuf.putShortString (Manageable::StatusText (status));\n") + for arg in method.args: + if arg.getDir () == "O" or arg.getDir () == "IO": + stream.write (" " +\ + arg.type.type.getWriteCode ("ioArgs." +\ + arg.dir.lower () + "_" +\ + arg.name, "outBuf") + ";\n") + stream.write (" return;\n }\n") + + + def genMethodIdDeclarations (self, stream): + 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): + pass ########################################################################### + + def genNameCap (self, stream): + stream.write (self.name.capitalize ()) + + def genNameLower (self, stream): + stream.write (self.name.lower ()) + + def genNameUpper (self, stream): + stream.write (self.name.upper ()) + + def genParentArg (self, stream): + for config in self.configElements: + if config.isParentRef == 1: + stream.write (" _parent") + return + + def genParentRefAssignment (self, stream): + for config in self.configElements: + if config.isParentRef == 1: + stream.write (config.getName () + \ + " = _parent->GetManagementObject ()->getObjectId ();") + return + + def genWriteConfig (self, stream): + for config in self.configElements: + config.genWrite (stream); + + def genWriteInst (self, stream): + for inst in self.instElements: + inst.genWrite (stream); + + +#===================================================================================== +# +#===================================================================================== +class PackageSchema: + def __init__ (self, typefile, schemafile): + + self.classes = [] + self.typespec = TypeSpec (typefile) + + dom = parse (schemafile) + document = dom.documentElement + if document.tagName != 'schema': + raise ValueError ("Expected 'schema' node") + attrs = document.attributes + self.packageName = attrs['package'].nodeValue + + children = document.childNodes + for child in children: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'class': + cls = SchemaClass (child, self.typespec) + self.classes.append (cls) + else: + raise ValueError ("Unknown schema tag '%s'" % child.nodeName) + + def getPackageName (self): + return self.packageName + + def getClasses (self): + return self.classes diff --git a/qpid/cpp/managementgen/templates/Args.h b/qpid/cpp/managementgen/templates/Args.h new file mode 100644 index 0000000000..4a6413ddc9 --- /dev/null +++ b/qpid/cpp/managementgen/templates/Args.h @@ -0,0 +1,39 @@ +#ifndef _ARGS_/*MGEN:Method.NameUpper*/_ +#define _ARGS_/*MGEN:Method.NameUpper*/_ + +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/Args.h" +#include + +namespace qpid { +namespace management { + +class Args/*MGEN:Method.NameCamel*/ : public Args +{ + public: +/*MGEN:Method.Arguments*/ +}; + +}} + +#endif /*!_ARGS_/*MGEN:Method.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp new file mode 100644 index 0000000000..70077d495c --- /dev/null +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -0,0 +1,108 @@ +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/log/Statement.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/management/Manageable.h" +#include "/*MGEN:Class.NameCap*/.h" +/*MGEN:Class.MethodArgIncludes*/ + +using namespace qpid::management; +using namespace qpid::sys; +using namespace qpid::framing; +using std::string; + +bool /*MGEN:Class.NameCap*/::schemaNeeded = true; + +/*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (Manageable* _core, Manageable*/*MGEN:Class.ParentArg*/, + /*MGEN:Class.ConstructorArgs*/) : + ManagementObject(_core, "/*MGEN:Class.NameLower*/") + /*MGEN:Class.ConstructorInits*/ +{ + /*MGEN:Class.ParentRefAssignment*/ +/*MGEN:Class.InitializeElements*/ +} + +/*MGEN:Class.NameCap*/::~/*MGEN:Class.NameCap*/ () {} + +namespace { + const string NAME("name"); + const string TYPE("type"); + const string ACCESS("access"); + const string INDEX("index"); + const string UNIT("unit"); + const string MIN("min"); + const string MAX("max"); + const string MAXLEN("maxlen"); + const string DESC("desc"); +} + +void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) +{ + FieldTable ft; + /*MGEN:Class.ArgDeclaration*/ + + schemaNeeded = false; + + // Schema class header: + buf.putShortString (className); // Class Name + buf.putShort (/*MGEN:Class.ConfigCount*/); // Config Element Count + buf.putShort (/*MGEN:Class.InstCount*/); // Inst Element Count + buf.putShort (/*MGEN:Class.MethodCount*/); // Method Count + buf.putShort (/*MGEN:Class.EventCount*/); // Event Count + + // Config Elements +/*MGEN:Class.ConfigElementSchema*/ + // Inst Elements +/*MGEN:Class.InstElementSchema*/ + // Methods +/*MGEN:Class.MethodSchema*/ + // Events +/*MGEN:Class.EventSchema*/ +} + +void /*MGEN:Class.NameCap*/::writeConfig (Buffer& buf) +{ + configChanged = false; + + writeTimestamps (buf); +/*MGEN:Class.WriteConfig*/ +} + +void /*MGEN:Class.NameCap*/::writeInstrumentation (Buffer& buf) +{ + instChanged = false; + + writeTimestamps (buf); +/*MGEN:Class.WriteInst*/ + + // Maintenance of hi-lo statistics +/*MGEN:Class.HiLoStatResets*/ +} + +void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) +{ + Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; +/*MGEN:Class.MethodHandlers*/ + outBuf.putLong (status); + outBuf.putShortString (Manageable::StatusText (status)); +} + diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h new file mode 100644 index 0000000000..cff915412e --- /dev/null +++ b/qpid/cpp/managementgen/templates/Class.h @@ -0,0 +1,69 @@ +#ifndef _MANAGEMENT_/*MGEN:Class.NameUpper*/_ +#define _MANAGEMENT_/*MGEN:Class.NameUpper*/_ + +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/ManagementObject.h" + +namespace qpid { +namespace management { + +class /*MGEN:Class.NameCap*/ : public ManagementObject +{ + private: + + static bool schemaNeeded; + + // Configuration Elements +/*MGEN:Class.ConfigDeclarations*/ + // Instrumentation Elements +/*MGEN:Class.InstDeclarations*/ + // Private Methods + std::string getObjectName (void) { return "/*MGEN:Class.NameLower*/"; } + void writeSchema (qpid::framing::Buffer& buf); + void writeConfig (qpid::framing::Buffer& buf); + void writeInstrumentation (qpid::framing::Buffer& buf); + bool getSchemaNeeded (void) { return schemaNeeded; } + void setSchemaNeeded (void) { schemaNeeded = true; } + void doMethod (std::string methodName, + qpid::framing::Buffer& inBuf, + qpid::framing::Buffer& outBuf); + +/*MGEN:Class.InstChangedStub*/ + public: + + typedef boost::shared_ptr shared_ptr; + + /*MGEN:Class.NameCap*/ (Manageable* coreObject, Manageable* parentObject, + /*MGEN:Class.ConstructorArgs*/); + ~/*MGEN:Class.NameCap*/ (void); + + // Method IDs +/*MGEN:Class.MethodIdDeclarations*/ + // Accessor Methods +/*MGEN:Class.AccessorMethods*/ +}; + +}} + + +#endif /*!_MANAGEMENT_/*MGEN:Class.NameUpper*/_*/ -- cgit v1.2.1 From 0b36aad4e16cc121253c4149f56846af7ee23ea3 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Thu, 6 Dec 2007 18:37:18 +0000 Subject: From Ted Ross Queue statistics fixed. Additional objects added (exchange, binding). Changes: M cpp/src/qpid/broker/ExchangeRegistry.h M cpp/src/qpid/broker/ExchangeRegistry.cpp ExchangeRegistry was modified to pass a parent pointer to created exchanges. This parent reference is not stored but is used to link management objects in a hierarchy of ownership. M cpp/src/qpid/broker/Exchange.h M cpp/src/qpid/broker/Exchange.cpp Exchange now inherits Manageable to make it visible via the management interface. The Exchange parent class handles most of the management boilerplate. A Binding struct was introduced to track bindings for management. This is separate from QueueBindings which track bindings for queues. M cpp/src/qpid/broker/HeadersExchange.h M cpp/src/qpid/broker/FanOutExchange.h M cpp/src/qpid/broker/DirectExchange.h M cpp/src/qpid/broker/TopicExchange.h M cpp/src/qpid/broker/HeadersExchange.cpp M cpp/src/qpid/broker/FanOutExchange.cpp M cpp/src/qpid/broker/DirectExchange.cpp M cpp/src/qpid/broker/TopicExchange.cpp M cpp/src/qpid/management/ManagementExchange.cpp M cpp/src/qpid/management/ManagementExchange.h Each exchange type handles management stats in its own specific way. Additionally, the constructors pass the management parent pointer to the constructor or Exchange. An extra layer was added to contain bindings. Instead of directly storing bound queues, the exchanges store "bindings" which are managable constructs. M cpp/src/qpid/broker/Broker.cpp Broker now explicitly enables the management agent. Also sets the management parent (vhost) in the exchange registry. M cpp/src/qpid/broker/Vhost.cpp Updated constructor to be more defensive in case the management agent has not been enabled. M cpp/src/qpid/broker/Queue.cpp Same constructor update as vhost. Moved accounting of dequeues into "pop". Implemented management method handler (purge). M cpp/src/qpid/broker/Deliverable.h A new method was added to extract the content size of the deliverable content (if appropriate). The method is not pure virtual and returns zero if not overridden. M cpp/src/qpid/broker/DeliverableMessage.h M cpp/src/qpid/broker/TxPublish.cpp M cpp/src/qpid/broker/DeliverableMessage.cpp M cpp/src/qpid/broker/TxPublish.h These derivatives of Deliverable were updated with overrides for contenSize. M cpp/src/qpid/management/ManagementAgent.h M cpp/src/qpid/management/ManagementAgent.cpp An "enable" method was added to prevent inadvertent creation of a management agent when not desired. Adding and deleting management objects is now protected by a mutex. Make sure that deleted objects get reported even if neither their configuration nor instrumentation is changed. M specs/management-schema.xml Minor cosmetic updates. Additional parent linkage. M cpp/managementgen/schema.py M cpp/managementgen/templates/Class.cpp Added generated code to publish schema details for methods. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@601807 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/schema.py | 40 ++++++++++++++++++++++-------- qpid/cpp/managementgen/templates/Class.cpp | 5 +++- 2 files changed, 34 insertions(+), 11 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index c3db4eaf53..34121a2544 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -397,6 +397,24 @@ class SchemaArg: def getDir (self): return self.dir + def genSchema (self, stream): + stream.write (" ft = FieldTable ();\n") + stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") + stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + stream.write (" ft.setString (DIR, \"" + self.dir + "\");\n") + if self.unit != None: + stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + if self.min != None: + stream.write (" ft.setInt (MIN, " + self.min + ");\n") + if self.max != None: + stream.write (" ft.setInt (MAX, " + self.max + ");\n") + if self.maxLen != None: + stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") + if self.desc != None: + stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") + if self.default != None: + stream.write (" ft.setString (DEFAULT, \"" + self.default + "\");\n") + stream.write (" buf.put (ft);\n\n") #===================================================================================== # @@ -455,6 +473,16 @@ class SchemaMethod: dirTag = arg.dir.lower() + "_" stream.write (" " + ctype + " " + dirTag + arg.getName () + ";\n") + def genSchema (self, stream): + stream.write (" ft = FieldTable ();\n") + stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") + stream.write (" ft.setInt (ARGCOUNT, " + str (len (self.args)) + ");\n") + if self.desc != None: + stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + for arg in self.args: + arg.genSchema (stream) + #===================================================================================== # #===================================================================================== @@ -550,15 +578,6 @@ class SchemaClass: for inst in self.instElements: inst.genAccessor (stream) - def genArgDeclaration (self, stream): - argsFound = 0 - for method in self.methods: - argsFound = argsFound + len (method.args) - for event in self.events: - argsFound = argsFound + len (event.args) - if argsFound > 0: - stream.write ("FieldTable arg;"); - def genConfigCount (self, stream): stream.write ("%d" % len (self.configElements)) @@ -683,7 +702,8 @@ class SchemaClass: number = number + 1 def genMethodSchema (self, stream): - pass ########################################################################### + for method in self.methods: + method.genSchema (stream) def genNameCap (self, stream): stream.write (self.name.capitalize ()) diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp index 70077d495c..d3b95fd674 100644 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -53,12 +53,15 @@ namespace { const string MAX("max"); const string MAXLEN("maxlen"); const string DESC("desc"); + const string ARGCOUNT("argCount"); + const string ARGS("args"); + const string DIR("dir"); + const string DEFAULT("default"); } void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) { FieldTable ft; - /*MGEN:Class.ArgDeclaration*/ schemaNeeded = false; -- cgit v1.2.1 From 340eccfc41a61b5cea01184f0da40b2f78c20a3f Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Mon, 10 Dec 2007 20:22:23 +0000 Subject: Patches from Ted Ross QPID-697 Fixed access-rights constants for management schema. Added mutex to fix problems associated with concurrent invocation of accessors for queue statistics. Removed queue schema content that is not relevant to QPID. QPID-698 This patch creates a new subdirectory in python called "mgmt-cli". python/mgmt-cli/main.py can be executed from the shell. If no arguments are supplied, it attempts to connect to the broker at localhost:5672. The first argument is the hostname for the target broker and the second (optional) argument is the TCP port (defaults to 5672). It is assumed that the AMQP spec file is in the following location: /usr/share/amqp/amqp.0-10-preview.xml It is also required that the qpid/python directory be in the PYTHONPATH environment variable. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@603034 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/templates/Class.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h index cff915412e..6a54b2131c 100644 --- a/qpid/cpp/managementgen/templates/Class.h +++ b/qpid/cpp/managementgen/templates/Class.h @@ -22,6 +22,7 @@ /*MGEN:Root.Disclaimer*/ +#include "qpid/sys/Mutex.h" #include "qpid/management/ManagementObject.h" namespace qpid { @@ -52,6 +53,7 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject public: typedef boost::shared_ptr shared_ptr; + qpid::sys::Mutex accessorLock; /*MGEN:Class.NameCap*/ (Manageable* coreObject, Manageable* parentObject, /*MGEN:Class.ConstructorArgs*/); -- cgit v1.2.1 From e336559c82f22ecd0a013b8ea787bb4946ab2fdc Mon Sep 17 00:00:00 2001 From: "Carl C. Trieloff" Date: Wed, 2 Jan 2008 15:56:20 +0000 Subject: patch-715 (tross) git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@608135 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/main.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/main.py b/qpid/cpp/managementgen/main.py index 2f70639482..ddf18ef873 100755 --- a/qpid/cpp/managementgen/main.py +++ b/qpid/cpp/managementgen/main.py @@ -41,8 +41,7 @@ parser.add_option ("-m", "--makefile", dest="makefile", metavar="FILE", if opts.outdir == None or \ opts.typefile == None or \ opts.schemafile == None or \ - opts.templatedir == None or \ - opts.makefile == None: + opts.templatedir == None: parser.error ("Incorrect options, see --help for help") gen = Generator (opts.outdir, opts.templatedir) @@ -51,4 +50,6 @@ schema = PackageSchema (opts.typefile, opts.schemafile) gen.makeClassFiles ("Class.h", schema) gen.makeClassFiles ("Class.cpp", schema) gen.makeMethodFiles ("Args.h", schema) -gen.makeMakeFile (opts.makefile) + +if opts.makefile != None: + gen.makeMakeFile (opts.makefile) -- cgit v1.2.1 From 168f40831104bc954cadba17d08544c08c858b77 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Mon, 7 Jan 2008 16:28:07 +0000 Subject: Patch from https://issues.apache.org/jira/browse/QPID-722 by Ted Ross: Two changes in this patch: 1) Management object IDs are now persistent for persistent (durable) objects. This is required to provide continuity of historical management data across broker restarts. The format of object IDs now indicates whether they are transient or persistent. The upper bit (bit 63) is 0 for transient IDs and 1 for persistent IDs. 2) Changes have been made to the management code generator in preparation for allowing it to be used by outside projects that wish to use the broker Plugin API for management access. File-by-file notes: M python/mgmt-cli/managementdata.py Enhanced user-friendly display of 64-bit object IDs to differentiate between persistent IDs and non-persistent IDs. M cpp/src/Makefile.am Changed command line format for call to the management code generator. M cpp/src/qpid/broker/Broker.cpp M cpp/src/qpid/broker/Vhost.cpp M cpp/src/qpid/broker/Queue.cpp Updated calls to ManagementAgent::addObject to use the new support for persistent IDs, ensuring that the management object IDs for persistent objects are themselves persistent. M cpp/src/qpid/management/ManagementAgent.h M cpp/src/qpid/management/ManagementAgent.cpp Added support (using defaulted arguments) to ManagementAgent::addObject for persistent object IDs M cpp/managementgen/generate.py M cpp/managementgen/schema.py M cpp/managementgen/main.py Added the ability for templates to set variables to be used during code generation. Makefile fragment is now generated using a template rather than hard-code. This was done to help non-qpid code to use the code generator for management-via-qpid support. M cpp/managementgen/templates/Args.h M cpp/managementgen/templates/Class.cpp M cpp/managementgen/templates/Class.h Use a generator variable to define the comment prefix. A cpp/managementgen/templates/Makefile.mk New template for the qpid makefile fragment. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@609672 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/generate.py | 164 +++++++++++++++++------------ qpid/cpp/managementgen/main.py | 29 +++-- qpid/cpp/managementgen/schema.py | 64 +++++------ qpid/cpp/managementgen/templates/Args.h | 1 + qpid/cpp/managementgen/templates/Class.cpp | 1 + qpid/cpp/managementgen/templates/Class.h | 1 + 6 files changed, 141 insertions(+), 119 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/generate.py b/qpid/cpp/managementgen/generate.py index 1d0987e685..4c042bd3f6 100755 --- a/qpid/cpp/managementgen/generate.py +++ b/qpid/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/qpid/cpp/managementgen/main.py b/qpid/cpp/managementgen/main.py index ddf18ef873..de8ce4cbe6 100755 --- a/qpid/cpp/managementgen/main.py +++ b/qpid/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/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index 34121a2544..ef3fb50667 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/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/qpid/cpp/managementgen/templates/Args.h b/qpid/cpp/managementgen/templates/Args.h index 4a6413ddc9..576d891a3f 100644 --- a/qpid/cpp/managementgen/templates/Args.h +++ b/qpid/cpp/managementgen/templates/Args.h @@ -1,3 +1,4 @@ +/*MGEN:commentPrefix=//*/ #ifndef _ARGS_/*MGEN:Method.NameUpper*/_ #define _ARGS_/*MGEN:Method.NameUpper*/_ diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp index d3b95fd674..d87d11f767 100644 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ b/qpid/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/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h index 6a54b2131c..ba6a1183e2 100644 --- a/qpid/cpp/managementgen/templates/Class.h +++ b/qpid/cpp/managementgen/templates/Class.h @@ -1,3 +1,4 @@ +/*MGEN:commentPrefix=//*/ #ifndef _MANAGEMENT_/*MGEN:Class.NameUpper*/_ #define _MANAGEMENT_/*MGEN:Class.NameUpper*/_ -- cgit v1.2.1 From 131653662625e18df0bec6247a19537a6e238ca6 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Mon, 7 Jan 2008 16:35:18 +0000 Subject: Omitted in previous commit. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@609680 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/templates/Makefile.mk | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 qpid/cpp/managementgen/templates/Makefile.mk (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/templates/Makefile.mk b/qpid/cpp/managementgen/templates/Makefile.mk new file mode 100644 index 0000000000..0e6454c13a --- /dev/null +++ b/qpid/cpp/managementgen/templates/Makefile.mk @@ -0,0 +1,37 @@ +# +# 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. +# +/*MGEN:commentPrefix=#*/ +/*MGEN:mgenDir=$(mgen_dir)*/ +/*MGEN:specDir=$(top_srcdir)/../specs*/ +/*MGEN:Root.Disclaimer*/ + +mgen_generator=/*MGEN:Makefile.GenSources*/ + +mgen_broker_cpp=/*MGEN:Makefile.GenCppFiles*/ + +# Header file install rules. +qpid_managementdir = $(includedir)/qpid/management +dist_qpid_management_HEADERS = /*MGEN:Makefile.GenHFiles*/ + +if GENERATE +$(srcdir)/managementgen.mk: $(mgen_generator) + $(mgen_cmd) + +$(mgen_generator): +endif -- cgit v1.2.1 From d8de946fe4b62a6e398d58184a7572662565de7f Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Fri, 11 Jan 2008 15:45:57 +0000 Subject: A new management data type (and the code-generation support for it) have been added that allows min/max/average statistics to be tracked. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@611209 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/schema.py | 68 +++++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 7 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index ef3fb50667..a459db7a47 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -77,12 +77,20 @@ class SchemaType: def genAccessor (self, stream, varName, changeFlag = None): if self.accessor == "direct": stream.write (" inline void set_" + varName + " (" + self.cpp + " val){\n"); - stream.write (" " + varName + " = val;\n"); + if self.style != "mma": + stream.write (" " + varName + " = val;\n"); if self.style == "wm": stream.write (" if (" + varName + "Low > val)\n") - stream.write (" " + varName + "Low = val;\n"); + stream.write (" " + varName + "Low = val;\n") stream.write (" if (" + varName + "High < val)\n") - stream.write (" " + varName + "High = val;\n"); + stream.write (" " + varName + "High = val;\n") + if self.style == "mma": + stream.write (" " + varName + "Count++;\n") + stream.write (" " + varName + "Total += val;\n") + stream.write (" if (" + varName + "Min > val)\n") + stream.write (" " + varName + "Min = val;\n") + stream.write (" if (" + varName + "Max < val)\n") + stream.write (" " + varName + "Max = val;\n") if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n"); @@ -108,14 +116,31 @@ class SchemaType: if self.style == "wm": stream.write (" " + varName + "High = " + varName + ";\n") stream.write (" " + varName + "Low = " + varName + ";\n") + if self.style == "mma": + stream.write (" " + varName + "Count = 0;\n") + stream.write (" " + varName + "Total = 0;\n") + stream.write (" " + varName + "Min = -1;\n") + stream.write (" " + varName + "Max = 0;\n") def genWrite (self, stream, varName): - stream.write (" " + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") + if self.style != "mma": + stream.write (" " + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") if self.style == "wm": stream.write (" " + self.encode.replace ("@", "buf") \ .replace ("#", varName + "High") + ";\n") stream.write (" " + self.encode.replace ("@", "buf") \ .replace ("#", varName + "Low") + ";\n") + if self.style == "mma": + stream.write (" " + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Count") + ";\n") + stream.write (" " + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Count ? " + varName + "Min : 0") + ";\n") + stream.write (" " + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Max") + ";\n") + stream.write (" " + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Count ? " + varName + "Total / " + + varName + "Count : 0") + ";\n") + def getReadCode (self, varName, bufName): result = self.decode.replace ("@", bufName).replace ("#", varName) @@ -294,10 +319,16 @@ class SchemaInst: return self.name def genDeclaration (self, stream): - stream.write (" " + self.type.type.cpp + " " + self.name + ";\n") + if self.type.type.style != "mma": + stream.write (" " + self.type.type.cpp + " " + self.name + ";\n") if self.type.type.style == 'wm': stream.write (" " + self.type.type.cpp + " " + self.name + "High;\n") stream.write (" " + self.type.type.cpp + " " + self.name + "Low;\n") + if self.type.type.style == "mma": + stream.write (" " + self.type.type.cpp + " " + self.name + "Count;\n") + stream.write (" uint64_t " + self.name + "Total;\n") + stream.write (" " + self.type.type.cpp + " " + self.name + "Min;\n") + stream.write (" " + self.type.type.cpp + " " + self.name + "Max;\n") def genAccessor (self, stream): self.type.type.genAccessor (stream, self.name, "instChanged") @@ -316,7 +347,8 @@ class SchemaInst: stream.write (" buf.put (ft);\n\n") def genSchema (self, stream): - self.genSchemaText (stream, self.name, self.desc) + if self.type.type.style != "mma": + self.genSchemaText (stream, self.name, self.desc) if self.type.type.style == "wm": descHigh = self.desc descLow = self.desc @@ -325,16 +357,36 @@ class SchemaInst: descLow = descLow + " (Low)" self.genSchemaText (stream, self.name + "High", descHigh) self.genSchemaText (stream, self.name + "Low", descLow) + if self.type.type.style == "mma": + descCount = self.desc + descMin = self.desc + descMax = self.desc + descAverage = self.desc + if self.desc != None: + descCount = descCount + " (Samples)" + descMin = descMin + " (Min)" + descMax = descMax + " (Max)" + descAverage = descAverage + " (Average)" + self.genSchemaText (stream, self.name + "Samples", descCount) + self.genSchemaText (stream, self.name + "Min", descMin) + self.genSchemaText (stream, self.name + "Max", descMax) + self.genSchemaText (stream, self.name + "Average", descAverage) def genWrite (self, stream): self.type.type.genWrite (stream, self.name) def genInitialize (self, stream): val = self.type.type.init - stream.write (" " + self.name + " = " + val + ";\n") + if self.type.type.style != "mma": + stream.write (" " + self.name + " = " + val + ";\n") if self.type.type.style == "wm": stream.write (" " + self.name + "High = " + val + ";\n") stream.write (" " + self.name + "Low = " + val + ";\n") + if self.type.type.style == "mma": + stream.write (" " + self.name + "Count = 0;\n") + stream.write (" " + self.name + "Min = -1;\n") + stream.write (" " + self.name + "Max = 0;\n") + stream.write (" " + self.name + "Total = 0;\n") #===================================================================================== @@ -648,6 +700,8 @@ class SchemaClass: count = count + 1 if inst.type.type.style == "wm": count = count + 2 + if inst.type.type.style == "mma": + count = count + 3 stream.write ("%d" % count) def genInstDeclarations (self, stream, variables): -- cgit v1.2.1 From 89bf8bee0cb748de137f1826a3d96a78414dd1f0 Mon Sep 17 00:00:00 2001 From: "Carl C. Trieloff" Date: Thu, 28 Feb 2008 18:55:21 +0000 Subject: QPID-820 from tross git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@632087 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/main.py | 8 ++- qpid/cpp/managementgen/schema.py | 85 +++++++++++++++++++++++------- qpid/cpp/managementgen/templates/Class.cpp | 31 ++++++++--- qpid/cpp/managementgen/templates/Class.h | 19 ++++--- 4 files changed, 108 insertions(+), 35 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/main.py b/qpid/cpp/managementgen/main.py index de8ce4cbe6..677c7321ae 100755 --- a/qpid/cpp/managementgen/main.py +++ b/qpid/cpp/managementgen/main.py @@ -28,6 +28,9 @@ usage = "usage: %prog [options] schema-document type-document template-director parser = OptionParser (usage=usage) parser.add_option ("-m", "--makefile", dest="makefile", metavar="FILE", help="Makefile fragment") +parser.add_option ("-i", "--include-prefix", dest="include_prefix", metavar="PATH", + default="qpid/management/", + help="Prefix for #include of generated headers in generated source, default: qpid/management/") (opts, args) = parser.parse_args () @@ -39,8 +42,11 @@ typefile = args[1] templatedir = args[2] outdir = args[3] +if opts.include_prefix == ".": + opts.include_prefix = None + gen = Generator (outdir, templatedir) -schema = PackageSchema (typefile, schemafile) +schema = PackageSchema (typefile, schemafile, opts) gen.makeClassFiles ("Class.h", schema) gen.makeClassFiles ("Class.cpp", schema) diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index a459db7a47..fd76ba9112 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -21,6 +21,7 @@ from xml.dom.minidom import parse, parseString, Node from cStringIO import StringIO +import md5 #===================================================================================== # @@ -575,15 +576,18 @@ class SchemaEvent: def getArgCount (self): return len (self.args) -#===================================================================================== -# -#===================================================================================== + class SchemaClass: - def __init__ (self, node, typespec): + def __init__ (self, package, node, typespec, fragments, options): + self.packageName = package self.configElements = [] self.instElements = [] self.methods = [] self.events = [] + self.options = options + self.md5Sum = md5.new () + + self.hash (node) attrs = node.attributes self.name = attrs['name'].nodeValue @@ -607,9 +611,40 @@ class SchemaClass: sub = SchemaEvent (self, child, typespec) self.events.append (sub) + elif child.nodeName == 'group': + self.expandFragment (child, fragments) + else: raise ValueError ("Unknown class tag '%s'" % child.nodeName) + def hash (self, node): + attrs = node.attributes + self.md5Sum.update (node.nodeName) + + for idx in range (attrs.length): + self.md5Sum.update (attrs.item(idx).nodeName) + self.md5Sum.update (attrs.item(idx).nodeValue) + + for child in node.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self.hash (child) + + def expandFragment (self, node, fragments): + attrs = node.attributes + name = attrs['name'].nodeValue + for fragment in fragments: + if fragment.name == name: + for config in fragment.configElements: + self.configElements.append (config) + for inst in fragment.instElements: + self.instElements.append (inst) + for method in fragment.methods: + self.methods.append (method) + for event in fragment.events: + self.events.append (event) + return + raise ValueError ("Undefined group '%s'" % name) + def getName (self): return self.name @@ -644,13 +679,9 @@ class SchemaClass: def genConstructorArgs (self, stream, variables): # Constructor args are config elements with read-create access result = "" - first = 1 for element in self.configElements: if element.isConstructorArg (): - if first == 1: - first = 0 - else: - stream.write (", ") + stream.write (", ") element.genFormalParam (stream) def genConstructorInits (self, stream, variables): @@ -715,8 +746,8 @@ class SchemaClass: def genMethodArgIncludes (self, stream, variables): for method in self.methods: if method.getArgCount () > 0: - stream.write ("#include \"qpid/management/Args" +\ - method.getFullName () + ".h\"\n") + stream.write ("#include \"" + (self.options.include_prefix or "") +\ + "Args" + method.getFullName () + ".h\"\n") def genMethodCount (self, stream, variables): stream.write ("%d" % len (self.methods)) @@ -765,13 +796,16 @@ class SchemaClass: def genNameLower (self, stream, variables): stream.write (self.name.lower ()) + def genNamePackageLower (self, stream, variables): + stream.write (self.packageName.lower ()) + def genNameUpper (self, stream, variables): stream.write (self.name.upper ()) def genParentArg (self, stream, variables): for config in self.configElements: if config.isParentRef == 1: - stream.write (" _parent") + stream.write (", Manageable* _parent") return def genParentRefAssignment (self, stream, variables): @@ -781,6 +815,13 @@ class SchemaClass: " = _parent->GetManagementObject ()->getObjectId ();") return + def genSchemaMD5 (self, stream, variables): + sum = self.md5Sum.digest () + for idx in range (len (sum)): + if idx != 0: + stream.write (",") + stream.write (hex (ord (sum[idx]))) + def genWriteConfig (self, stream, variables): for config in self.configElements: config.genWrite (stream); @@ -790,14 +831,13 @@ class SchemaClass: inst.genWrite (stream); -#===================================================================================== -# -#===================================================================================== + class PackageSchema: - def __init__ (self, typefile, schemafile): + def __init__ (self, typefile, schemafile, options): - self.classes = [] - self.typespec = TypeSpec (typefile) + self.classes = [] + self.fragments = [] + self.typespec = TypeSpec (typefile) dom = parse (schemafile) document = dom.documentElement @@ -810,8 +850,15 @@ class PackageSchema: for child in children: if child.nodeType == Node.ELEMENT_NODE: if child.nodeName == 'class': - cls = SchemaClass (child, self.typespec) + cls = SchemaClass (self.packageName, child, self.typespec, + self.fragments, options) self.classes.append (cls) + + elif child.nodeName == 'group': + cls = SchemaClass (self.packageName, child, self.typespec, + self.fragments, options) + self.fragments.append (cls) + else: raise ValueError ("Unknown schema tag '%s'" % child.nodeName) diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp index d87d11f767..2a3f71e262 100644 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -31,11 +31,14 @@ using namespace qpid::sys; using namespace qpid::framing; using std::string; -bool /*MGEN:Class.NameCap*/::schemaNeeded = true; - -/*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (Manageable* _core, Manageable*/*MGEN:Class.ParentArg*/, - /*MGEN:Class.ConstructorArgs*/) : - ManagementObject(_core, "/*MGEN:Class.NameLower*/") +string /*MGEN:Class.NameCap*/::packageName = string ("/*MGEN:Class.NamePackageLower*/"); +string /*MGEN:Class.NameCap*/::className = string ("/*MGEN:Class.NameLower*/"); +uint8_t /*MGEN:Class.NameCap*/::md5Sum[16] = + {/*MGEN:Class.SchemaMD5*/}; +bool /*MGEN:Class.NameCap*/::firstInst = true; + +/*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (Manageable* _core/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/) : + ManagementObject(_core) /*MGEN:Class.ConstructorInits*/ { /*MGEN:Class.ParentRefAssignment*/ @@ -60,14 +63,26 @@ namespace { const string DEFAULT("default"); } +bool /*MGEN:Class.NameCap*/::firstInstance (void) +{ + Mutex::ScopedLock alock(accessorLock); + if (firstInst) + { + firstInst = false; + return true; + } + + return false; +} + void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) { FieldTable ft; - schemaNeeded = false; - // Schema class header: - buf.putShortString (className); // Class Name + buf.putShortString (packageName); // Package Name + buf.putShortString (className); // Class Name + buf.putBin128 (md5Sum); // Schema Hash buf.putShort (/*MGEN:Class.ConfigCount*/); // Config Element Count buf.putShort (/*MGEN:Class.InstCount*/); // Inst Element Count buf.putShort (/*MGEN:Class.MethodCount*/); // Method Count diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h index ba6a1183e2..82fac00d47 100644 --- a/qpid/cpp/managementgen/templates/Class.h +++ b/qpid/cpp/managementgen/templates/Class.h @@ -33,22 +33,24 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject { private: - static bool schemaNeeded; + static std::string packageName; + static std::string className; + static uint8_t md5Sum[16]; + static bool firstInst; // Configuration Elements /*MGEN:Class.ConfigDeclarations*/ // Instrumentation Elements /*MGEN:Class.InstDeclarations*/ // Private Methods - std::string getObjectName (void) { return "/*MGEN:Class.NameLower*/"; } - void writeSchema (qpid::framing::Buffer& buf); + static void writeSchema (qpid::framing::Buffer& buf); void writeConfig (qpid::framing::Buffer& buf); void writeInstrumentation (qpid::framing::Buffer& buf); - bool getSchemaNeeded (void) { return schemaNeeded; } - void setSchemaNeeded (void) { schemaNeeded = true; } void doMethod (std::string methodName, qpid::framing::Buffer& inBuf, qpid::framing::Buffer& outBuf); + writeSchemaCall_t getWriteSchemaCall (void) { return writeSchema; } + bool firstInstance (void); /*MGEN:Class.InstChangedStub*/ public: @@ -56,10 +58,13 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject typedef boost::shared_ptr shared_ptr; qpid::sys::Mutex accessorLock; - /*MGEN:Class.NameCap*/ (Manageable* coreObject, Manageable* parentObject, - /*MGEN:Class.ConstructorArgs*/); + /*MGEN:Class.NameCap*/ (Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); ~/*MGEN:Class.NameCap*/ (void); + std::string getPackageName (void) { return packageName; } + std::string getClassName (void) { return className; } + uint8_t* getMd5Sum (void) { return md5Sum; } + // Method IDs /*MGEN:Class.MethodIdDeclarations*/ // Accessor Methods -- cgit v1.2.1 From 1b2e86e1f3835be232044b82e87c16e1bd5190be Mon Sep 17 00:00:00 2001 From: Nuno Santos Date: Tue, 25 Mar 2008 20:30:01 +0000 Subject: QPID-877: applied patch from Ted Ross git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@640970 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/templates/Class.cpp | 5 +++-- qpid/cpp/managementgen/templates/Class.h | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp index 2a3f71e262..3c3dfff5a2 100644 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -106,11 +106,12 @@ void /*MGEN:Class.NameCap*/::writeConfig (Buffer& buf) /*MGEN:Class.WriteConfig*/ } -void /*MGEN:Class.NameCap*/::writeInstrumentation (Buffer& buf) +void /*MGEN:Class.NameCap*/::writeInstrumentation (Buffer& buf, bool skipHeaders) { instChanged = false; - writeTimestamps (buf); + if (!skipHeaders) + writeTimestamps (buf); /*MGEN:Class.WriteInst*/ // Maintenance of hi-lo statistics diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h index 82fac00d47..047d7cc950 100644 --- a/qpid/cpp/managementgen/templates/Class.h +++ b/qpid/cpp/managementgen/templates/Class.h @@ -25,8 +25,9 @@ #include "qpid/sys/Mutex.h" #include "qpid/management/ManagementObject.h" +#include "qpid/framing/Uuid.h" -namespace qpid { +namespace qpid { namespace management { class /*MGEN:Class.NameCap*/ : public ManagementObject @@ -45,7 +46,8 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject // Private Methods static void writeSchema (qpid::framing::Buffer& buf); void writeConfig (qpid::framing::Buffer& buf); - void writeInstrumentation (qpid::framing::Buffer& buf); + void writeInstrumentation (qpid::framing::Buffer& buf, + bool skipHeaders = false); void doMethod (std::string methodName, qpid::framing::Buffer& inBuf, qpid::framing::Buffer& outBuf); -- cgit v1.2.1 From f765080d69339ff978a20ff697173c362a333f41 Mon Sep 17 00:00:00 2001 From: Kim van der Riet Date: Fri, 4 Apr 2008 18:14:42 +0000 Subject: Patch from Ted Ross (see QPID-902): This patch contains the following improvements for management:\n1) Schema display cleaned up in the python mgmt-cli\n2) Locking added automatically to management object accessors (manual locking removed from broker/Queue.cpp)\n3) Schemas are now pre-registered with the management agent using a package initializer. This allows management consoles to get schema information for a class even if no instances of the class exist. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@644806 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/generate.py | 18 ++++++++++++++++- qpid/cpp/managementgen/main.py | 8 +++++--- qpid/cpp/managementgen/schema.py | 31 ++++++++++++++++++++++++++++++ qpid/cpp/managementgen/templates/Class.cpp | 15 ++------------- qpid/cpp/managementgen/templates/Class.h | 5 +---- 5 files changed, 56 insertions(+), 21 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/generate.py b/qpid/cpp/managementgen/generate.py index 4c042bd3f6..e1c01de9b0 100755 --- a/qpid/cpp/managementgen/generate.py +++ b/qpid/cpp/managementgen/generate.py @@ -187,7 +187,15 @@ class Generator: pass os.rename (tempFile, target) - print "Generated:", target + print "Generated:", target + + def targetPackageFile (self, schema, templateFile): + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + extension = templateFile[dot:len (templateFile)] + path = self.dest + "Package" + schema.getPackageName().capitalize() + extension + return path def targetClassFile (self, _class, templateFile): dot = templateFile.find(".") @@ -244,6 +252,14 @@ class Generator: stream = template.expand (method) self.writeIfChanged (stream, target, force) + def makePackageFile (self, templateFile, schema, force=False): + """ Generate a package-specific file """ + template = Template (self.input + templateFile, self) + self.templateFiles.append (templateFile) + target = self.targetPackageFile (schema, templateFile) + stream = template.expand (schema) + self.writeIfChanged (stream, target, force) + def makeSingleFile (self, templateFile, target, force=False): """ Generate a single expanded template """ makefile = Makefile (self.filelists, self.templateFiles) diff --git a/qpid/cpp/managementgen/main.py b/qpid/cpp/managementgen/main.py index 677c7321ae..87ef3d5298 100755 --- a/qpid/cpp/managementgen/main.py +++ b/qpid/cpp/managementgen/main.py @@ -48,9 +48,11 @@ if opts.include_prefix == ".": gen = Generator (outdir, templatedir) schema = PackageSchema (typefile, schemafile, opts) -gen.makeClassFiles ("Class.h", schema) -gen.makeClassFiles ("Class.cpp", schema) -gen.makeMethodFiles ("Args.h", schema) +gen.makeClassFiles ("Class.h", schema) +gen.makeClassFiles ("Class.cpp", schema) +gen.makeMethodFiles ("Args.h", schema) +gen.makePackageFile ("Package.h", schema) +gen.makePackageFile ("Package.cpp", schema) if opts.makefile != None: gen.makeSingleFile ("Makefile.mk", opts.makefile, force=True) diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index fd76ba9112..44fc091372 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -78,6 +78,7 @@ class SchemaType: def genAccessor (self, stream, varName, changeFlag = None): if self.accessor == "direct": stream.write (" inline void set_" + varName + " (" + self.cpp + " val){\n"); + stream.write (" sys::RWlock::ScopedWlock writeLock (accessLock);\n") if self.style != "mma": stream.write (" " + varName + " = val;\n"); if self.style == "wm": @@ -97,6 +98,7 @@ class SchemaType: stream.write (" }\n"); elif self.accessor == "counter": stream.write (" inline void inc_" + varName + " (" + self.cpp + " by = 1){\n"); + stream.write (" sys::RWlock::ScopedWlock writeLock (accessLock);\n") stream.write (" " + varName + " += by;\n") if self.style == "wm": stream.write (" if (" + varName + "High < " + varName + ")\n") @@ -105,6 +107,7 @@ class SchemaType: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n"); stream.write (" inline void dec_" + varName + " (" + self.cpp + " by = 1){\n"); + stream.write (" sys::RWlock::ScopedWlock writeLock (accessLock);\n") stream.write (" " + varName + " -= by;\n") if self.style == "wm": stream.write (" if (" + varName + "Low > " + varName + ")\n") @@ -796,6 +799,9 @@ class SchemaClass: def genNameLower (self, stream, variables): stream.write (self.name.lower ()) + def genNamePackageCap (self, stream, variables): + stream.write (self.packageName.capitalize ()) + def genNamePackageLower (self, stream, variables): stream.write (self.packageName.lower ()) @@ -867,3 +873,28 @@ class PackageSchema: def getClasses (self): return self.classes + + def genPackageNameUpper (self, stream, variables): + stream.write (self.packageName.upper ()) + + def genPackageNameCap (self, stream, variables): + stream.write (self.packageName.capitalize ()) + + def genClassIncludes (self, stream, variables): + for _class in self.classes: + stream.write ("#include \"qpid/management/") + _class.genNameCap (stream, variables) + stream.write (".h\"\n") + + def genClassRegisters (self, stream, variables): + for _class in self.classes: + stream.write ("agent->RegisterClass (") + _class.genNameCap (stream, variables) + stream.write ("::packageName, ") + _class.genNameCap (stream, variables) + stream.write ("::className, ") + _class.genNameCap (stream, variables) + stream.write ("::md5Sum, ") + _class.genNameCap (stream, variables) + stream.write ("::writeSchema);\n") + diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp index 3c3dfff5a2..5862685670 100644 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -35,7 +35,6 @@ string /*MGEN:Class.NameCap*/::packageName = string ("/*MGEN:Class.NamePackage string /*MGEN:Class.NameCap*/::className = string ("/*MGEN:Class.NameLower*/"); uint8_t /*MGEN:Class.NameCap*/::md5Sum[16] = {/*MGEN:Class.SchemaMD5*/}; -bool /*MGEN:Class.NameCap*/::firstInst = true; /*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (Manageable* _core/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/) : ManagementObject(_core) @@ -63,18 +62,6 @@ namespace { const string DEFAULT("default"); } -bool /*MGEN:Class.NameCap*/::firstInstance (void) -{ - Mutex::ScopedLock alock(accessorLock); - if (firstInst) - { - firstInst = false; - return true; - } - - return false; -} - void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) { FieldTable ft; @@ -100,6 +87,7 @@ void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) void /*MGEN:Class.NameCap*/::writeConfig (Buffer& buf) { + sys::RWlock::ScopedRlock readLock (accessLock); configChanged = false; writeTimestamps (buf); @@ -108,6 +96,7 @@ void /*MGEN:Class.NameCap*/::writeConfig (Buffer& buf) void /*MGEN:Class.NameCap*/::writeInstrumentation (Buffer& buf, bool skipHeaders) { + sys::RWlock::ScopedWlock writeLock (accessLock); instChanged = false; if (!skipHeaders) diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h index 047d7cc950..d95a06479e 100644 --- a/qpid/cpp/managementgen/templates/Class.h +++ b/qpid/cpp/managementgen/templates/Class.h @@ -23,7 +23,6 @@ /*MGEN:Root.Disclaimer*/ -#include "qpid/sys/Mutex.h" #include "qpid/management/ManagementObject.h" #include "qpid/framing/Uuid.h" @@ -37,7 +36,6 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject static std::string packageName; static std::string className; static uint8_t md5Sum[16]; - static bool firstInst; // Configuration Elements /*MGEN:Class.ConfigDeclarations*/ @@ -52,13 +50,12 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject qpid::framing::Buffer& inBuf, qpid::framing::Buffer& outBuf); writeSchemaCall_t getWriteSchemaCall (void) { return writeSchema; } - bool firstInstance (void); /*MGEN:Class.InstChangedStub*/ public: + friend class Package/*MGEN:Class.NamePackageCap*/; typedef boost::shared_ptr shared_ptr; - qpid::sys::Mutex accessorLock; /*MGEN:Class.NameCap*/ (Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); ~/*MGEN:Class.NameCap*/ (void); -- cgit v1.2.1 From 8b4af258451be0ebe40bb0fa10523818ecdbe576 Mon Sep 17 00:00:00 2001 From: Kim van der Riet Date: Fri, 4 Apr 2008 18:25:08 +0000 Subject: Additional files for Ted Ross's checkin git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@644812 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/templates/Package.cpp | 32 ++++++++++++++++++++++ qpid/cpp/managementgen/templates/Package.h | 41 ++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 qpid/cpp/managementgen/templates/Package.cpp create mode 100644 qpid/cpp/managementgen/templates/Package.h (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/templates/Package.cpp b/qpid/cpp/managementgen/templates/Package.cpp new file mode 100644 index 0000000000..0c5af8d71d --- /dev/null +++ b/qpid/cpp/managementgen/templates/Package.cpp @@ -0,0 +1,32 @@ +/*MGEN:commentPrefix=//*/ +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/Package/*MGEN:Schema.PackageNameCap*/.h" +/*MGEN:Schema.ClassIncludes*/ + +using namespace qpid::management; + +Package/*MGEN:Schema.PackageNameCap*/::Package/*MGEN:Schema.PackageNameCap*/ (ManagementAgent::shared_ptr agent) +{ +/*MGEN:Schema.ClassRegisters*/ +} + diff --git a/qpid/cpp/managementgen/templates/Package.h b/qpid/cpp/managementgen/templates/Package.h new file mode 100644 index 0000000000..214f811a1f --- /dev/null +++ b/qpid/cpp/managementgen/templates/Package.h @@ -0,0 +1,41 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ +#define _MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ + +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/ManagementAgent.h" + +namespace qpid { +namespace management { + +class Package/*MGEN:Schema.PackageNameCap*/ +{ + public: + Package/*MGEN:Schema.PackageNameCap*/ (ManagementAgent::shared_ptr agent); + ~Package/*MGEN:Schema.PackageNameCap*/ () {} +}; + +}} + + +#endif /*!_MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_*/ -- cgit v1.2.1 From 981499ce88378e3ab40b5d3bbafc77a6ed25d97a Mon Sep 17 00:00:00 2001 From: Kim van der Riet Date: Fri, 11 Apr 2008 19:10:05 +0000 Subject: Patch from Ted Ross: added set methods to hilo types in generated management classes git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@647270 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/schema.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index 44fc091372..7e4a91814f 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -115,6 +115,17 @@ class SchemaType: if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n"); + stream.write (" inline void set_" + varName + " (" + self.cpp + " val){\n"); + stream.write (" sys::RWlock::ScopedWlock writeLock (accessLock);\n") + stream.write (" " + varName + " = val;\n"); + if self.style == "wm": + stream.write (" if (" + varName + "Low > val)\n") + stream.write (" " + varName + "Low = val;\n") + stream.write (" if (" + varName + "High < val)\n") + stream.write (" " + varName + "High = val;\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); def genHiLoStatResets (self, stream, varName): if self.style == "wm": -- cgit v1.2.1 From b478cb053b79674c74990a390047568de44e448d Mon Sep 17 00:00:00 2001 From: Nuno Santos Date: Thu, 8 May 2008 15:55:57 +0000 Subject: QPID-1035: managementgen only exists in qpid C++ source - applying patched supplied by Matt Farrellee git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@654564 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/generate.py | 2 -- qpid/cpp/managementgen/schema.py | 2 -- 2 files changed, 4 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/generate.py b/qpid/cpp/managementgen/generate.py index e1c01de9b0..5e3aa51b57 100755 --- a/qpid/cpp/managementgen/generate.py +++ b/qpid/cpp/managementgen/generate.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index 7e4a91814f..1b4ca75b44 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file -- cgit v1.2.1 From 43b4c7c2b39db824705738cb00de4aa3521cbf2c Mon Sep 17 00:00:00 2001 From: Nuno Santos Date: Thu, 8 May 2008 16:00:00 +0000 Subject: QPID-1026: managementgen C++ symbol validation - applied patch supplied by Matt Farrellee git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@654566 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/generate.py | 4 +-- qpid/cpp/managementgen/schema.py | 66 +++++++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 10 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/generate.py b/qpid/cpp/managementgen/generate.py index 5e3aa51b57..da78d6c7e9 100755 --- a/qpid/cpp/managementgen/generate.py +++ b/qpid/cpp/managementgen/generate.py @@ -192,7 +192,7 @@ class Generator: if dot == -1: raise ValueError ("Invalid template file name %s" % templateFile) extension = templateFile[dot:len (templateFile)] - path = self.dest + "Package" + schema.getPackageName().capitalize() + extension + path = self.dest + "Package" + schema.getPackageNameCap() + extension return path def targetClassFile (self, _class, templateFile): @@ -200,7 +200,7 @@ class Generator: if dot == -1: raise ValueError ("Invalid template file name %s" % templateFile) extension = templateFile[dot:len (templateFile)] - path = self.dest + _class.getName ().capitalize () + extension + path = self.dest + _class.getNameCap () + extension return path def targetMethodFile (self, method, templateFile): diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index 1b4ca75b44..68e9bfd4e2 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -214,7 +214,7 @@ class SchemaConfig: key = attrs.item(idx).nodeName val = attrs.item(idx).nodeValue if key == 'name': - self.name = val + self.name = makeValidCppSymbol(val) elif key == 'type': self.type = Type (val, typespec) @@ -309,7 +309,7 @@ class SchemaInst: key = attrs.item(idx).nodeName val = attrs.item(idx).nodeValue if key == 'name': - self.name = val + self.name = makeValidCppSymbol(val) elif key == 'type': self.type = Type (val, typespec) @@ -422,7 +422,7 @@ class SchemaArg: key = attrs.item(idx).nodeName val = attrs.item(idx).nodeValue if key == 'name': - self.name = val + self.name = makeValidCppSymbol(val) elif key == 'type': self.type = Type (val, typespec) @@ -496,7 +496,7 @@ class SchemaMethod: key = attrs.item(idx).nodeName val = attrs.item(idx).nodeValue if key == 'name': - self.name = val + self.name = makeValidCppSymbol(val) elif key == 'desc': self.desc = val @@ -602,7 +602,7 @@ class SchemaClass: self.hash (node) attrs = node.attributes - self.name = attrs['name'].nodeValue + self.name = makeValidCppSymbol(attrs['name'].nodeValue) children = node.childNodes for child in children: @@ -660,12 +660,18 @@ class SchemaClass: def getName (self): return self.name + def getNameCap (self): + return capitalize(self.name) + def getMethods (self): return self.methods def getEvents (self): return self.events + def getPackageNameCap (self): + return capitalize(self.packageName) + #=================================================================================== # Code Generation Functions. The names of these functions (minus the leading "gen") # match the substitution keywords in the template files. @@ -809,7 +815,7 @@ class SchemaClass: stream.write (self.name.lower ()) def genNamePackageCap (self, stream, variables): - stream.write (self.packageName.capitalize ()) + stream.write (self.getPackageNameCap ()) def genNamePackageLower (self, stream, variables): stream.write (self.packageName.lower ()) @@ -859,7 +865,7 @@ class PackageSchema: if document.tagName != 'schema': raise ValueError ("Expected 'schema' node") attrs = document.attributes - self.packageName = attrs['package'].nodeValue + self.packageName = makeValidCppSymbol(attrs['package'].nodeValue) children = document.childNodes for child in children: @@ -880,6 +886,9 @@ class PackageSchema: def getPackageName (self): return self.packageName + def getPackageNameCap (self): + return capitalize(self.packageName) + def getClasses (self): return self.classes @@ -887,7 +896,7 @@ class PackageSchema: stream.write (self.packageName.upper ()) def genPackageNameCap (self, stream, variables): - stream.write (self.packageName.capitalize ()) + stream.write (self.getPackageNameCap ()) def genClassIncludes (self, stream, variables): for _class in self.classes: @@ -907,3 +916,44 @@ class PackageSchema: _class.genNameCap (stream, variables) stream.write ("::writeSchema);\n") + +#===================================================================================== +# Utility Functions +#===================================================================================== + +# Create a valid C++ symbol from the input string so that it can be +# used in generated C++ source. For instance, change "qpid.mgmt" to +# "qpidMgmt". +# +# Input: Raw string (str) to process +# Output: String (str) suitable for use as a C++ symbol +# +# Limitations: Currently, only strips periods ('.') from strings, +# eventually should strip :'s and ,'s and ''s, oh my! +def makeValidCppSymbol(input): + output = str() + capitalize = False + + for char in input: + skip = False + + if char == ".": + capitalize = True + skip = True + + if not skip: + output += capitalize and char.upper() or char + + capitalize = False + + return output + +# Capitalize a string by /only/ forcing the first character to be +# uppercase. The rest of the string is left alone. This is different +# from str.capitalize(), which forces the first character to uppercase +# and the rest to lowercase. +# +# Input: A string (str) to capitalize +# Output: A string (str) with the first character as uppercase +def capitalize(input): + return input[0].upper() + input[1:] -- cgit v1.2.1 From 7df38ca1af3bcc71a327cbae7b494b15f16b67de Mon Sep 17 00:00:00 2001 From: Nuno Santos Date: Thu, 8 May 2008 16:27:42 +0000 Subject: QPID-1035: managementgen only exists in qpid C++ source - applying patched supplied by Matt Farrellee git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@654574 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/Makefile.am | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 qpid/cpp/managementgen/Makefile.am (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am new file mode 100644 index 0000000000..be10d9f0d1 --- /dev/null +++ b/qpid/cpp/managementgen/Makefile.am @@ -0,0 +1,27 @@ +managementgendir = $(datadir)/managementgen +dist_managementgen_SCRIPTS = \ + main.py +nobase_managementgen_DATA = \ + schema.py generate.py \ + templates/Args.h \ + templates/Class.cpp \ + templates/Class.h \ + templates/Makefile.mk \ + templates/Package.cpp \ + templates/Package.h \ + management-types.xml + +dist_bin_SCRIPTS = managementgen + +EXTRA_DIST = $(nobase_managementgen_DATA) + +# This should depend on ../../specs/management-types.xml, but can't +# because it won't exist in a dist. This rule means that dist-gzip +# (and rpmbuild) cannot be run purely on the cpp/ directory, the +# cpp/../specs/ directory must exist, which is not a new dependency +# but this is an additional instance of the dependency. +# +# WARNING: Because this target does not have a proper dependency +# changes to the specs/management-types.xml will not be picked up! +management-types.xml: + cp ../../specs/management-types.xml . -- cgit v1.2.1 From 8e44c8d17d2bed4f69ef3a9bcfdec5d087514315 Mon Sep 17 00:00:00 2001 From: Nuno Santos Date: Thu, 8 May 2008 17:22:11 +0000 Subject: QPID-1035: managementgen only exists in qpid C++ source - applying patched supplied by Matt Farrellee git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@654584 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/managementgen | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 qpid/cpp/managementgen/managementgen (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/managementgen b/qpid/cpp/managementgen/managementgen new file mode 100644 index 0000000000..55ea846270 --- /dev/null +++ b/qpid/cpp/managementgen/managementgen @@ -0,0 +1,26 @@ +#!/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. +# + +import sys + +sys.path.append("/usr/share/managementgen") + +import main -- cgit v1.2.1 From 3e41544f9e3a66d4ab8b554ad6e2c864b48b79c6 Mon Sep 17 00:00:00 2001 From: Andrew Stitcher Date: Fri, 9 May 2008 16:02:15 +0000 Subject: Fix to managementgen so that VPATH builds work git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@654866 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am index be10d9f0d1..993eeb1d20 100644 --- a/qpid/cpp/managementgen/Makefile.am +++ b/qpid/cpp/managementgen/Makefile.am @@ -24,4 +24,4 @@ EXTRA_DIST = $(nobase_managementgen_DATA) # WARNING: Because this target does not have a proper dependency # changes to the specs/management-types.xml will not be picked up! management-types.xml: - cp ../../specs/management-types.xml . + cp $(top_srcdir)/../specs/management-types.xml . -- cgit v1.2.1 From b9622a65fdfc0846e620b4ef508488d75d6e6ee5 Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Mon, 12 May 2008 17:04:07 +0000 Subject: QPID-1050: Patch from Ted Ross: 1) Durability for federation links (broker-to-broker connections) 2) Improved handling of federation links: a) Links can be created even if the remote broker is not reachable b) If links are lost, re-establishment will occur using an exponential back-off algorithm 3) Durability of exchanges is now viewable through management 4) ManagementAgent API has been moved to an interface class to reduce coupling between the broker and manageable plug-ins. 5) General configuration storage capability has been added to the store/recover interface. This is used for federation links. 6) Management object-ids for durable objects are now themselves durable. (Note: some refactoring needed around ProtocolAccess needed to try and reduce dependencies) git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@655563 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/templates/Class.h | 1 + 1 file changed, 1 insertion(+) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h index d95a06479e..628a70d2d9 100644 --- a/qpid/cpp/managementgen/templates/Class.h +++ b/qpid/cpp/managementgen/templates/Class.h @@ -24,6 +24,7 @@ /*MGEN:Root.Disclaimer*/ #include "qpid/management/ManagementObject.h" +#include "qpid/framing/FieldTable.h" #include "qpid/framing/Uuid.h" namespace qpid { -- cgit v1.2.1 From fe0ce73ac72ac4c2300b62f67275dd7221fa4c7d Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Thu, 22 May 2008 13:42:05 +0000 Subject: QPID-1088 git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@659110 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/schema.py | 6 ++---- qpid/cpp/managementgen/templates/Class.cpp | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index 68e9bfd4e2..7a9f23ea76 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -76,7 +76,7 @@ class SchemaType: def genAccessor (self, stream, varName, changeFlag = None): if self.accessor == "direct": stream.write (" inline void set_" + varName + " (" + self.cpp + " val){\n"); - stream.write (" sys::RWlock::ScopedWlock writeLock (accessLock);\n") + stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") if self.style != "mma": stream.write (" " + varName + " = val;\n"); if self.style == "wm": @@ -96,7 +96,6 @@ class SchemaType: stream.write (" }\n"); elif self.accessor == "counter": stream.write (" inline void inc_" + varName + " (" + self.cpp + " by = 1){\n"); - stream.write (" sys::RWlock::ScopedWlock writeLock (accessLock);\n") stream.write (" " + varName + " += by;\n") if self.style == "wm": stream.write (" if (" + varName + "High < " + varName + ")\n") @@ -105,7 +104,6 @@ class SchemaType: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n"); stream.write (" inline void dec_" + varName + " (" + self.cpp + " by = 1){\n"); - stream.write (" sys::RWlock::ScopedWlock writeLock (accessLock);\n") stream.write (" " + varName + " -= by;\n") if self.style == "wm": stream.write (" if (" + varName + "Low > " + varName + ")\n") @@ -114,7 +112,7 @@ class SchemaType: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n"); stream.write (" inline void set_" + varName + " (" + self.cpp + " val){\n"); - stream.write (" sys::RWlock::ScopedWlock writeLock (accessLock);\n") + stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") stream.write (" " + varName + " = val;\n"); if self.style == "wm": stream.write (" if (" + varName + "Low > val)\n") diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp index 5862685670..733e29188e 100644 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -87,7 +87,7 @@ void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) void /*MGEN:Class.NameCap*/::writeConfig (Buffer& buf) { - sys::RWlock::ScopedRlock readLock (accessLock); + sys::Mutex::ScopedLock mutex(accessLock); configChanged = false; writeTimestamps (buf); @@ -96,7 +96,7 @@ void /*MGEN:Class.NameCap*/::writeConfig (Buffer& buf) void /*MGEN:Class.NameCap*/::writeInstrumentation (Buffer& buf, bool skipHeaders) { - sys::RWlock::ScopedWlock writeLock (accessLock); + sys::Mutex::ScopedLock mutex(accessLock); instChanged = false; if (!skipHeaders) -- cgit v1.2.1 From f72b278bcee746b01bc8334a0bd3775817db3162 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Mon, 2 Jun 2008 16:01:51 +0000 Subject: QPID-1113 Management cleanup and performance enhancements git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@662470 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/schema.py | 133 ++++++++++++++++++----------- qpid/cpp/managementgen/templates/Class.cpp | 4 +- qpid/cpp/managementgen/templates/Class.h | 8 +- 3 files changed, 90 insertions(+), 55 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index 7a9f23ea76..6e48003ab2 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -94,9 +94,23 @@ class SchemaType: if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n"); + elif self.accessor == "counterByOne": + stream.write (" inline void inc_" + varName + " (){\n"); + stream.write (" ++" + varName + ";\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); + stream.write (" inline void dec_" + varName + " (){\n"); + stream.write (" --" + varName + ";\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); elif self.accessor == "counter": stream.write (" inline void inc_" + varName + " (" + self.cpp + " by = 1){\n"); - stream.write (" " + varName + " += by;\n") + stream.write (" if (by == 1)\n") + stream.write (" ++" + varName + ";\n") + stream.write (" else\n") + stream.write (" " + varName + " += by;\n") if self.style == "wm": stream.write (" if (" + varName + "High < " + varName + ")\n") stream.write (" " + varName + "High = " + varName + ";\n") @@ -104,7 +118,10 @@ class SchemaType: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n"); stream.write (" inline void dec_" + varName + " (" + self.cpp + " by = 1){\n"); - stream.write (" " + varName + " -= by;\n") + stream.write (" if (by == 1)\n") + stream.write (" " + varName + "--;\n") + stream.write (" else\n") + stream.write (" " + varName + " -= by;\n") if self.style == "wm": stream.write (" if (" + varName + "Low > " + varName + ")\n") stream.write (" " + varName + "Low = " + varName + ";\n") @@ -196,16 +213,18 @@ class Type: #===================================================================================== class SchemaConfig: def __init__ (self, node, typespec): - self.name = None - self.type = None - self.access = "RO" - self.isIndex = 0 - self.isParentRef = 0 - self.unit = None - self.min = None - self.max = None - self.maxLen = None - self.desc = None + self.name = None + self.type = None + self.ref = None + self.access = "RO" + self.isIndex = 0 + self.isParentRef = 0 + self.isGeneralRef = 0 + self.unit = None + self.min = None + self.max = None + self.maxLen = None + self.desc = None attrs = node.attributes for idx in range (attrs.length): @@ -216,6 +235,9 @@ class SchemaConfig: elif key == 'type': self.type = Type (val, typespec) + + elif key == 'references': + self.ref = val elif key == 'access': self.access = val @@ -230,6 +252,11 @@ class SchemaConfig: raise ValueError ("Expected 'y' in parentRef attribute") self.isParentRef = 1 + elif key == 'isGeneralReference': + if val != 'y': + raise ValueError ("Expected 'y' in isGeneralReference attribute") + self.isGeneralRef = 1 + elif key == 'unit': self.unit = val @@ -246,12 +273,12 @@ class SchemaConfig: self.desc = val else: - raise ValueError ("Unknown attribute in configElement '%s'" % key) + raise ValueError ("Unknown attribute in property '%s'" % key) if self.name == None: - raise ValueError ("Missing 'name' attribute in configElement") + raise ValueError ("Missing 'name' attribute in property") if self.type == None: - raise ValueError ("Missing 'type' attribute in configElement") + raise ValueError ("Missing 'type' attribute in property") def getName (self): return self.name @@ -319,12 +346,12 @@ class SchemaInst: self.desc = val else: - raise ValueError ("Unknown attribute in instElement '%s'" % key) + raise ValueError ("Unknown attribute in statistic '%s'" % key) if self.name == None: - raise ValueError ("Missing 'name' attribute in instElement") + raise ValueError ("Missing 'name' attribute in statistic") if self.type == None: - raise ValueError ("Missing 'type' attribute in instElement") + raise ValueError ("Missing 'type' attribute in statistic") def getName (self): return self.name @@ -388,6 +415,8 @@ class SchemaInst: def genInitialize (self, stream): val = self.type.type.init + if self.type.type.accessor == "counterByOne": + return if self.type.type.style != "mma": stream.write (" " + self.name + " = " + val + ";\n") if self.type.type.style == "wm": @@ -589,13 +618,13 @@ class SchemaEvent: class SchemaClass: def __init__ (self, package, node, typespec, fragments, options): - self.packageName = package - self.configElements = [] - self.instElements = [] - self.methods = [] - self.events = [] - self.options = options - self.md5Sum = md5.new () + self.packageName = package + self.properties = [] + self.statistics = [] + self.methods = [] + self.events = [] + self.options = options + self.md5Sum = md5.new () self.hash (node) @@ -605,13 +634,13 @@ class SchemaClass: children = node.childNodes for child in children: if child.nodeType == Node.ELEMENT_NODE: - if child.nodeName == 'configElement': + if child.nodeName == 'property': sub = SchemaConfig (child, typespec) - self.configElements.append (sub) + self.properties.append (sub) - elif child.nodeName == 'instElement': + elif child.nodeName == 'statistic': sub = SchemaInst (child, typespec) - self.instElements.append (sub) + self.statistics.append (sub) elif child.nodeName == 'method': sub = SchemaMethod (self, child, typespec) @@ -644,10 +673,10 @@ class SchemaClass: name = attrs['name'].nodeValue for fragment in fragments: if fragment.name == name: - for config in fragment.configElements: - self.configElements.append (config) - for inst in fragment.instElements: - self.instElements.append (inst) + for config in fragment.properties: + self.properties.append (config) + for inst in fragment.statistics: + self.statistics.append (inst) for method in fragment.methods: self.methods.append (method) for event in fragment.events: @@ -675,33 +704,33 @@ class SchemaClass: # match the substitution keywords in the template files. #=================================================================================== def genAccessorMethods (self, stream, variables): - for config in self.configElements: + for config in self.properties: if config.access != "RC": config.genAccessor (stream) - for inst in self.instElements: + for inst in self.statistics: inst.genAccessor (stream) def genConfigCount (self, stream, variables): - stream.write ("%d" % len (self.configElements)) + stream.write ("%d" % len (self.properties)) def genConfigDeclarations (self, stream, variables): - for element in self.configElements: + for element in self.properties: element.genDeclaration (stream) def genConfigElementSchema (self, stream, variables): - for config in self.configElements: + for config in self.properties: config.genSchema (stream) def genConstructorArgs (self, stream, variables): # Constructor args are config elements with read-create access result = "" - for element in self.configElements: + for element in self.properties: if element.isConstructorArg (): stream.write (", ") element.genFormalParam (stream) def genConstructorInits (self, stream, variables): - for element in self.configElements: + for element in self.properties: if element.isConstructorArg (): stream.write ("," + element.getName () + "(_" + element.getName () + ")") @@ -729,21 +758,21 @@ class SchemaClass: pass ########################################################################### def genHiLoStatResets (self, stream, variables): - for inst in self.instElements: + for inst in self.statistics: inst.genHiLoStatResets (stream) def genInitializeElements (self, stream, variables): - for inst in self.instElements: + for inst in self.statistics: inst.genInitialize (stream) def genInstChangedStub (self, stream, variables): - if len (self.instElements) == 0: + if len (self.statistics) == 0: stream.write (" // Stub for getInstChanged. There are no inst elements\n") stream.write (" bool getInstChanged (void) { return false; }\n") def genInstCount (self, stream, variables): count = 0 - for inst in self.instElements: + for inst in self.statistics: count = count + 1 if inst.type.type.style == "wm": count = count + 2 @@ -752,11 +781,11 @@ class SchemaClass: stream.write ("%d" % count) def genInstDeclarations (self, stream, variables): - for element in self.instElements: + for element in self.statistics: element.genDeclaration (stream) def genInstElementSchema (self, stream, variables): - for inst in self.instElements: + for inst in self.statistics: inst.genSchema (stream) def genMethodArgIncludes (self, stream, variables): @@ -794,6 +823,10 @@ class SchemaClass: arg.name, "outBuf") + ";\n") stream.write (" return;\n }\n") + def genSetGeneralReferenceDeclaration (self, stream, variables): + for prop in self.properties: + if prop.isGeneralRef: + stream.write ("void setReference(uint64_t objectId) { " + prop.name + " = objectId; }\n") def genMethodIdDeclarations (self, stream, variables): number = 1 @@ -822,13 +855,13 @@ class SchemaClass: stream.write (self.name.upper ()) def genParentArg (self, stream, variables): - for config in self.configElements: + for config in self.properties: if config.isParentRef == 1: stream.write (", Manageable* _parent") return def genParentRefAssignment (self, stream, variables): - for config in self.configElements: + for config in self.properties: if config.isParentRef == 1: stream.write (config.getName () + \ " = _parent->GetManagementObject ()->getObjectId ();") @@ -842,11 +875,11 @@ class SchemaClass: stream.write (hex (ord (sum[idx]))) def genWriteConfig (self, stream, variables): - for config in self.configElements: + for config in self.properties: config.genWrite (stream); def genWriteInst (self, stream, variables): - for inst in self.instElements: + for inst in self.statistics: inst.genWrite (stream); diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp index 733e29188e..699d8217b6 100644 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -75,9 +75,9 @@ void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) buf.putShort (/*MGEN:Class.MethodCount*/); // Method Count buf.putShort (/*MGEN:Class.EventCount*/); // Event Count - // Config Elements + // Properties /*MGEN:Class.ConfigElementSchema*/ - // Inst Elements + // Statistics /*MGEN:Class.InstElementSchema*/ // Methods /*MGEN:Class.MethodSchema*/ diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h index 628a70d2d9..441571a174 100644 --- a/qpid/cpp/managementgen/templates/Class.h +++ b/qpid/cpp/managementgen/templates/Class.h @@ -26,6 +26,7 @@ #include "qpid/management/ManagementObject.h" #include "qpid/framing/FieldTable.h" #include "qpid/framing/Uuid.h" +#include "qpid/sys/AtomicCount.h" namespace qpid { namespace management { @@ -38,9 +39,9 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject static std::string className; static uint8_t md5Sum[16]; - // Configuration Elements + // Properties /*MGEN:Class.ConfigDeclarations*/ - // Instrumentation Elements + // Statistics /*MGEN:Class.InstDeclarations*/ // Private Methods static void writeSchema (qpid::framing::Buffer& buf); @@ -61,6 +62,8 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject /*MGEN:Class.NameCap*/ (Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); ~/*MGEN:Class.NameCap*/ (void); + /*MGEN:Class.SetGeneralReferenceDeclaration*/ + std::string getPackageName (void) { return packageName; } std::string getClassName (void) { return className; } uint8_t* getMd5Sum (void) { return md5Sum; } @@ -72,6 +75,5 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject }; }} - #endif /*!_MANAGEMENT_/*MGEN:Class.NameUpper*/_*/ -- cgit v1.2.1 From e3ec9422951be06c11ca285b75675cec9c8369f6 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Mon, 2 Jun 2008 22:32:21 +0000 Subject: Queue stats: byteDepth now computed periodically git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@662592 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/schema.py | 24 ++++++++++++++++++------ qpid/cpp/managementgen/templates/Class.cpp | 1 + 2 files changed, 19 insertions(+), 6 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index 6e48003ab2..4e1f898274 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -324,10 +324,11 @@ class SchemaConfig: #===================================================================================== class SchemaInst: def __init__ (self, node, typespec): - self.name = None - self.type = None - self.unit = None - self.desc = None + self.name = None + self.type = None + self.unit = None + self.desc = None + self.assign = None attrs = node.attributes for idx in range (attrs.length): @@ -345,6 +346,9 @@ class SchemaInst: elif key == 'desc': self.desc = val + elif key == 'assign': + self.assign = val + else: raise ValueError ("Unknown attribute in statistic '%s'" % key) @@ -410,6 +414,10 @@ class SchemaInst: self.genSchemaText (stream, self.name + "Max", descMax) self.genSchemaText (stream, self.name + "Average", descAverage) + def genAssign (self, stream): + if self.assign != None: + stream.write (" " + self.name + " = (" + self.type.type.cpp + ") (" + self.assign + ");\n") + def genWrite (self, stream): self.type.type.genWrite (stream, self.name) @@ -874,13 +882,17 @@ class SchemaClass: stream.write (",") stream.write (hex (ord (sum[idx]))) + def genAssign (self, stream, variables): + for inst in self.statistics: + inst.genAssign (stream) + def genWriteConfig (self, stream, variables): for config in self.properties: - config.genWrite (stream); + config.genWrite (stream) def genWriteInst (self, stream, variables): for inst in self.statistics: - inst.genWrite (stream); + inst.genWrite (stream) diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp index 699d8217b6..a1d5fed192 100644 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -98,6 +98,7 @@ void /*MGEN:Class.NameCap*/::writeInstrumentation (Buffer& buf, bool skipHeaders { sys::Mutex::ScopedLock mutex(accessLock); instChanged = false; +/*MGEN:Class.Assign*/ if (!skipHeaders) writeTimestamps (buf); -- cgit v1.2.1 From f0674fb0984ed4ff6b43276b7711244e69fd7d40 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 4 Jun 2008 22:13:40 +0000 Subject: Management cleanup - Synchronized with the spec on the Wiki git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@663386 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/templates/Class.cpp | 4 ++-- qpid/cpp/managementgen/templates/Class.h | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp index a1d5fed192..0fbb78b7f1 100644 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -85,7 +85,7 @@ void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) /*MGEN:Class.EventSchema*/ } -void /*MGEN:Class.NameCap*/::writeConfig (Buffer& buf) +void /*MGEN:Class.NameCap*/::writeProperties (Buffer& buf) { sys::Mutex::ScopedLock mutex(accessLock); configChanged = false; @@ -94,7 +94,7 @@ void /*MGEN:Class.NameCap*/::writeConfig (Buffer& buf) /*MGEN:Class.WriteConfig*/ } -void /*MGEN:Class.NameCap*/::writeInstrumentation (Buffer& buf, bool skipHeaders) +void /*MGEN:Class.NameCap*/::writeStatistics (Buffer& buf, bool skipHeaders) { sys::Mutex::ScopedLock mutex(accessLock); instChanged = false; diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h index 441571a174..aa01f8f105 100644 --- a/qpid/cpp/managementgen/templates/Class.h +++ b/qpid/cpp/managementgen/templates/Class.h @@ -44,13 +44,13 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject // Statistics /*MGEN:Class.InstDeclarations*/ // Private Methods - static void writeSchema (qpid::framing::Buffer& buf); - void writeConfig (qpid::framing::Buffer& buf); - void writeInstrumentation (qpid::framing::Buffer& buf, - bool skipHeaders = false); - void doMethod (std::string methodName, - qpid::framing::Buffer& inBuf, - qpid::framing::Buffer& outBuf); + static void writeSchema (qpid::framing::Buffer& buf); + void writeProperties (qpid::framing::Buffer& buf); + void writeStatistics (qpid::framing::Buffer& buf, + bool skipHeaders = false); + void doMethod (std::string methodName, + qpid::framing::Buffer& inBuf, + qpid::framing::Buffer& outBuf); writeSchemaCall_t getWriteSchemaCall (void) { return writeSchema; } /*MGEN:Class.InstChangedStub*/ -- cgit v1.2.1 From d2051d8e6910c4cbcd9c2ce2ef01089360f83e43 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Mon, 30 Jun 2008 19:00:49 +0000 Subject: QPID-1160 - Per-thread counters in management API to avoid locking git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@672864 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/generate.py | 62 +++++-- qpid/cpp/managementgen/schema.py | 251 ++++++++++++++++++++--------- qpid/cpp/managementgen/templates/Class.cpp | 56 ++++++- qpid/cpp/managementgen/templates/Class.h | 33 +++- 4 files changed, 300 insertions(+), 102 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/generate.py b/qpid/cpp/managementgen/generate.py index da78d6c7e9..197deec4f1 100755 --- a/qpid/cpp/managementgen/generate.py +++ b/qpid/cpp/managementgen/generate.py @@ -30,39 +30,62 @@ 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). + is an object that is responsible for storing variables (setVariable), + checking conditions (testCondition), and expanding tags (substHandler). """ def __init__ (self, filename, handler): self.filename = filename self.handler = handler self.handler.initExpansion () + self.writing = True def expandLine (self, line, stream, object): cursor = 0 while 1: sub = line.find ("/*MGEN:", cursor) if sub == -1: - stream.write (line[cursor:len (line)]) + if self.writing: + stream.write (line[cursor:len (line)]) return subend = line.find("*/", sub) - stream.write (line[cursor:sub]) + if self.writing: + stream.write (line[cursor:sub]) cursor = subend + 2 - tag = line[sub:subend] - equalPos = tag.find ("=") - if equalPos == -1: - dotPos = tag.find (".") + tag = line[sub:subend] + + if tag[7:10] == "IF(": + close = tag.find(")") + if close == -1: + raise ValueError ("Missing ')' on condition") + cond = tag[10:close] + dotPos = cond.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) + raise ValueError ("Invalid condition tag: %s" % cond) + tagObject = cond[0:dotPos] + tagName = cond[dotPos + 1 : len(cond)] + if not self.handler.testCondition(object, tagObject, tagName): + self.writing = False + + elif tag[7:12] == "ENDIF": + self.writing = True + else: - tagKey = tag[7:equalPos] - tagVal = tag[equalPos + 1:len (tag)] - self.handler.setVariable (tagKey, tagVal) + 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)] + if self.writing: + self.handler.substHandler (object, stream, tagObject, tagName) + else: + tagKey = tag[7:equalPos] + tagVal = tag[equalPos + 1:len (tag)] + if self.writing: + self.handler.setVariable (tagKey, tagVal) def expand (self, object): fd = open (self.filename) @@ -224,6 +247,15 @@ class Generator: call = obj + ".gen" + tag + "(stream, self.variables)" eval (call) + def testCondition (self, object, tagObject, tag): + if tagObject == "Root": + obj = "self" + else: + obj = "object" # MUST be the same as the 2nd formal parameter + + call = obj + ".test" + tag + "(self.variables)" + return eval (call) + def setVariable (self, key, value): self.variables[key] = value diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index 4e1f898274..4f5dc216ab 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -26,14 +26,15 @@ import md5 #===================================================================================== class SchemaType: def __init__ (self, node): - self.name = None - self.base = None - self.cpp = None - self.encode = None - self.decode = None - self.style = "normal" - self.accessor = None - self.init = "0" + self.name = None + self.base = None + self.cpp = None + self.encode = None + self.decode = None + self.style = "normal" + self.accessor = None + self.init = "0" + self.perThread = False attrs = node.attributes for idx in range (attrs.length): @@ -63,6 +64,11 @@ class SchemaType: elif key == 'init': self.init = val + elif key == 'perThread': + if val != 'y': + raise ValueError ("Expected 'y' in perThread attribute") + self.perThread = True + else: raise ValueError ("Unknown attribute in type '%s'" % key) @@ -74,43 +80,38 @@ class SchemaType: return self.name def genAccessor (self, stream, varName, changeFlag = None): + if self.perThread: + prefix = "getThreadStats()->" + if self.style == "wm": + raise ValueError ("'wm' style types can't be per-thread") + else: + prefix = "" if self.accessor == "direct": stream.write (" inline void set_" + varName + " (" + self.cpp + " val){\n"); - stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") + if not self.perThread: + stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") if self.style != "mma": - stream.write (" " + varName + " = val;\n"); + stream.write (" " + prefix + varName + " = val;\n"); if self.style == "wm": stream.write (" if (" + varName + "Low > val)\n") stream.write (" " + varName + "Low = val;\n") stream.write (" if (" + varName + "High < val)\n") stream.write (" " + varName + "High = val;\n") if self.style == "mma": - stream.write (" " + varName + "Count++;\n") - stream.write (" " + varName + "Total += val;\n") - stream.write (" if (" + varName + "Min > val)\n") - stream.write (" " + varName + "Min = val;\n") - stream.write (" if (" + varName + "Max < val)\n") - stream.write (" " + varName + "Max = val;\n") - if changeFlag != None: - stream.write (" " + changeFlag + " = true;\n") - stream.write (" }\n"); - elif self.accessor == "counterByOne": - stream.write (" inline void inc_" + varName + " (){\n"); - stream.write (" ++" + varName + ";\n") - if changeFlag != None: - stream.write (" " + changeFlag + " = true;\n") - stream.write (" }\n"); - stream.write (" inline void dec_" + varName + " (){\n"); - stream.write (" --" + varName + ";\n") + stream.write (" " + prefix + varName + "Count++;\n") + stream.write (" " + prefix + varName + "Total += val;\n") + stream.write (" if (" + prefix + varName + "Min > val)\n") + stream.write (" " + prefix + varName + "Min = val;\n") + stream.write (" if (" + prefix + varName + "Max < val)\n") + stream.write (" " + prefix + varName + "Max = val;\n") if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n"); elif self.accessor == "counter": stream.write (" inline void inc_" + varName + " (" + self.cpp + " by = 1){\n"); - stream.write (" if (by == 1)\n") - stream.write (" ++" + varName + ";\n") - stream.write (" else\n") - stream.write (" " + varName + " += by;\n") + if not self.perThread: + stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" " + prefix + varName + " += by;\n") if self.style == "wm": stream.write (" if (" + varName + "High < " + varName + ")\n") stream.write (" " + varName + "High = " + varName + ";\n") @@ -118,27 +119,15 @@ class SchemaType: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n"); stream.write (" inline void dec_" + varName + " (" + self.cpp + " by = 1){\n"); - stream.write (" if (by == 1)\n") - stream.write (" " + varName + "--;\n") - stream.write (" else\n") - stream.write (" " + varName + " -= by;\n") + if not self.perThread: + stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" " + prefix + varName + " -= by;\n") if self.style == "wm": stream.write (" if (" + varName + "Low > " + varName + ")\n") stream.write (" " + varName + "Low = " + varName + ";\n") if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n"); - stream.write (" inline void set_" + varName + " (" + self.cpp + " val){\n"); - stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") - stream.write (" " + varName + " = val;\n"); - if self.style == "wm": - stream.write (" if (" + varName + "Low > val)\n") - stream.write (" " + varName + "Low = val;\n") - stream.write (" if (" + varName + "High < val)\n") - stream.write (" " + varName + "High = val;\n") - if changeFlag != None: - stream.write (" " + changeFlag + " = true;\n") - stream.write (" }\n"); def genHiLoStatResets (self, stream, varName): if self.style == "wm": @@ -150,6 +139,13 @@ class SchemaType: stream.write (" " + varName + "Min = -1;\n") stream.write (" " + varName + "Max = 0;\n") + def genPerThreadHiLoStatResets (self, stream, varName): + if self.style == "mma": + stream.write (" threadStats->" + varName + "Count = 0;\n") + stream.write (" threadStats->" + varName + "Total = 0;\n") + stream.write (" threadStats->" + varName + "Min = -1;\n") + stream.write (" threadStats->" + varName + "Max = 0;\n") + def genWrite (self, stream, varName): if self.style != "mma": stream.write (" " + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") @@ -235,6 +231,8 @@ class SchemaConfig: elif key == 'type': self.type = Type (val, typespec) + if self.type.type.accessor != 'direct': + raise ValueError ("Class properties must have a type with a direct accessor") elif key == 'references': self.ref = val @@ -288,8 +286,8 @@ class SchemaConfig: return 1 return 0 - def genDeclaration (self, stream): - stream.write (" " + self.type.type.cpp + " " + self.name + ";\n") + def genDeclaration (self, stream, prefix=" "): + stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") def genFormalParam (self, stream): stream.write (self.type.type.cpp + " _" + self.name) @@ -360,17 +358,17 @@ class SchemaInst: def getName (self): return self.name - def genDeclaration (self, stream): + def genDeclaration (self, stream, prefix=" "): if self.type.type.style != "mma": - stream.write (" " + self.type.type.cpp + " " + self.name + ";\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") if self.type.type.style == 'wm': - stream.write (" " + self.type.type.cpp + " " + self.name + "High;\n") - stream.write (" " + self.type.type.cpp + " " + self.name + "Low;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "High;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "Low;\n") if self.type.type.style == "mma": - stream.write (" " + self.type.type.cpp + " " + self.name + "Count;\n") - stream.write (" uint64_t " + self.name + "Total;\n") - stream.write (" " + self.type.type.cpp + " " + self.name + "Min;\n") - stream.write (" " + self.type.type.cpp + " " + self.name + "Max;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "Count;\n") + stream.write (prefix + "uint64_t " + self.name + "Total;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "Min;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "Max;\n") def genAccessor (self, stream): self.type.type.genAccessor (stream, self.name, "instChanged") @@ -378,6 +376,9 @@ class SchemaInst: def genHiLoStatResets (self, stream): self.type.type.genHiLoStatResets (stream, self.name) + def genPerThreadHiLoStatResets (self, stream): + self.type.type.genPerThreadHiLoStatResets (stream, self.name) + def genSchemaText (self, stream, name, desc): stream.write (" ft = FieldTable ();\n") stream.write (" ft.setString (NAME, \"" + name + "\");\n") @@ -416,26 +417,51 @@ class SchemaInst: def genAssign (self, stream): if self.assign != None: - stream.write (" " + self.name + " = (" + self.type.type.cpp + ") (" + self.assign + ");\n") + if self.type.type.perThread: + prefix = " threadStats->" + else: + prefix = "" + stream.write (" " + prefix + self.name + " = (" + self.type.type.cpp + + ") (" + self.assign + ");\n") def genWrite (self, stream): - self.type.type.genWrite (stream, self.name) + if self.type.type.perThread: + self.type.type.genWrite (stream, "totals." + self.name) + else: + self.type.type.genWrite (stream, self.name) - def genInitialize (self, stream): + def genInitialize (self, stream, prefix="", indent=" "): val = self.type.type.init - if self.type.type.accessor == "counterByOne": - return if self.type.type.style != "mma": - stream.write (" " + self.name + " = " + val + ";\n") + stream.write (indent + prefix + self.name + " = " + val + ";\n") if self.type.type.style == "wm": - stream.write (" " + self.name + "High = " + val + ";\n") - stream.write (" " + self.name + "Low = " + val + ";\n") + stream.write (indent + prefix + self.name + "High = " + val + ";\n") + stream.write (indent + prefix + self.name + "Low = " + val + ";\n") if self.type.type.style == "mma": - stream.write (" " + self.name + "Count = 0;\n") - stream.write (" " + self.name + "Min = -1;\n") - stream.write (" " + self.name + "Max = 0;\n") - stream.write (" " + self.name + "Total = 0;\n") + stream.write (indent + prefix + self.name + "Count = 0;\n") + stream.write (indent + prefix + self.name + "Min = -1;\n") + stream.write (indent + prefix + self.name + "Max = 0;\n") + stream.write (indent + prefix + self.name + "Total = 0;\n") + def genInitializeTotalPerThreadStats (self, stream): + if self.type.type.style == "mma": + stream.write (" totals->" + self.name + "Count = 0;\n") + stream.write (" totals->" + self.name + "Min = -1;\n") + stream.write (" totals->" + self.name + "Max = 0;\n") + stream.write (" totals->" + self.name + "Total = 0;\n") + else: + stream.write (" totals->" + self.name + " = 0;\n") + + def genAggregatePerThreadStats (self, stream): + if self.type.type.style == "mma": + stream.write (" totals->%sCount += threadStats->%sCount;\n" % (self.name, self.name)) + stream.write (" if (totals->%sMin > threadStats->%sMin)\n" % (self.name, self.name)) + stream.write (" totals->%sMin = threadStats->%sMin;\n" % (self.name, self.name)) + stream.write (" if (totals->%sMax < threadStats->%sMax)\n" % (self.name, self.name)) + stream.write (" totals->%sMax = threadStats->%sMax;\n" % (self.name, self.name)) + stream.write (" totals->%sTotal += threadStats->%sTotal;\n" % (self.name, self.name)) + else: + stream.write (" totals->%s += threadStats->%s;\n" % (self.name, self.name)) #===================================================================================== # @@ -664,6 +690,26 @@ class SchemaClass: else: raise ValueError ("Unknown class tag '%s'" % child.nodeName) + # Adjust the 'assign' attributes for each statistic + for stat in self.statistics: + if stat.assign != None and stat.type.type.perThread: + stat.assign = self.adjust (stat.assign, self.statistics) + + def adjust (self, text, statistics): + result = text + start = 0 + while True: + next = None + for stat in statistics: + pos = result.find (stat.name, start) + if pos != -1 and (next == None or pos < next[0]): + next = (pos, stat.name) + if next == None: + return result + pos = next[0] + result = result[0:pos] + "threadStats->" + result[pos:] + start = pos + 9 + len(next[1]) + def hash (self, node): attrs = node.attributes self.md5Sum.update (node.nodeName) @@ -711,12 +757,34 @@ class SchemaClass: # Code Generation Functions. The names of these functions (minus the leading "gen") # match the substitution keywords in the template files. #=================================================================================== + def testExistPerThreadStats (self, variables): + for inst in self.statistics: + if inst.type.type.perThread: + return True + return False + + def testExistPerThreadAssign (self, variables): + for inst in self.statistics: + if inst.type.type.perThread and inst.assign != None: + return True + return False + + def testExistPerThreadResets (self, variables): + for inst in self.statistics: + if inst.type.type.perThread and inst.type.type.style == "mma": + return True + return False + + def testNoStatistics (self, variables): + return len (self.statistics) == 0 + def genAccessorMethods (self, stream, variables): for config in self.properties: if config.access != "RC": config.genAccessor (stream) for inst in self.statistics: - inst.genAccessor (stream) + if inst.assign == None: + inst.genAccessor (stream) def genConfigCount (self, stream, variables): stream.write ("%d" % len (self.properties)) @@ -767,16 +835,33 @@ class SchemaClass: def genHiLoStatResets (self, stream, variables): for inst in self.statistics: - inst.genHiLoStatResets (stream) + if not inst.type.type.perThread: + inst.genHiLoStatResets (stream) + + def genPerThreadHiLoStatResets (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genPerThreadHiLoStatResets (stream) def genInitializeElements (self, stream, variables): for inst in self.statistics: - inst.genInitialize (stream) + if not inst.type.type.perThread: + inst.genInitialize (stream) + + def genInitializePerThreadElements (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genInitialize (stream, "threadStats->", " ") + + def genInitializeTotalPerThreadStats (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genInitializeTotalPerThreadStats (stream) - def genInstChangedStub (self, stream, variables): - if len (self.statistics) == 0: - stream.write (" // Stub for getInstChanged. There are no inst elements\n") - stream.write (" bool getInstChanged (void) { return false; }\n") + def genAggregatePerThreadStats (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genAggregatePerThreadStats (stream) def genInstCount (self, stream, variables): count = 0 @@ -790,7 +875,13 @@ class SchemaClass: def genInstDeclarations (self, stream, variables): for element in self.statistics: - element.genDeclaration (stream) + if not element.type.type.perThread: + element.genDeclaration (stream) + + def genPerThreadDeclarations (self, stream, variables): + for element in self.statistics: + if element.type.type.perThread: + element.genDeclaration (stream, " ") def genInstElementSchema (self, stream, variables): for inst in self.statistics: @@ -884,7 +975,13 @@ class SchemaClass: def genAssign (self, stream, variables): for inst in self.statistics: - inst.genAssign (stream) + if not inst.type.type.perThread: + inst.genAssign (stream) + + def genPerThreadAssign (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genAssign (stream) def genWriteConfig (self, stream, variables): for config in self.properties: diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp index 0fbb78b7f1..1ea1da5090 100644 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -23,6 +23,7 @@ #include "qpid/log/Statement.h" #include "qpid/framing/FieldTable.h" #include "qpid/management/Manageable.h" +#include "qpid/management/ManagementAgent.h" #include "/*MGEN:Class.NameCap*/.h" /*MGEN:Class.MethodArgIncludes*/ @@ -36,15 +37,28 @@ string /*MGEN:Class.NameCap*/::className = string ("/*MGEN:Class.NameLower*/ uint8_t /*MGEN:Class.NameCap*/::md5Sum[16] = {/*MGEN:Class.SchemaMD5*/}; -/*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (Manageable* _core/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/) : - ManagementObject(_core) - /*MGEN:Class.ConstructorInits*/ +/*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (ManagementAgent* _agent, Manageable* _core/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/) : + ManagementObject(_agent, _core)/*MGEN:Class.ConstructorInits*/ { /*MGEN:Class.ParentRefAssignment*/ /*MGEN:Class.InitializeElements*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + maxThreads = agent->getMaxThreads(); + perThreadStatsArray = new struct PerThreadStats*[maxThreads]; + for (int idx = 0; idx < maxThreads; idx++) + perThreadStatsArray[idx] = 0; +/*MGEN:ENDIF*/ } -/*MGEN:Class.NameCap*/::~/*MGEN:Class.NameCap*/ () {} +/*MGEN:Class.NameCap*/::~/*MGEN:Class.NameCap*/ () +{ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + for (int idx = 0; idx < maxThreads; idx++) + if (perThreadStatsArray[idx] != 0) + delete perThreadStatsArray[idx]; + delete perThreadStatsArray; +/*MGEN:ENDIF*/ +} namespace { const string NAME("name"); @@ -85,6 +99,19 @@ void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) /*MGEN:Class.EventSchema*/ } +/*MGEN:IF(Class.ExistPerThreadStats)*/ +void /*MGEN:Class.NameCap*/::aggregatePerThreadStats(struct PerThreadStats* totals) +{ +/*MGEN:Class.InitializeTotalPerThreadStats*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.AggregatePerThreadStats*/ + } + } +} +/*MGEN:ENDIF*/ + void /*MGEN:Class.NameCap*/::writeProperties (Buffer& buf) { sys::Mutex::ScopedLock mutex(accessLock); @@ -98,14 +125,33 @@ void /*MGEN:Class.NameCap*/::writeStatistics (Buffer& buf, bool skipHeaders) { sys::Mutex::ScopedLock mutex(accessLock); instChanged = false; +/*MGEN:IF(Class.ExistPerThreadAssign)*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.PerThreadAssign*/ + } + } +/*MGEN:ENDIF*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + struct PerThreadStats totals; + aggregatePerThreadStats(&totals); +/*MGEN:ENDIF*/ /*MGEN:Class.Assign*/ - if (!skipHeaders) writeTimestamps (buf); /*MGEN:Class.WriteInst*/ // Maintenance of hi-lo statistics /*MGEN:Class.HiLoStatResets*/ +/*MGEN:IF(Class.ExistPerThreadResets)*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.PerThreadHiLoStatResets*/ + } + } +/*MGEN:ENDIF*/ } void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h index aa01f8f105..557c7a45d5 100644 --- a/qpid/cpp/managementgen/templates/Class.h +++ b/qpid/cpp/managementgen/templates/Class.h @@ -26,7 +26,6 @@ #include "qpid/management/ManagementObject.h" #include "qpid/framing/FieldTable.h" #include "qpid/framing/Uuid.h" -#include "qpid/sys/AtomicCount.h" namespace qpid { namespace management { @@ -43,6 +42,27 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject /*MGEN:Class.ConfigDeclarations*/ // Statistics /*MGEN:Class.InstDeclarations*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + // Per-Thread Statistics + struct PerThreadStats { +/*MGEN:Class.PerThreadDeclarations*/ + }; + + struct PerThreadStats** perThreadStatsArray; + + inline struct PerThreadStats* getThreadStats() { + int index = getThreadIndex(); + struct PerThreadStats* threadStats = perThreadStatsArray[index]; + if (threadStats == 0) { + threadStats = new(PerThreadStats); + perThreadStatsArray[index] = threadStats; +/*MGEN:Class.InitializePerThreadElements*/ + } + return threadStats; + } + + void aggregatePerThreadStats(struct PerThreadStats*); +/*MGEN:ENDIF*/ // Private Methods static void writeSchema (qpid::framing::Buffer& buf); void writeProperties (qpid::framing::Buffer& buf); @@ -51,15 +71,18 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject void doMethod (std::string methodName, qpid::framing::Buffer& inBuf, qpid::framing::Buffer& outBuf); - writeSchemaCall_t getWriteSchemaCall (void) { return writeSchema; } - -/*MGEN:Class.InstChangedStub*/ + writeSchemaCall_t getWriteSchemaCall(void) { return writeSchema; } +/*MGEN:IF(Class.NoStatistics)*/ + // Stub for getInstChanged. There are no statistics in this class. + bool getInstChanged (void) { return false; } +/*MGEN:ENDIF*/ public: friend class Package/*MGEN:Class.NamePackageCap*/; typedef boost::shared_ptr shared_ptr; - /*MGEN:Class.NameCap*/ (Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); + /*MGEN:Class.NameCap*/ (ManagementAgent* agent, + Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); ~/*MGEN:Class.NameCap*/ (void); /*MGEN:Class.SetGeneralReferenceDeclaration*/ -- cgit v1.2.1 From e8627f39f81d5105c8afd532da48f2f2b98d86d8 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Thu, 3 Jul 2008 15:49:48 +0000 Subject: QPID-1160 - Use array-style delete for allocated array git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@673718 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/templates/Class.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp index 1ea1da5090..100e306fe0 100644 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -56,7 +56,7 @@ uint8_t /*MGEN:Class.NameCap*/::md5Sum[16] = for (int idx = 0; idx < maxThreads; idx++) if (perThreadStatsArray[idx] != 0) delete perThreadStatsArray[idx]; - delete perThreadStatsArray; + delete[] perThreadStatsArray; /*MGEN:ENDIF*/ } -- cgit v1.2.1 From 79f59f23d5720c20af326d799e47d6a30c15cca9 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Tue, 8 Jul 2008 21:54:20 +0000 Subject: QPID-1170 - Remove boost dependency from management agent interface git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@674994 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/generate.py | 3 ++- qpid/cpp/managementgen/templates/Class.cpp | 2 +- qpid/cpp/managementgen/templates/Class.h | 1 - qpid/cpp/managementgen/templates/Package.cpp | 2 +- qpid/cpp/managementgen/templates/Package.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/generate.py b/qpid/cpp/managementgen/generate.py index 197deec4f1..6024173f67 100755 --- a/qpid/cpp/managementgen/generate.py +++ b/qpid/cpp/managementgen/generate.py @@ -158,7 +158,8 @@ class Generator: raise ValueError ("path is not directory: %s" % path) if not exists: pair = os.path.split (path) - self.createPath (pair[0]) + if pair[0] != '': + self.createPath (pair[0]) os.mkdir (path) def normalize (self, path): diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp index 100e306fe0..289427d742 100644 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -23,7 +23,7 @@ #include "qpid/log/Statement.h" #include "qpid/framing/FieldTable.h" #include "qpid/management/Manageable.h" -#include "qpid/management/ManagementAgent.h" +#include "qpid/agent/ManagementAgent.h" #include "/*MGEN:Class.NameCap*/.h" /*MGEN:Class.MethodArgIncludes*/ diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h index 557c7a45d5..8a4dc1006a 100644 --- a/qpid/cpp/managementgen/templates/Class.h +++ b/qpid/cpp/managementgen/templates/Class.h @@ -79,7 +79,6 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject public: friend class Package/*MGEN:Class.NamePackageCap*/; - typedef boost::shared_ptr shared_ptr; /*MGEN:Class.NameCap*/ (ManagementAgent* agent, Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); diff --git a/qpid/cpp/managementgen/templates/Package.cpp b/qpid/cpp/managementgen/templates/Package.cpp index 0c5af8d71d..8bb2d42c47 100644 --- a/qpid/cpp/managementgen/templates/Package.cpp +++ b/qpid/cpp/managementgen/templates/Package.cpp @@ -25,7 +25,7 @@ using namespace qpid::management; -Package/*MGEN:Schema.PackageNameCap*/::Package/*MGEN:Schema.PackageNameCap*/ (ManagementAgent::shared_ptr agent) +Package/*MGEN:Schema.PackageNameCap*/::Package/*MGEN:Schema.PackageNameCap*/ (ManagementAgent* agent) { /*MGEN:Schema.ClassRegisters*/ } diff --git a/qpid/cpp/managementgen/templates/Package.h b/qpid/cpp/managementgen/templates/Package.h index 214f811a1f..3f3ac35ffc 100644 --- a/qpid/cpp/managementgen/templates/Package.h +++ b/qpid/cpp/managementgen/templates/Package.h @@ -23,7 +23,7 @@ /*MGEN:Root.Disclaimer*/ -#include "qpid/management/ManagementAgent.h" +#include "qpid/agent/ManagementAgent.h" namespace qpid { namespace management { @@ -31,7 +31,7 @@ namespace management { class Package/*MGEN:Schema.PackageNameCap*/ { public: - Package/*MGEN:Schema.PackageNameCap*/ (ManagementAgent::shared_ptr agent); + Package/*MGEN:Schema.PackageNameCap*/ (ManagementAgent* agent); ~Package/*MGEN:Schema.PackageNameCap*/ () {} }; -- cgit v1.2.1 From 2ebe3bcb668151cfd9a860e4416fe4478d9a56f4 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Fri, 11 Jul 2008 20:14:07 +0000 Subject: QPID-1174 Remote Management Agent for management of external components git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@676067 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/main.py | 6 ------ qpid/cpp/managementgen/schema.py | 5 ++--- qpid/cpp/managementgen/templates/Package.cpp | 2 +- 3 files changed, 3 insertions(+), 10 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/main.py b/qpid/cpp/managementgen/main.py index 87ef3d5298..4459177a53 100755 --- a/qpid/cpp/managementgen/main.py +++ b/qpid/cpp/managementgen/main.py @@ -28,9 +28,6 @@ usage = "usage: %prog [options] schema-document type-document template-director parser = OptionParser (usage=usage) parser.add_option ("-m", "--makefile", dest="makefile", metavar="FILE", help="Makefile fragment") -parser.add_option ("-i", "--include-prefix", dest="include_prefix", metavar="PATH", - default="qpid/management/", - help="Prefix for #include of generated headers in generated source, default: qpid/management/") (opts, args) = parser.parse_args () @@ -42,9 +39,6 @@ typefile = args[1] templatedir = args[2] outdir = args[3] -if opts.include_prefix == ".": - opts.include_prefix = None - gen = Generator (outdir, templatedir) schema = PackageSchema (typefile, schemafile, opts) diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index 4f5dc216ab..921c1bf01f 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -890,8 +890,7 @@ class SchemaClass: def genMethodArgIncludes (self, stream, variables): for method in self.methods: if method.getArgCount () > 0: - stream.write ("#include \"" + (self.options.include_prefix or "") +\ - "Args" + method.getFullName () + ".h\"\n") + stream.write ("#include \"Args" + method.getFullName () + ".h\"\n") def genMethodCount (self, stream, variables): stream.write ("%d" % len (self.methods)) @@ -1040,7 +1039,7 @@ class PackageSchema: def genClassIncludes (self, stream, variables): for _class in self.classes: - stream.write ("#include \"qpid/management/") + stream.write ("#include \"") _class.genNameCap (stream, variables) stream.write (".h\"\n") diff --git a/qpid/cpp/managementgen/templates/Package.cpp b/qpid/cpp/managementgen/templates/Package.cpp index 8bb2d42c47..15e7fc15ec 100644 --- a/qpid/cpp/managementgen/templates/Package.cpp +++ b/qpid/cpp/managementgen/templates/Package.cpp @@ -20,7 +20,7 @@ /*MGEN:Root.Disclaimer*/ -#include "qpid/management/Package/*MGEN:Schema.PackageNameCap*/.h" +#include "Package/*MGEN:Schema.PackageNameCap*/.h" /*MGEN:Schema.ClassIncludes*/ using namespace qpid::management; -- cgit v1.2.1 From f0ec46f9a3faffe3d44cb793dcf85751ed2eadf5 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Tue, 29 Jul 2008 18:31:25 +0000 Subject: QPID-1153 - Patch from Steve Huston git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@680798 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/schema.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index 921c1bf01f..eb0b066b62 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -136,15 +136,15 @@ class SchemaType: if self.style == "mma": stream.write (" " + varName + "Count = 0;\n") stream.write (" " + varName + "Total = 0;\n") - stream.write (" " + varName + "Min = -1;\n") - stream.write (" " + varName + "Max = 0;\n") + stream.write (" " + varName + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") + stream.write (" " + varName + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") - def genPerThreadHiLoStatResets (self, stream, varName): + def genPerThreadHiLoStatResets (self, stream, varName, cpptype): if self.style == "mma": stream.write (" threadStats->" + varName + "Count = 0;\n") stream.write (" threadStats->" + varName + "Total = 0;\n") - stream.write (" threadStats->" + varName + "Min = -1;\n") - stream.write (" threadStats->" + varName + "Max = 0;\n") + stream.write (" threadStats->" + varName + "Min = std::numeric_limits<" + cpptype + ">::max();\n") + stream.write (" threadStats->" + varName + "Max = std::numeric_limits<" + cpptype + ">::min();\n") def genWrite (self, stream, varName): if self.style != "mma": @@ -377,7 +377,7 @@ class SchemaInst: self.type.type.genHiLoStatResets (stream, self.name) def genPerThreadHiLoStatResets (self, stream): - self.type.type.genPerThreadHiLoStatResets (stream, self.name) + self.type.type.genPerThreadHiLoStatResets (stream, self.name, self.type.type.cpp) def genSchemaText (self, stream, name, desc): stream.write (" ft = FieldTable ();\n") @@ -439,15 +439,15 @@ class SchemaInst: stream.write (indent + prefix + self.name + "Low = " + val + ";\n") if self.type.type.style == "mma": stream.write (indent + prefix + self.name + "Count = 0;\n") - stream.write (indent + prefix + self.name + "Min = -1;\n") - stream.write (indent + prefix + self.name + "Max = 0;\n") + stream.write (indent + prefix + self.name + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") + stream.write (indent + prefix + self.name + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") stream.write (indent + prefix + self.name + "Total = 0;\n") def genInitializeTotalPerThreadStats (self, stream): if self.type.type.style == "mma": stream.write (" totals->" + self.name + "Count = 0;\n") - stream.write (" totals->" + self.name + "Min = -1;\n") - stream.write (" totals->" + self.name + "Max = 0;\n") + stream.write (" totals->" + self.name + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") + stream.write (" totals->" + self.name + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") stream.write (" totals->" + self.name + "Total = 0;\n") else: stream.write (" totals->" + self.name + " = 0;\n") -- cgit v1.2.1 From 12b33f499c8a33d5010fedecdb267c721483f0a5 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Thu, 31 Jul 2008 13:15:16 +0000 Subject: QPID-1174 - Management updates for remote agents git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@681362 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/schema.py | 6 +++--- qpid/cpp/managementgen/templates/Class.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index eb0b066b62..25284a14f7 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -577,7 +577,7 @@ class SchemaMethod: return self.name def getFullName (self): - return self.parent.getName().capitalize() + self.name[0:1].upper() +\ + return capitalize(self.parent.getName()) + self.name[0:1].upper() +\ self.name[1:] def getArgCount (self): @@ -644,7 +644,7 @@ class SchemaEvent: return self.name def getFullName (self): - return self.parent.getName ().capitalize() + self.name.capitalize () + return capitalize(self.parent.getName()) + capitalize(self.name) def getArgCount (self): return len (self.args) @@ -938,7 +938,7 @@ class SchemaClass: method.genSchema (stream, variables) def genNameCap (self, stream, variables): - stream.write (self.name.capitalize ()) + stream.write (capitalize(self.name)) def genNameLower (self, stream, variables): stream.write (self.name.lower ()) diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h index 8a4dc1006a..fac63d5d55 100644 --- a/qpid/cpp/managementgen/templates/Class.h +++ b/qpid/cpp/managementgen/templates/Class.h @@ -86,9 +86,9 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject /*MGEN:Class.SetGeneralReferenceDeclaration*/ - std::string getPackageName (void) { return packageName; } - std::string getClassName (void) { return className; } - uint8_t* getMd5Sum (void) { return md5Sum; } + std::string& getPackageName (void) { return packageName; } + std::string& getClassName (void) { return className; } + uint8_t* getMd5Sum (void) { return md5Sum; } // Method IDs /*MGEN:Class.MethodIdDeclarations*/ -- cgit v1.2.1 From 3da7d2425e3921d47edba4ad413ee6859678b4ed Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Fri, 1 Aug 2008 14:41:49 +0000 Subject: Make md5-hash of table recursively include data from referenced groups git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@681709 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/schema.py | 1 + 1 file changed, 1 insertion(+) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index 25284a14f7..2ee61fff80 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -727,6 +727,7 @@ class SchemaClass: name = attrs['name'].nodeValue for fragment in fragments: if fragment.name == name: + self.md5Sum.update (fragment.md5Sum.digest()) for config in fragment.properties: self.properties.append (config) for inst in fragment.statistics: -- cgit v1.2.1 From bf45f1241b9f801b55ede16d77c3dbbe505f0f89 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 3 Sep 2008 18:01:44 +0000 Subject: QPID-1174 Updates to the management framework git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@691700 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/schema.py | 229 +++++++++++++++++++++-------- qpid/cpp/managementgen/templates/Class.cpp | 24 ++- qpid/cpp/managementgen/templates/Class.h | 9 +- 3 files changed, 196 insertions(+), 66 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index 2ee61fff80..f911c28db3 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -79,7 +79,7 @@ class SchemaType: def getName (self): return self.name - def genAccessor (self, stream, varName, changeFlag = None): + def genAccessor (self, stream, varName, changeFlag = None, optional = False): if self.perThread: prefix = "getThreadStats()->" if self.style == "wm": @@ -87,11 +87,13 @@ class SchemaType: else: prefix = "" if self.accessor == "direct": - stream.write (" inline void set_" + varName + " (" + self.cpp + " val){\n"); + stream.write (" inline void set_" + varName + " (" + self.cpp + " val) {\n"); if not self.perThread: stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") if self.style != "mma": - stream.write (" " + prefix + varName + " = val;\n"); + stream.write (" " + prefix + varName + " = val;\n") + if optional: + stream.write (" presenceMask[presenceByte_%s] |= presenceMask_%s;\n" % (varName, varName)) if self.style == "wm": stream.write (" if (" + varName + "Low > val)\n") stream.write (" " + varName + "Low = val;\n") @@ -106,9 +108,24 @@ class SchemaType: stream.write (" " + prefix + varName + "Max = val;\n") if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") - stream.write (" }\n"); + stream.write (" }\n") + if self.style != "mma": + stream.write (" inline " + self.cpp + "& get_" + varName + "() {\n"); + if not self.perThread: + stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" return " + prefix + varName + ";\n") + stream.write (" }\n") + if optional: + stream.write (" inline void clr_" + varName + "() {\n") + stream.write (" presenceMask[presenceByte_%s] &= ~presenceMask_%s;\n" % (varName, varName)) + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n") + stream.write (" inline bool isSet_" + varName + "() {\n") + stream.write (" return presenceMask[presenceByte_%s] & presenceMask_%s != 0;\n" % (varName, varName)) + stream.write (" }\n") elif self.accessor == "counter": - stream.write (" inline void inc_" + varName + " (" + self.cpp + " by = 1){\n"); + stream.write (" inline void inc_" + varName + " (" + self.cpp + " by = 1) {\n"); if not self.perThread: stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") stream.write (" " + prefix + varName + " += by;\n") @@ -118,7 +135,7 @@ class SchemaType: if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n"); - stream.write (" inline void dec_" + varName + " (" + self.cpp + " by = 1){\n"); + stream.write (" inline void dec_" + varName + " (" + self.cpp + " by = 1) {\n"); if not self.perThread: stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") stream.write (" " + prefix + varName + " -= by;\n") @@ -146,22 +163,22 @@ class SchemaType: stream.write (" threadStats->" + varName + "Min = std::numeric_limits<" + cpptype + ">::max();\n") stream.write (" threadStats->" + varName + "Max = std::numeric_limits<" + cpptype + ">::min();\n") - def genWrite (self, stream, varName): + def genWrite (self, stream, varName, indent=" "): if self.style != "mma": - stream.write (" " + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") + stream.write (indent + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") if self.style == "wm": - stream.write (" " + self.encode.replace ("@", "buf") \ + stream.write (indent + self.encode.replace ("@", "buf") \ .replace ("#", varName + "High") + ";\n") - stream.write (" " + self.encode.replace ("@", "buf") \ + stream.write (indent + self.encode.replace ("@", "buf") \ .replace ("#", varName + "Low") + ";\n") if self.style == "mma": - stream.write (" " + self.encode.replace ("@", "buf") \ + stream.write (indent + self.encode.replace ("@", "buf") \ .replace ("#", varName + "Count") + ";\n") - stream.write (" " + self.encode.replace ("@", "buf") \ + stream.write (indent + self.encode.replace ("@", "buf") \ .replace ("#", varName + "Count ? " + varName + "Min : 0") + ";\n") - stream.write (" " + self.encode.replace ("@", "buf") \ + stream.write (indent + self.encode.replace ("@", "buf") \ .replace ("#", varName + "Max") + ";\n") - stream.write (" " + self.encode.replace ("@", "buf") \ + stream.write (indent + self.encode.replace ("@", "buf") \ .replace ("#", varName + "Count ? " + varName + "Total / " + varName + "Count : 0") + ";\n") @@ -207,7 +224,7 @@ class Type: #===================================================================================== # #===================================================================================== -class SchemaConfig: +class SchemaProperty: def __init__ (self, node, typespec): self.name = None self.type = None @@ -216,6 +233,7 @@ class SchemaConfig: self.isIndex = 0 self.isParentRef = 0 self.isGeneralRef = 0 + self.isOptional = 0 self.unit = None self.min = None self.max = None @@ -255,6 +273,11 @@ class SchemaConfig: raise ValueError ("Expected 'y' in isGeneralReference attribute") self.isGeneralRef = 1 + elif key == 'optional': + if val != 'y': + raise ValueError ("Expected 'y' in optional attribute") + self.isOptional = 1 + elif key == 'unit': self.unit = val @@ -273,6 +296,9 @@ class SchemaConfig: else: raise ValueError ("Unknown attribute in property '%s'" % key) + if self.access == "RC" and self.isOptional == 1: + raise ValueError ("Properties with ReadCreate access must not be optional (%s)" % self.name) + if self.name == None: raise ValueError ("Missing 'name' attribute in property") if self.type == None: @@ -289,18 +315,19 @@ class SchemaConfig: def genDeclaration (self, stream, prefix=" "): stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") - def genFormalParam (self, stream): + def genFormalParam (self, stream, variables): stream.write (self.type.type.cpp + " _" + self.name) def genAccessor (self, stream): - self.type.type.genAccessor (stream, self.name, "configChanged") + self.type.type.genAccessor (stream, self.name, "configChanged", self.isOptional == 1) def genSchema (self, stream): stream.write (" ft = FieldTable ();\n") - stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") - stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") + stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") stream.write (" ft.setInt (ACCESS, ACCESS_" + self.access + ");\n") - stream.write (" ft.setInt (INDEX, " + str (self.isIndex) + ");\n") + stream.write (" ft.setInt (INDEX, " + str (self.isIndex) + ");\n") + stream.write (" ft.setInt (OPTIONAL, " + str (self.isOptional) + ");\n") if self.unit != None: stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") if self.min != None: @@ -314,13 +341,19 @@ class SchemaConfig: stream.write (" buf.put (ft);\n\n") def genWrite (self, stream): - self.type.type.genWrite (stream, self.name) + indent = " " + if self.isOptional: + stream.write(" if (presenceMask[presenceByte_%s] & presenceMask_%s) {\n" % (self.name, self.name)) + indent = " " + self.type.type.genWrite (stream, self.name, indent) + if self.isOptional: + stream.write(" }\n") #===================================================================================== # #===================================================================================== -class SchemaInst: +class SchemaStatistic: def __init__ (self, node, typespec): self.name = None self.type = None @@ -523,25 +556,30 @@ class SchemaArg: def getDir (self): return self.dir - def genSchema (self, stream): + def genSchema (self, stream, event=False): stream.write (" ft = FieldTable ();\n") stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") - stream.write (" ft.setString (DIR, \"" + self.dir + "\");\n") + if (not event): + stream.write (" ft.setString (DIR, \"" + self.dir + "\");\n") if self.unit != None: stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") - if self.min != None: - stream.write (" ft.setInt (MIN, " + self.min + ");\n") - if self.max != None: - stream.write (" ft.setInt (MAX, " + self.max + ");\n") - if self.maxLen != None: - stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") + if not event: + if self.min != None: + stream.write (" ft.setInt (MIN, " + self.min + ");\n") + if self.max != None: + stream.write (" ft.setInt (MAX, " + self.max + ");\n") + if self.maxLen != None: + stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") + if self.default != None: + stream.write (" ft.setString (DEFAULT, \"" + self.default + "\");\n") if self.desc != None: stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") - if self.default != None: - stream.write (" ft.setString (DEFAULT, \"" + self.default + "\");\n") stream.write (" buf.put (ft);\n\n") + def genFormalParam (self, stream, variables): + stream.write ("%s _%s" % (self.type.type.cpp, self.name)) + #===================================================================================== # #===================================================================================== @@ -649,6 +687,50 @@ class SchemaEvent: def getArgCount (self): return len (self.args) + def genMethodBody (self, stream, variables, classObject): + stream.write("void ") + classObject.genNameCap(stream, variables) + stream.write("::event_%s(" % self.name) + count = 0 + for arg in self.args: + arg.genFormalParam(stream, variables) + count += 1 + if count < len(self.args): + stream.write(", ") + stream.write(") {\n") + stream.write(" sys::Mutex::ScopedLock mutex(getMutex());\n") + stream.write(" Buffer* buf = startEventLH();\n") + stream.write(" objectId.encode(*buf);\n") + stream.write(" buf->putShortString(packageName);\n") + stream.write(" buf->putShortString(className);\n") + stream.write(" buf->putBin128(md5Sum);\n") + stream.write(" buf->putShortString(\"%s\");\n" % self.name) + for arg in self.args: + stream.write(" %s;\n" % arg.type.type.encode.replace("@", "(*buf)").replace("#", "_" + arg.name)) + stream.write(" finishEventLH(buf);\n") + stream.write("}\n\n") + + def genMethodDecl (self, stream, variables): + stream.write(" void event_%s(" % self.name) + count = 0 + for arg in self.args: + arg.genFormalParam(stream, variables) + count += 1 + if count < len(self.args): + stream.write(", ") + stream.write(");\n") + + 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") + if self.desc != None: + stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + for arg in self.args: + arg.genSchema (stream, True) + + class SchemaClass: def __init__ (self, package, node, typespec, fragments, options): @@ -669,11 +751,11 @@ class SchemaClass: for child in children: if child.nodeType == Node.ELEMENT_NODE: if child.nodeName == 'property': - sub = SchemaConfig (child, typespec) + sub = SchemaProperty (child, typespec) self.properties.append (sub) elif child.nodeName == 'statistic': - sub = SchemaInst (child, typespec) + sub = SchemaStatistic (child, typespec) self.statistics.append (sub) elif child.nodeName == 'method': @@ -758,6 +840,12 @@ class SchemaClass: # Code Generation Functions. The names of these functions (minus the leading "gen") # match the substitution keywords in the template files. #=================================================================================== + def testExistOptionals (self, variables): + for prop in self.properties: + if prop.isOptional == 1: + return True + return False + def testExistPerThreadStats (self, variables): for inst in self.statistics: if inst.type.type.perThread: @@ -794,17 +882,13 @@ class SchemaClass: for element in self.properties: element.genDeclaration (stream) - def genConfigElementSchema (self, stream, variables): - for config in self.properties: - config.genSchema (stream) - def genConstructorArgs (self, stream, variables): # Constructor args are config elements with read-create access result = "" for element in self.properties: if element.isConstructorArg (): stream.write (", ") - element.genFormalParam (stream) + element.genFormalParam (stream, variables) def genConstructorInits (self, stream, variables): for element in self.properties: @@ -831,8 +915,17 @@ class SchemaClass: def genEventCount (self, stream, variables): stream.write ("%d" % len (self.events)) + def genEventMethodBodies (self, stream, variables): + for event in self.events: + event.genMethodBody (stream, variables, self) + + def genEventMethodDecls (self, stream, variables): + for event in self.events: + event.genMethodDecl (stream, variables) + def genEventSchema (self, stream, variables): - pass ########################################################################### + for event in self.events: + event.genSchema (stream, variables) def genHiLoStatResets (self, stream, variables): for inst in self.statistics: @@ -884,10 +977,6 @@ class SchemaClass: if element.type.type.perThread: element.genDeclaration (stream, " ") - def genInstElementSchema (self, stream, variables): - for inst in self.statistics: - inst.genSchema (stream) - def genMethodArgIncludes (self, stream, variables): for method in self.methods: if method.getArgCount () > 0: @@ -898,7 +987,7 @@ class SchemaClass: def genMethodHandlers (self, stream, variables): for method in self.methods: - stream.write ("\n if (methodName == \"" + method.getName () + "\")\n {\n") + stream.write ("\n if (methodName == \"" + method.getName () + "\") {\n") if method.getArgCount () == 0: stream.write (" ArgsNone ioArgs;\n") else: @@ -922,10 +1011,36 @@ class SchemaClass: arg.name, "outBuf") + ";\n") stream.write (" return;\n }\n") + def genPresenceMaskBytes (self, stream, variables): + count = 0 + for prop in self.properties: + if prop.isOptional == 1: + count += 1 + if count == 0: + stream.write("0") + else: + stream.write (str(((count - 1) / 8) + 1)) + + def genPresenceMaskConstants (self, stream, variables): + count = 0 + for prop in self.properties: + if prop.isOptional == 1: + stream.write(" static const uint8_t presenceByte_%s = %d;\n" % (prop.name, count / 8)) + stream.write(" static const uint8_t presenceMask_%s = %d;\n" % (prop.name, 1 << (count % 8))) + count += 1 + + def genPropertySchema (self, stream, variables): + for prop in self.properties: + prop.genSchema (stream) + def genSetGeneralReferenceDeclaration (self, stream, variables): for prop in self.properties: if prop.isGeneralRef: - stream.write ("void setReference(uint64_t objectId) { " + prop.name + " = objectId; }\n") + stream.write ("void setReference(ObjectId objectId) { " + prop.name + " = objectId; }\n") + + def genStatisticSchema (self, stream, variables): + for stat in self.statistics: + stat.genSchema (stream) def genMethodIdDeclarations (self, stream, variables): number = 1 @@ -983,13 +1098,13 @@ class SchemaClass: if inst.type.type.perThread: inst.genAssign (stream) - def genWriteConfig (self, stream, variables): - for config in self.properties: - config.genWrite (stream) + def genWriteProperties (self, stream, variables): + for prop in self.properties: + prop.genWrite (stream) - def genWriteInst (self, stream, variables): - for inst in self.statistics: - inst.genWrite (stream) + def genWriteStatistics (self, stream, variables): + for stat in self.statistics: + stat.genWrite (stream) @@ -1046,15 +1161,9 @@ class PackageSchema: def genClassRegisters (self, stream, variables): for _class in self.classes: - stream.write ("agent->RegisterClass (") - _class.genNameCap (stream, variables) - stream.write ("::packageName, ") - _class.genNameCap (stream, variables) - stream.write ("::className, ") - _class.genNameCap (stream, variables) - stream.write ("::md5Sum, ") + stream.write (" ") _class.genNameCap (stream, variables) - stream.write ("::writeSchema);\n") + stream.write ("::registerClass(agent);\n") #===================================================================================== diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp index 289427d742..2a0e55b34d 100644 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -42,6 +42,11 @@ uint8_t /*MGEN:Class.NameCap*/::md5Sum[16] = { /*MGEN:Class.ParentRefAssignment*/ /*MGEN:Class.InitializeElements*/ +/*MGEN:IF(Class.ExistOptionals)*/ + // Optional properties start out not-present + for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) + presenceMask[idx] = 0; +/*MGEN:ENDIF*/ /*MGEN:IF(Class.ExistPerThreadStats)*/ maxThreads = agent->getMaxThreads(); perThreadStatsArray = new struct PerThreadStats*[maxThreads]; @@ -65,6 +70,7 @@ namespace { const string TYPE("type"); const string ACCESS("access"); const string INDEX("index"); + const string OPTIONAL("optional"); const string UNIT("unit"); const string MIN("min"); const string MAX("max"); @@ -76,6 +82,11 @@ namespace { const string DEFAULT("default"); } +void /*MGEN:Class.NameCap*/::registerClass(ManagementAgent* agent) +{ + agent->RegisterClass(packageName, className, md5Sum, writeSchema); +} + void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) { FieldTable ft; @@ -90,9 +101,9 @@ void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) buf.putShort (/*MGEN:Class.EventCount*/); // Event Count // Properties -/*MGEN:Class.ConfigElementSchema*/ +/*MGEN:Class.PropertySchema*/ // Statistics -/*MGEN:Class.InstElementSchema*/ +/*MGEN:Class.StatisticSchema*/ // Methods /*MGEN:Class.MethodSchema*/ // Events @@ -118,7 +129,11 @@ void /*MGEN:Class.NameCap*/::writeProperties (Buffer& buf) configChanged = false; writeTimestamps (buf); -/*MGEN:Class.WriteConfig*/ +/*MGEN:IF(Class.ExistOptionals)*/ + for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) + buf.putOctet(presenceMask[idx]); +/*MGEN:ENDIF*/ +/*MGEN:Class.WriteProperties*/ } void /*MGEN:Class.NameCap*/::writeStatistics (Buffer& buf, bool skipHeaders) @@ -140,7 +155,7 @@ void /*MGEN:Class.NameCap*/::writeStatistics (Buffer& buf, bool skipHeaders) /*MGEN:Class.Assign*/ if (!skipHeaders) writeTimestamps (buf); -/*MGEN:Class.WriteInst*/ +/*MGEN:Class.WriteStatistics*/ // Maintenance of hi-lo statistics /*MGEN:Class.HiLoStatResets*/ @@ -162,3 +177,4 @@ void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) outBuf.putShortString (Manageable::StatusText (status)); } +/*MGEN:Class.EventMethodBodies*/ diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h index fac63d5d55..40ad20eb85 100644 --- a/qpid/cpp/managementgen/templates/Class.h +++ b/qpid/cpp/managementgen/templates/Class.h @@ -37,6 +37,10 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject static std::string packageName; static std::string className; static uint8_t md5Sum[16]; +/*MGEN:IF(Class.ExistOptionals)*/ + uint8_t presenceMask[/*MGEN:Class.PresenceMaskBytes*/]; +/*MGEN:Class.PresenceMaskConstants*/ +/*MGEN:ENDIF*/ // Properties /*MGEN:Class.ConfigDeclarations*/ @@ -78,14 +82,13 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject /*MGEN:ENDIF*/ public: - friend class Package/*MGEN:Class.NamePackageCap*/; - /*MGEN:Class.NameCap*/ (ManagementAgent* agent, Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); ~/*MGEN:Class.NameCap*/ (void); /*MGEN:Class.SetGeneralReferenceDeclaration*/ + static void registerClass (ManagementAgent* agent); std::string& getPackageName (void) { return packageName; } std::string& getClassName (void) { return className; } uint8_t* getMd5Sum (void) { return md5Sum; } @@ -94,6 +97,8 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject /*MGEN:Class.MethodIdDeclarations*/ // Accessor Methods /*MGEN:Class.AccessorMethods*/ + // Event Methods +/*MGEN:Class.EventMethodDecls*/ }; }} -- cgit v1.2.1 From f5aaf06e18515bd2274bff7f69aac6a33e8161e0 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 3 Sep 2008 20:10:45 +0000 Subject: Disambiguated a mask-and-compare for the Fedora-9 compiler git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@691755 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py index f911c28db3..e666bdbb39 100755 --- a/qpid/cpp/managementgen/schema.py +++ b/qpid/cpp/managementgen/schema.py @@ -122,7 +122,7 @@ class SchemaType: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n") stream.write (" inline bool isSet_" + varName + "() {\n") - stream.write (" return presenceMask[presenceByte_%s] & presenceMask_%s != 0;\n" % (varName, varName)) + stream.write (" return (presenceMask[presenceByte_%s] & presenceMask_%s) != 0;\n" % (varName, varName)) stream.write (" }\n") elif self.accessor == "counter": stream.write (" inline void inc_" + varName + " (" + self.cpp + " by = 1) {\n"); -- cgit v1.2.1 From 67cb9d3c75bada36fae0086a04b6b1e9fc92459f Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Fri, 5 Sep 2008 14:11:23 +0000 Subject: QPID-1274 - Improved packaging for management agent and code generation tool git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@692450 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/Makefile.am | 29 +- qpid/cpp/managementgen/generate.py | 300 ------- qpid/cpp/managementgen/main.py | 52 -- qpid/cpp/managementgen/management-types.xml | 56 ++ qpid/cpp/managementgen/managementgen | 26 - qpid/cpp/managementgen/qmf-gen | 60 ++ qpid/cpp/managementgen/qmf/__init__.py | 19 + qpid/cpp/managementgen/qmf/generate.py | 300 +++++++ qpid/cpp/managementgen/qmf/schema.py | 1208 +++++++++++++++++++++++++++ qpid/cpp/managementgen/schema.py | 1208 --------------------------- 10 files changed, 1653 insertions(+), 1605 deletions(-) delete mode 100755 qpid/cpp/managementgen/generate.py delete mode 100755 qpid/cpp/managementgen/main.py create mode 100644 qpid/cpp/managementgen/management-types.xml delete mode 100644 qpid/cpp/managementgen/managementgen create mode 100755 qpid/cpp/managementgen/qmf-gen create mode 100644 qpid/cpp/managementgen/qmf/__init__.py create mode 100755 qpid/cpp/managementgen/qmf/generate.py create mode 100755 qpid/cpp/managementgen/qmf/schema.py delete mode 100755 qpid/cpp/managementgen/schema.py (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am index 993eeb1d20..7a415b4be6 100644 --- a/qpid/cpp/managementgen/Makefile.am +++ b/qpid/cpp/managementgen/Makefile.am @@ -1,8 +1,8 @@ -managementgendir = $(datadir)/managementgen -dist_managementgen_SCRIPTS = \ - main.py -nobase_managementgen_DATA = \ - schema.py generate.py \ +qmfdatadir = $(datadir)/qmf +qmfpythondir = $(pythondir) +dist_bin_SCRIPTS = \ + qmf-gen +nobase_qmfdata_DATA = \ templates/Args.h \ templates/Class.cpp \ templates/Class.h \ @@ -10,18 +10,9 @@ nobase_managementgen_DATA = \ templates/Package.cpp \ templates/Package.h \ management-types.xml +nobase_qmfpython_DATA = \ + qmf/__init__.py \ + qmf/generate.py \ + qmf/schema.py -dist_bin_SCRIPTS = managementgen - -EXTRA_DIST = $(nobase_managementgen_DATA) - -# This should depend on ../../specs/management-types.xml, but can't -# because it won't exist in a dist. This rule means that dist-gzip -# (and rpmbuild) cannot be run purely on the cpp/ directory, the -# cpp/../specs/ directory must exist, which is not a new dependency -# but this is an additional instance of the dependency. -# -# WARNING: Because this target does not have a proper dependency -# changes to the specs/management-types.xml will not be picked up! -management-types.xml: - cp $(top_srcdir)/../specs/management-types.xml . +EXTRA_DIST = $(nobase_qmfdata_DATA) $(nobase_qmfpython_DATA) diff --git a/qpid/cpp/managementgen/generate.py b/qpid/cpp/managementgen/generate.py deleted file mode 100755 index 6024173f67..0000000000 --- a/qpid/cpp/managementgen/generate.py +++ /dev/null @@ -1,300 +0,0 @@ -# -# 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: - """ - 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), - checking conditions (testCondition), and expanding tags (substHandler). - """ - def __init__ (self, filename, handler): - self.filename = filename - self.handler = handler - self.handler.initExpansion () - self.writing = True - - def expandLine (self, line, stream, object): - cursor = 0 - while 1: - sub = line.find ("/*MGEN:", cursor) - if sub == -1: - if self.writing: - stream.write (line[cursor:len (line)]) - return - - subend = line.find("*/", sub) - if self.writing: - stream.write (line[cursor:sub]) - cursor = subend + 2 - - tag = line[sub:subend] - - if tag[7:10] == "IF(": - close = tag.find(")") - if close == -1: - raise ValueError ("Missing ')' on condition") - cond = tag[10:close] - dotPos = cond.find (".") - if dotPos == -1: - raise ValueError ("Invalid condition tag: %s" % cond) - tagObject = cond[0:dotPos] - tagName = cond[dotPos + 1 : len(cond)] - if not self.handler.testCondition(object, tagObject, tagName): - self.writing = False - - elif tag[7:12] == "ENDIF": - self.writing = True - - else: - 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)] - if self.writing: - self.handler.substHandler (object, stream, tagObject, tagName) - else: - tagKey = tag[7:equalPos] - tagVal = tag[equalPos + 1:len (tag)] - if self.writing: - 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: - 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) - if pair[0] != '': - 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 = [] - self.variables = {} - - 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 (".") - 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 targetPackageFile (self, schema, templateFile): - dot = templateFile.find(".") - if dot == -1: - raise ValueError ("Invalid template file name %s" % templateFile) - extension = templateFile[dot:len (templateFile)] - path = self.dest + "Package" + schema.getPackageNameCap() + extension - return path - - 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.getNameCap () + 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 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, self.variables)" - eval (call) - - def testCondition (self, object, tagObject, tag): - if tagObject == "Root": - obj = "self" - else: - obj = "object" # MUST be the same as the 2nd formal parameter - - call = obj + ".test" + tag + "(self.variables)" - return eval (call) - - 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) - self.templateFiles.append (templateFile) - for _class in classes: - target = self.targetClassFile (_class, templateFile) - stream = template.expand (_class) - self.writeIfChanged (stream, target, force) - - def makeMethodFiles (self, templateFile, schema, force=False): - """ Generate an expanded template per method-with-arguments """ - classes = schema.getClasses () - template = Template (self.input + templateFile, self) - 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, force) - - def makePackageFile (self, templateFile, schema, force=False): - """ Generate a package-specific file """ - template = Template (self.input + templateFile, self) - self.templateFiles.append (templateFile) - target = self.targetPackageFile (schema, templateFile) - stream = template.expand (schema) - self.writeIfChanged (stream, target, force) - - 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/qpid/cpp/managementgen/main.py b/qpid/cpp/managementgen/main.py deleted file mode 100755 index 4459177a53..0000000000 --- a/qpid/cpp/managementgen/main.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/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 schema import PackageSchema, SchemaClass -from generate import Generator -from optparse import OptionParser - -# Set command line options -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 len (args) < 4: - parser.error ("Too few arguments") - -schemafile = args[0] -typefile = args[1] -templatedir = args[2] -outdir = args[3] - -gen = Generator (outdir, templatedir) -schema = PackageSchema (typefile, schemafile, opts) - -gen.makeClassFiles ("Class.h", schema) -gen.makeClassFiles ("Class.cpp", schema) -gen.makeMethodFiles ("Args.h", schema) -gen.makePackageFile ("Package.h", schema) -gen.makePackageFile ("Package.cpp", schema) - -if opts.makefile != None: - gen.makeSingleFile ("Makefile.mk", opts.makefile, force=True) diff --git a/qpid/cpp/managementgen/management-types.xml b/qpid/cpp/managementgen/management-types.xml new file mode 100644 index 0000000000..31337b23bc --- /dev/null +++ b/qpid/cpp/managementgen/management-types.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/qpid/cpp/managementgen/managementgen b/qpid/cpp/managementgen/managementgen deleted file mode 100644 index 55ea846270..0000000000 --- a/qpid/cpp/managementgen/managementgen +++ /dev/null @@ -1,26 +0,0 @@ -#!/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. -# - -import sys - -sys.path.append("/usr/share/managementgen") - -import main diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen new file mode 100755 index 0000000000..a29a4074fd --- /dev/null +++ b/qpid/cpp/managementgen/qmf-gen @@ -0,0 +1,60 @@ +#!/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. +# +import sys +import os +from qmf.schema import PackageSchema, SchemaClass +from qmf.generate import Generator +from optparse import OptionParser + +dataPath = os.path.dirname(sys.argv[0]) + +# Set command line options +usage = "usage: %prog [options] schema-document out-directory" +parser = OptionParser (usage=usage) +parser.add_option ("-m", "--makefile", dest="makefile", metavar="FILE", + help="Makefile fragment") +parser.add_option ("-t", "--typefile", dest="typefile", metavar="FILE", default=dataPath + "/management-types.xml", + help="Type descriptor file") +parser.add_option ("-d", "--templatedir", dest="templatedir", metavar="DIR", default=dataPath + "/templates", + help="Template directory") + +(opts, args) = parser.parse_args () + +if len (args) < 2: + parser.error ("Too few arguments") + +typefile = opts.typefile +templatedir = opts.templatedir + +schemafile = args[0] +outdir = args[1] + +gen = Generator (outdir, templatedir) +schema = PackageSchema (typefile, schemafile, opts) + +gen.makeClassFiles ("Class.h", schema) +gen.makeClassFiles ("Class.cpp", schema) +gen.makeMethodFiles ("Args.h", schema) +gen.makePackageFile ("Package.h", schema) +gen.makePackageFile ("Package.cpp", schema) + +if opts.makefile != None: + gen.makeSingleFile ("Makefile.mk", opts.makefile, force=True) diff --git a/qpid/cpp/managementgen/qmf/__init__.py b/qpid/cpp/managementgen/qmf/__init__.py new file mode 100644 index 0000000000..caef6cc58b --- /dev/null +++ b/qpid/cpp/managementgen/qmf/__init__.py @@ -0,0 +1,19 @@ +# +# 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. +# + diff --git a/qpid/cpp/managementgen/qmf/generate.py b/qpid/cpp/managementgen/qmf/generate.py new file mode 100755 index 0000000000..c1edf0b8e2 --- /dev/null +++ b/qpid/cpp/managementgen/qmf/generate.py @@ -0,0 +1,300 @@ +# +# 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: + """ + 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), + checking conditions (testCondition), and expanding tags (substHandler). + """ + def __init__ (self, filename, handler): + self.filename = filename + self.handler = handler + self.handler.initExpansion () + self.writing = True + + def expandLine (self, line, stream, object): + cursor = 0 + while 1: + sub = line.find ("/*MGEN:", cursor) + if sub == -1: + if self.writing: + stream.write (line[cursor:len (line)]) + return + + subend = line.find("*/", sub) + if self.writing: + stream.write (line[cursor:sub]) + cursor = subend + 2 + + tag = line[sub:subend] + + if tag[7:10] == "IF(": + close = tag.find(")") + if close == -1: + raise ValueError ("Missing ')' on condition") + cond = tag[10:close] + dotPos = cond.find (".") + if dotPos == -1: + raise ValueError ("Invalid condition tag: %s" % cond) + tagObject = cond[0:dotPos] + tagName = cond[dotPos + 1 : len(cond)] + if not self.handler.testCondition(object, tagObject, tagName): + self.writing = False + + elif tag[7:12] == "ENDIF": + self.writing = True + + else: + 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)] + if self.writing: + self.handler.substHandler (object, stream, tagObject, tagName) + else: + tagKey = tag[7:equalPos] + tagVal = tag[equalPos + 1:len (tag)] + if self.writing: + 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 + "/qmf-gen \\\n") + stream.write (" " + mdir + "/qmf/generate.py \\\n") + stream.write (" " + mdir + "/qmf/schema.py \\\n") + stream.write (" " + mdir + "/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: + 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) + if pair[0] != '': + 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 = [] + self.variables = {} + + 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 (".") + 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 targetPackageFile (self, schema, templateFile): + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + extension = templateFile[dot:len (templateFile)] + path = self.dest + "Package" + schema.getPackageNameCap() + extension + return path + + 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.getNameCap () + 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 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, self.variables)" + eval (call) + + def testCondition (self, object, tagObject, tag): + if tagObject == "Root": + obj = "self" + else: + obj = "object" # MUST be the same as the 2nd formal parameter + + call = obj + ".test" + tag + "(self.variables)" + return eval (call) + + 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) + self.templateFiles.append (templateFile) + for _class in classes: + target = self.targetClassFile (_class, templateFile) + stream = template.expand (_class) + self.writeIfChanged (stream, target, force) + + def makeMethodFiles (self, templateFile, schema, force=False): + """ Generate an expanded template per method-with-arguments """ + classes = schema.getClasses () + template = Template (self.input + templateFile, self) + 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, force) + + def makePackageFile (self, templateFile, schema, force=False): + """ Generate a package-specific file """ + template = Template (self.input + templateFile, self) + self.templateFiles.append (templateFile) + target = self.targetPackageFile (schema, templateFile) + stream = template.expand (schema) + self.writeIfChanged (stream, target, force) + + 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/qpid/cpp/managementgen/qmf/schema.py b/qpid/cpp/managementgen/qmf/schema.py new file mode 100755 index 0000000000..e666bdbb39 --- /dev/null +++ b/qpid/cpp/managementgen/qmf/schema.py @@ -0,0 +1,1208 @@ +# +# 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 +import md5 + +#===================================================================================== +# +#===================================================================================== +class SchemaType: + def __init__ (self, node): + self.name = None + self.base = None + self.cpp = None + self.encode = None + self.decode = None + self.style = "normal" + self.accessor = None + self.init = "0" + self.perThread = False + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'base': + self.base = val + + elif key == 'cpp': + self.cpp = val + + elif key == 'encode': + self.encode = val + + elif key == 'decode': + self.decode = val + + elif key == 'style': + self.style = val + + elif key == 'accessor': + self.accessor = val + + elif key == 'init': + self.init = val + + elif key == 'perThread': + if val != 'y': + raise ValueError ("Expected 'y' in perThread attribute") + self.perThread = True + + else: + raise ValueError ("Unknown attribute in type '%s'" % key) + + if self.name == None or self.base == None or self.cpp == None or \ + self.encode == None or self.decode == None: + raise ValueError ("Missing required attribute(s) in type") + + def getName (self): + return self.name + + def genAccessor (self, stream, varName, changeFlag = None, optional = False): + if self.perThread: + prefix = "getThreadStats()->" + if self.style == "wm": + raise ValueError ("'wm' style types can't be per-thread") + else: + prefix = "" + if self.accessor == "direct": + stream.write (" inline void set_" + varName + " (" + self.cpp + " val) {\n"); + if not self.perThread: + stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") + if self.style != "mma": + stream.write (" " + prefix + varName + " = val;\n") + if optional: + stream.write (" presenceMask[presenceByte_%s] |= presenceMask_%s;\n" % (varName, varName)) + if self.style == "wm": + stream.write (" if (" + varName + "Low > val)\n") + stream.write (" " + varName + "Low = val;\n") + stream.write (" if (" + varName + "High < val)\n") + stream.write (" " + varName + "High = val;\n") + if self.style == "mma": + stream.write (" " + prefix + varName + "Count++;\n") + stream.write (" " + prefix + varName + "Total += val;\n") + stream.write (" if (" + prefix + varName + "Min > val)\n") + stream.write (" " + prefix + varName + "Min = val;\n") + stream.write (" if (" + prefix + varName + "Max < val)\n") + stream.write (" " + prefix + varName + "Max = val;\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n") + if self.style != "mma": + stream.write (" inline " + self.cpp + "& get_" + varName + "() {\n"); + if not self.perThread: + stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" return " + prefix + varName + ";\n") + stream.write (" }\n") + if optional: + stream.write (" inline void clr_" + varName + "() {\n") + stream.write (" presenceMask[presenceByte_%s] &= ~presenceMask_%s;\n" % (varName, varName)) + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n") + stream.write (" inline bool isSet_" + varName + "() {\n") + stream.write (" return (presenceMask[presenceByte_%s] & presenceMask_%s) != 0;\n" % (varName, varName)) + stream.write (" }\n") + elif self.accessor == "counter": + stream.write (" inline void inc_" + varName + " (" + self.cpp + " by = 1) {\n"); + if not self.perThread: + stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" " + prefix + varName + " += by;\n") + if self.style == "wm": + stream.write (" if (" + varName + "High < " + varName + ")\n") + stream.write (" " + varName + "High = " + varName + ";\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); + stream.write (" inline void dec_" + varName + " (" + self.cpp + " by = 1) {\n"); + if not self.perThread: + stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" " + prefix + varName + " -= by;\n") + if self.style == "wm": + stream.write (" if (" + varName + "Low > " + varName + ")\n") + stream.write (" " + varName + "Low = " + varName + ";\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); + + def genHiLoStatResets (self, stream, varName): + if self.style == "wm": + stream.write (" " + varName + "High = " + varName + ";\n") + stream.write (" " + varName + "Low = " + varName + ";\n") + if self.style == "mma": + stream.write (" " + varName + "Count = 0;\n") + stream.write (" " + varName + "Total = 0;\n") + stream.write (" " + varName + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") + stream.write (" " + varName + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") + + def genPerThreadHiLoStatResets (self, stream, varName, cpptype): + if self.style == "mma": + stream.write (" threadStats->" + varName + "Count = 0;\n") + stream.write (" threadStats->" + varName + "Total = 0;\n") + stream.write (" threadStats->" + varName + "Min = std::numeric_limits<" + cpptype + ">::max();\n") + stream.write (" threadStats->" + varName + "Max = std::numeric_limits<" + cpptype + ">::min();\n") + + def genWrite (self, stream, varName, indent=" "): + if self.style != "mma": + stream.write (indent + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") + if self.style == "wm": + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "High") + ";\n") + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Low") + ";\n") + if self.style == "mma": + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Count") + ";\n") + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Count ? " + varName + "Min : 0") + ";\n") + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Max") + ";\n") + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Count ? " + varName + "Total / " + + varName + "Count : 0") + ";\n") + + + def getReadCode (self, varName, bufName): + result = self.decode.replace ("@", bufName).replace ("#", varName) + return result + + def getWriteCode (self, varName, bufName): + result = self.encode.replace ("@", bufName).replace ("#", varName) + return result + +#===================================================================================== +# +#===================================================================================== +class TypeSpec: + def __init__ (self, file): + self.types = {} + dom = parse (file) + document = dom.documentElement + if document.tagName != 'schema-types': + raise ValueError ("Expected 'schema-types' in type file") + + for child in document.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'type': + stype = SchemaType (child) + self.types[stype.getName ()] = stype + else: + raise ValueError ("Unknown type tag '%s'" % child.nodeName) + + def getType (self, name): + return self.types[name] + + +#===================================================================================== +# +#===================================================================================== +class Type: + def __init__ (self, name, typespec): + self.type = typespec.getType (name) + +#===================================================================================== +# +#===================================================================================== +class SchemaProperty: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.ref = None + self.access = "RO" + self.isIndex = 0 + self.isParentRef = 0 + self.isGeneralRef = 0 + self.isOptional = 0 + self.unit = None + self.min = None + self.max = None + self.maxLen = None + self.desc = None + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = makeValidCppSymbol(val) + + elif key == 'type': + self.type = Type (val, typespec) + if self.type.type.accessor != 'direct': + raise ValueError ("Class properties must have a type with a direct accessor") + + elif key == 'references': + self.ref = val + + elif key == 'access': + self.access = val + + elif key == 'index': + if val != 'y': + raise ValueError ("Expected 'y' in index attribute") + self.isIndex = 1 + + elif key == 'parentRef': + if val != 'y': + raise ValueError ("Expected 'y' in parentRef attribute") + self.isParentRef = 1 + + elif key == 'isGeneralReference': + if val != 'y': + raise ValueError ("Expected 'y' in isGeneralReference attribute") + self.isGeneralRef = 1 + + elif key == 'optional': + if val != 'y': + raise ValueError ("Expected 'y' in optional attribute") + self.isOptional = 1 + + elif key == 'unit': + self.unit = val + + elif key == 'min': + self.min = val + + elif key == 'max': + self.max = val + + elif key == 'maxlen': + self.maxLen = val + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in property '%s'" % key) + + if self.access == "RC" and self.isOptional == 1: + raise ValueError ("Properties with ReadCreate access must not be optional (%s)" % self.name) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in property") + if self.type == None: + raise ValueError ("Missing 'type' attribute in property") + + def getName (self): + return self.name + + def isConstructorArg (self): + if self.access == "RC" and self.isParentRef == 0: + return 1 + return 0 + + def genDeclaration (self, stream, prefix=" "): + stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") + + def genFormalParam (self, stream, variables): + stream.write (self.type.type.cpp + " _" + self.name) + + def genAccessor (self, stream): + self.type.type.genAccessor (stream, self.name, "configChanged", self.isOptional == 1) + + def genSchema (self, stream): + stream.write (" ft = FieldTable ();\n") + stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") + stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + stream.write (" ft.setInt (ACCESS, ACCESS_" + self.access + ");\n") + stream.write (" ft.setInt (INDEX, " + str (self.isIndex) + ");\n") + stream.write (" ft.setInt (OPTIONAL, " + str (self.isOptional) + ");\n") + if self.unit != None: + stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + if self.min != None: + stream.write (" ft.setInt (MIN, " + self.min + ");\n") + if self.max != None: + stream.write (" ft.setInt (MAX, " + self.max + ");\n") + if self.maxLen != None: + stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") + if self.desc != None: + stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + + def genWrite (self, stream): + indent = " " + if self.isOptional: + stream.write(" if (presenceMask[presenceByte_%s] & presenceMask_%s) {\n" % (self.name, self.name)) + indent = " " + self.type.type.genWrite (stream, self.name, indent) + if self.isOptional: + stream.write(" }\n") + + +#===================================================================================== +# +#===================================================================================== +class SchemaStatistic: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.unit = None + self.desc = None + self.assign = None + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = makeValidCppSymbol(val) + + elif key == 'type': + self.type = Type (val, typespec) + + elif key == 'unit': + self.unit = val + + elif key == 'desc': + self.desc = val + + elif key == 'assign': + self.assign = val + + else: + raise ValueError ("Unknown attribute in statistic '%s'" % key) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in statistic") + if self.type == None: + raise ValueError ("Missing 'type' attribute in statistic") + + def getName (self): + return self.name + + def genDeclaration (self, stream, prefix=" "): + if self.type.type.style != "mma": + stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") + if self.type.type.style == 'wm': + stream.write (prefix + self.type.type.cpp + " " + self.name + "High;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "Low;\n") + if self.type.type.style == "mma": + stream.write (prefix + self.type.type.cpp + " " + self.name + "Count;\n") + stream.write (prefix + "uint64_t " + self.name + "Total;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "Min;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "Max;\n") + + def genAccessor (self, stream): + self.type.type.genAccessor (stream, self.name, "instChanged") + + def genHiLoStatResets (self, stream): + self.type.type.genHiLoStatResets (stream, self.name) + + def genPerThreadHiLoStatResets (self, stream): + self.type.type.genPerThreadHiLoStatResets (stream, self.name, self.type.type.cpp) + + def genSchemaText (self, stream, name, desc): + stream.write (" ft = FieldTable ();\n") + stream.write (" ft.setString (NAME, \"" + name + "\");\n") + stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + if self.unit != None: + stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + if desc != None: + stream.write (" ft.setString (DESC, \"" + desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + + def genSchema (self, stream): + if self.type.type.style != "mma": + self.genSchemaText (stream, self.name, self.desc) + if self.type.type.style == "wm": + descHigh = self.desc + descLow = self.desc + if self.desc != None: + descHigh = descHigh + " (High)" + descLow = descLow + " (Low)" + self.genSchemaText (stream, self.name + "High", descHigh) + self.genSchemaText (stream, self.name + "Low", descLow) + if self.type.type.style == "mma": + descCount = self.desc + descMin = self.desc + descMax = self.desc + descAverage = self.desc + if self.desc != None: + descCount = descCount + " (Samples)" + descMin = descMin + " (Min)" + descMax = descMax + " (Max)" + descAverage = descAverage + " (Average)" + self.genSchemaText (stream, self.name + "Samples", descCount) + self.genSchemaText (stream, self.name + "Min", descMin) + self.genSchemaText (stream, self.name + "Max", descMax) + self.genSchemaText (stream, self.name + "Average", descAverage) + + def genAssign (self, stream): + if self.assign != None: + if self.type.type.perThread: + prefix = " threadStats->" + else: + prefix = "" + stream.write (" " + prefix + self.name + " = (" + self.type.type.cpp + + ") (" + self.assign + ");\n") + + def genWrite (self, stream): + if self.type.type.perThread: + self.type.type.genWrite (stream, "totals." + self.name) + else: + self.type.type.genWrite (stream, self.name) + + def genInitialize (self, stream, prefix="", indent=" "): + val = self.type.type.init + if self.type.type.style != "mma": + stream.write (indent + prefix + self.name + " = " + val + ";\n") + if self.type.type.style == "wm": + stream.write (indent + prefix + self.name + "High = " + val + ";\n") + stream.write (indent + prefix + self.name + "Low = " + val + ";\n") + if self.type.type.style == "mma": + stream.write (indent + prefix + self.name + "Count = 0;\n") + stream.write (indent + prefix + self.name + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") + stream.write (indent + prefix + self.name + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") + stream.write (indent + prefix + self.name + "Total = 0;\n") + + def genInitializeTotalPerThreadStats (self, stream): + if self.type.type.style == "mma": + stream.write (" totals->" + self.name + "Count = 0;\n") + stream.write (" totals->" + self.name + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") + stream.write (" totals->" + self.name + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") + stream.write (" totals->" + self.name + "Total = 0;\n") + else: + stream.write (" totals->" + self.name + " = 0;\n") + + def genAggregatePerThreadStats (self, stream): + if self.type.type.style == "mma": + stream.write (" totals->%sCount += threadStats->%sCount;\n" % (self.name, self.name)) + stream.write (" if (totals->%sMin > threadStats->%sMin)\n" % (self.name, self.name)) + stream.write (" totals->%sMin = threadStats->%sMin;\n" % (self.name, self.name)) + stream.write (" if (totals->%sMax < threadStats->%sMax)\n" % (self.name, self.name)) + stream.write (" totals->%sMax = threadStats->%sMax;\n" % (self.name, self.name)) + stream.write (" totals->%sTotal += threadStats->%sTotal;\n" % (self.name, self.name)) + else: + stream.write (" totals->%s += threadStats->%s;\n" % (self.name, self.name)) + +#===================================================================================== +# +#===================================================================================== +class SchemaArg: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.unit = None + self.dir = "I" + self.min = None + self.max = None + self.maxLen = None + self.desc = None + self.default = None + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = makeValidCppSymbol(val) + + elif key == 'type': + self.type = Type (val, typespec) + + elif key == 'unit': + self.unit = val + + elif key == 'dir': + self.dir = val.upper () + + elif key == 'min': + self.min = val + + elif key == 'max': + self.max = val + + elif key == 'maxlen': + self.maxLen = val + + elif key == 'desc': + self.desc = val + + elif key == 'default': + self.default = val + + else: + raise ValueError ("Unknown attribute in arg '%s'" % key) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in arg") + if self.type == None: + raise ValueError ("Missing 'type' attribute in arg") + + def getName (self): + return self.name + + def getDir (self): + return self.dir + + def genSchema (self, stream, event=False): + stream.write (" ft = FieldTable ();\n") + stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") + stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + if (not event): + stream.write (" ft.setString (DIR, \"" + self.dir + "\");\n") + if self.unit != None: + stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + if not event: + if self.min != None: + stream.write (" ft.setInt (MIN, " + self.min + ");\n") + if self.max != None: + stream.write (" ft.setInt (MAX, " + self.max + ");\n") + if self.maxLen != None: + stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") + if self.default != None: + stream.write (" ft.setString (DEFAULT, \"" + self.default + "\");\n") + if self.desc != None: + stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + + def genFormalParam (self, stream, variables): + stream.write ("%s _%s" % (self.type.type.cpp, self.name)) + +#===================================================================================== +# +#===================================================================================== +class SchemaMethod: + def __init__ (self, parent, node, typespec): + self.parent = parent + self.name = None + self.desc = None + self.args = [] + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = makeValidCppSymbol(val) + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in method '%s'" % key) + + for child in node.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'arg': + arg = SchemaArg (child, typespec) + self.args.append (arg) + else: + raise ValueError ("Unknown method tag '%s'" % child.nodeName) + + def getName (self): + return self.name + + def getFullName (self): + return capitalize(self.parent.getName()) + self.name[0:1].upper() +\ + self.name[1:] + + def getArgCount (self): + return len (self.args) + + #=================================================================================== + # Code Generation Functions. The names of these functions (minus the leading "gen") + # match the substitution keywords in the template files. + #=================================================================================== + def genNameUpper (self, stream, variables): + stream.write (self.getFullName ().upper ()) + + def genNameCamel (self, stream, variables): + stream.write (self.getFullName ()) + + 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, variables): + stream.write (" ft = FieldTable ();\n") + stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") + stream.write (" ft.setInt (ARGCOUNT, " + str (len (self.args)) + ");\n") + if self.desc != None: + stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + for arg in self.args: + arg.genSchema (stream) + +#===================================================================================== +# +#===================================================================================== +class SchemaEvent: + def __init__ (self, parent, node, typespec): + self.parent = parent + self.name = None + self.desc = None + self.args = [] + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in event '%s'" % key) + + for child in node.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'arg': + arg = SchemaArg (child, typespec) + self.args.append (arg) + else: + raise ValueError ("Unknown event tag '%s'" % child.nodeName) + + def getName (self): + return self.name + + def getFullName (self): + return capitalize(self.parent.getName()) + capitalize(self.name) + + def getArgCount (self): + return len (self.args) + + def genMethodBody (self, stream, variables, classObject): + stream.write("void ") + classObject.genNameCap(stream, variables) + stream.write("::event_%s(" % self.name) + count = 0 + for arg in self.args: + arg.genFormalParam(stream, variables) + count += 1 + if count < len(self.args): + stream.write(", ") + stream.write(") {\n") + stream.write(" sys::Mutex::ScopedLock mutex(getMutex());\n") + stream.write(" Buffer* buf = startEventLH();\n") + stream.write(" objectId.encode(*buf);\n") + stream.write(" buf->putShortString(packageName);\n") + stream.write(" buf->putShortString(className);\n") + stream.write(" buf->putBin128(md5Sum);\n") + stream.write(" buf->putShortString(\"%s\");\n" % self.name) + for arg in self.args: + stream.write(" %s;\n" % arg.type.type.encode.replace("@", "(*buf)").replace("#", "_" + arg.name)) + stream.write(" finishEventLH(buf);\n") + stream.write("}\n\n") + + def genMethodDecl (self, stream, variables): + stream.write(" void event_%s(" % self.name) + count = 0 + for arg in self.args: + arg.genFormalParam(stream, variables) + count += 1 + if count < len(self.args): + stream.write(", ") + stream.write(");\n") + + 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") + if self.desc != None: + stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + for arg in self.args: + arg.genSchema (stream, True) + + + +class SchemaClass: + def __init__ (self, package, node, typespec, fragments, options): + self.packageName = package + self.properties = [] + self.statistics = [] + self.methods = [] + self.events = [] + self.options = options + self.md5Sum = md5.new () + + self.hash (node) + + attrs = node.attributes + self.name = makeValidCppSymbol(attrs['name'].nodeValue) + + children = node.childNodes + for child in children: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'property': + sub = SchemaProperty (child, typespec) + self.properties.append (sub) + + elif child.nodeName == 'statistic': + sub = SchemaStatistic (child, typespec) + self.statistics.append (sub) + + elif child.nodeName == 'method': + sub = SchemaMethod (self, child, typespec) + self.methods.append (sub) + + elif child.nodeName == 'event': + sub = SchemaEvent (self, child, typespec) + self.events.append (sub) + + elif child.nodeName == 'group': + self.expandFragment (child, fragments) + + else: + raise ValueError ("Unknown class tag '%s'" % child.nodeName) + + # Adjust the 'assign' attributes for each statistic + for stat in self.statistics: + if stat.assign != None and stat.type.type.perThread: + stat.assign = self.adjust (stat.assign, self.statistics) + + def adjust (self, text, statistics): + result = text + start = 0 + while True: + next = None + for stat in statistics: + pos = result.find (stat.name, start) + if pos != -1 and (next == None or pos < next[0]): + next = (pos, stat.name) + if next == None: + return result + pos = next[0] + result = result[0:pos] + "threadStats->" + result[pos:] + start = pos + 9 + len(next[1]) + + def hash (self, node): + attrs = node.attributes + self.md5Sum.update (node.nodeName) + + for idx in range (attrs.length): + self.md5Sum.update (attrs.item(idx).nodeName) + self.md5Sum.update (attrs.item(idx).nodeValue) + + for child in node.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self.hash (child) + + def expandFragment (self, node, fragments): + attrs = node.attributes + name = attrs['name'].nodeValue + for fragment in fragments: + if fragment.name == name: + self.md5Sum.update (fragment.md5Sum.digest()) + for config in fragment.properties: + self.properties.append (config) + for inst in fragment.statistics: + self.statistics.append (inst) + for method in fragment.methods: + self.methods.append (method) + for event in fragment.events: + self.events.append (event) + return + raise ValueError ("Undefined group '%s'" % name) + + def getName (self): + return self.name + + def getNameCap (self): + return capitalize(self.name) + + def getMethods (self): + return self.methods + + def getEvents (self): + return self.events + + def getPackageNameCap (self): + return capitalize(self.packageName) + + #=================================================================================== + # Code Generation Functions. The names of these functions (minus the leading "gen") + # match the substitution keywords in the template files. + #=================================================================================== + def testExistOptionals (self, variables): + for prop in self.properties: + if prop.isOptional == 1: + return True + return False + + def testExistPerThreadStats (self, variables): + for inst in self.statistics: + if inst.type.type.perThread: + return True + return False + + def testExistPerThreadAssign (self, variables): + for inst in self.statistics: + if inst.type.type.perThread and inst.assign != None: + return True + return False + + def testExistPerThreadResets (self, variables): + for inst in self.statistics: + if inst.type.type.perThread and inst.type.type.style == "mma": + return True + return False + + def testNoStatistics (self, variables): + return len (self.statistics) == 0 + + def genAccessorMethods (self, stream, variables): + for config in self.properties: + if config.access != "RC": + config.genAccessor (stream) + for inst in self.statistics: + if inst.assign == None: + inst.genAccessor (stream) + + def genConfigCount (self, stream, variables): + stream.write ("%d" % len (self.properties)) + + def genConfigDeclarations (self, stream, variables): + for element in self.properties: + element.genDeclaration (stream) + + def genConstructorArgs (self, stream, variables): + # Constructor args are config elements with read-create access + result = "" + for element in self.properties: + if element.isConstructorArg (): + stream.write (", ") + element.genFormalParam (stream, variables) + + def genConstructorInits (self, stream, variables): + for element in self.properties: + if element.isConstructorArg (): + stream.write ("," + element.getName () + "(_" + element.getName () + ")") + + def genDoMethodArgs (self, stream, variables): + methodCount = 0 + inArgCount = 0 + for method in self.methods: + methodCount = methodCount + 1 + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + inArgCount = inArgCount + 1 + + if methodCount == 0: + stream.write ("string, Buffer&, Buffer& outBuf") + else: + if inArgCount == 0: + stream.write ("string methodName, Buffer&, Buffer& outBuf") + else: + stream.write ("string methodName, Buffer& inBuf, Buffer& outBuf") + + def genEventCount (self, stream, variables): + stream.write ("%d" % len (self.events)) + + def genEventMethodBodies (self, stream, variables): + for event in self.events: + event.genMethodBody (stream, variables, self) + + def genEventMethodDecls (self, stream, variables): + for event in self.events: + event.genMethodDecl (stream, variables) + + def genEventSchema (self, stream, variables): + for event in self.events: + event.genSchema (stream, variables) + + def genHiLoStatResets (self, stream, variables): + for inst in self.statistics: + if not inst.type.type.perThread: + inst.genHiLoStatResets (stream) + + def genPerThreadHiLoStatResets (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genPerThreadHiLoStatResets (stream) + + def genInitializeElements (self, stream, variables): + for inst in self.statistics: + if not inst.type.type.perThread: + inst.genInitialize (stream) + + def genInitializePerThreadElements (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genInitialize (stream, "threadStats->", " ") + + def genInitializeTotalPerThreadStats (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genInitializeTotalPerThreadStats (stream) + + def genAggregatePerThreadStats (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genAggregatePerThreadStats (stream) + + def genInstCount (self, stream, variables): + count = 0 + for inst in self.statistics: + count = count + 1 + if inst.type.type.style == "wm": + count = count + 2 + if inst.type.type.style == "mma": + count = count + 3 + stream.write ("%d" % count) + + def genInstDeclarations (self, stream, variables): + for element in self.statistics: + if not element.type.type.perThread: + element.genDeclaration (stream) + + def genPerThreadDeclarations (self, stream, variables): + for element in self.statistics: + if element.type.type.perThread: + element.genDeclaration (stream, " ") + + def genMethodArgIncludes (self, stream, variables): + for method in self.methods: + if method.getArgCount () > 0: + stream.write ("#include \"Args" + method.getFullName () + ".h\"\n") + + def genMethodCount (self, stream, variables): + stream.write ("%d" % len (self.methods)) + + def genMethodHandlers (self, stream, variables): + for method in self.methods: + stream.write ("\n if (methodName == \"" + method.getName () + "\") {\n") + if method.getArgCount () == 0: + stream.write (" ArgsNone ioArgs;\n") + else: + stream.write (" Args" + method.getFullName () + " ioArgs;\n") + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + stream.write (" " +\ + arg.type.type.getReadCode ("ioArgs." +\ + arg.dir.lower () + "_" +\ + arg.name, "inBuf") + ";\n") + + stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ + method.getName().upper() + ", ioArgs);\n") + stream.write (" outBuf.putLong (status);\n") + stream.write (" outBuf.putShortString (Manageable::StatusText (status));\n") + for arg in method.args: + if arg.getDir () == "O" or arg.getDir () == "IO": + stream.write (" " +\ + arg.type.type.getWriteCode ("ioArgs." +\ + arg.dir.lower () + "_" +\ + arg.name, "outBuf") + ";\n") + stream.write (" return;\n }\n") + + def genPresenceMaskBytes (self, stream, variables): + count = 0 + for prop in self.properties: + if prop.isOptional == 1: + count += 1 + if count == 0: + stream.write("0") + else: + stream.write (str(((count - 1) / 8) + 1)) + + def genPresenceMaskConstants (self, stream, variables): + count = 0 + for prop in self.properties: + if prop.isOptional == 1: + stream.write(" static const uint8_t presenceByte_%s = %d;\n" % (prop.name, count / 8)) + stream.write(" static const uint8_t presenceMask_%s = %d;\n" % (prop.name, 1 << (count % 8))) + count += 1 + + def genPropertySchema (self, stream, variables): + for prop in self.properties: + prop.genSchema (stream) + + def genSetGeneralReferenceDeclaration (self, stream, variables): + for prop in self.properties: + if prop.isGeneralRef: + stream.write ("void setReference(ObjectId objectId) { " + prop.name + " = objectId; }\n") + + def genStatisticSchema (self, stream, variables): + for stat in self.statistics: + stat.genSchema (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, variables): + for method in self.methods: + method.genSchema (stream, variables) + + def genNameCap (self, stream, variables): + stream.write (capitalize(self.name)) + + def genNameLower (self, stream, variables): + stream.write (self.name.lower ()) + + def genNamePackageCap (self, stream, variables): + stream.write (self.getPackageNameCap ()) + + def genNamePackageLower (self, stream, variables): + stream.write (self.packageName.lower ()) + + def genNameUpper (self, stream, variables): + stream.write (self.name.upper ()) + + def genParentArg (self, stream, variables): + for config in self.properties: + if config.isParentRef == 1: + stream.write (", Manageable* _parent") + return + + def genParentRefAssignment (self, stream, variables): + for config in self.properties: + if config.isParentRef == 1: + stream.write (config.getName () + \ + " = _parent->GetManagementObject ()->getObjectId ();") + return + + def genSchemaMD5 (self, stream, variables): + sum = self.md5Sum.digest () + for idx in range (len (sum)): + if idx != 0: + stream.write (",") + stream.write (hex (ord (sum[idx]))) + + def genAssign (self, stream, variables): + for inst in self.statistics: + if not inst.type.type.perThread: + inst.genAssign (stream) + + def genPerThreadAssign (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genAssign (stream) + + def genWriteProperties (self, stream, variables): + for prop in self.properties: + prop.genWrite (stream) + + def genWriteStatistics (self, stream, variables): + for stat in self.statistics: + stat.genWrite (stream) + + + +class PackageSchema: + def __init__ (self, typefile, schemafile, options): + + self.classes = [] + self.fragments = [] + self.typespec = TypeSpec (typefile) + + dom = parse (schemafile) + document = dom.documentElement + if document.tagName != 'schema': + raise ValueError ("Expected 'schema' node") + attrs = document.attributes + self.packageName = makeValidCppSymbol(attrs['package'].nodeValue) + + children = document.childNodes + for child in children: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'class': + cls = SchemaClass (self.packageName, child, self.typespec, + self.fragments, options) + self.classes.append (cls) + + elif child.nodeName == 'group': + cls = SchemaClass (self.packageName, child, self.typespec, + self.fragments, options) + self.fragments.append (cls) + + else: + raise ValueError ("Unknown schema tag '%s'" % child.nodeName) + + def getPackageName (self): + return self.packageName + + def getPackageNameCap (self): + return capitalize(self.packageName) + + def getClasses (self): + return self.classes + + def genPackageNameUpper (self, stream, variables): + stream.write (self.packageName.upper ()) + + def genPackageNameCap (self, stream, variables): + stream.write (self.getPackageNameCap ()) + + def genClassIncludes (self, stream, variables): + for _class in self.classes: + stream.write ("#include \"") + _class.genNameCap (stream, variables) + stream.write (".h\"\n") + + def genClassRegisters (self, stream, variables): + for _class in self.classes: + stream.write (" ") + _class.genNameCap (stream, variables) + stream.write ("::registerClass(agent);\n") + + +#===================================================================================== +# Utility Functions +#===================================================================================== + +# Create a valid C++ symbol from the input string so that it can be +# used in generated C++ source. For instance, change "qpid.mgmt" to +# "qpidMgmt". +# +# Input: Raw string (str) to process +# Output: String (str) suitable for use as a C++ symbol +# +# Limitations: Currently, only strips periods ('.') from strings, +# eventually should strip :'s and ,'s and ''s, oh my! +def makeValidCppSymbol(input): + output = str() + capitalize = False + + for char in input: + skip = False + + if char == ".": + capitalize = True + skip = True + + if not skip: + output += capitalize and char.upper() or char + + capitalize = False + + return output + +# Capitalize a string by /only/ forcing the first character to be +# uppercase. The rest of the string is left alone. This is different +# from str.capitalize(), which forces the first character to uppercase +# and the rest to lowercase. +# +# Input: A string (str) to capitalize +# Output: A string (str) with the first character as uppercase +def capitalize(input): + return input[0].upper() + input[1:] diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py deleted file mode 100755 index e666bdbb39..0000000000 --- a/qpid/cpp/managementgen/schema.py +++ /dev/null @@ -1,1208 +0,0 @@ -# -# 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 -import md5 - -#===================================================================================== -# -#===================================================================================== -class SchemaType: - def __init__ (self, node): - self.name = None - self.base = None - self.cpp = None - self.encode = None - self.decode = None - self.style = "normal" - self.accessor = None - self.init = "0" - self.perThread = False - - attrs = node.attributes - for idx in range (attrs.length): - key = attrs.item(idx).nodeName - val = attrs.item(idx).nodeValue - if key == 'name': - self.name = val - - elif key == 'base': - self.base = val - - elif key == 'cpp': - self.cpp = val - - elif key == 'encode': - self.encode = val - - elif key == 'decode': - self.decode = val - - elif key == 'style': - self.style = val - - elif key == 'accessor': - self.accessor = val - - elif key == 'init': - self.init = val - - elif key == 'perThread': - if val != 'y': - raise ValueError ("Expected 'y' in perThread attribute") - self.perThread = True - - else: - raise ValueError ("Unknown attribute in type '%s'" % key) - - if self.name == None or self.base == None or self.cpp == None or \ - self.encode == None or self.decode == None: - raise ValueError ("Missing required attribute(s) in type") - - def getName (self): - return self.name - - def genAccessor (self, stream, varName, changeFlag = None, optional = False): - if self.perThread: - prefix = "getThreadStats()->" - if self.style == "wm": - raise ValueError ("'wm' style types can't be per-thread") - else: - prefix = "" - if self.accessor == "direct": - stream.write (" inline void set_" + varName + " (" + self.cpp + " val) {\n"); - if not self.perThread: - stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") - if self.style != "mma": - stream.write (" " + prefix + varName + " = val;\n") - if optional: - stream.write (" presenceMask[presenceByte_%s] |= presenceMask_%s;\n" % (varName, varName)) - if self.style == "wm": - stream.write (" if (" + varName + "Low > val)\n") - stream.write (" " + varName + "Low = val;\n") - stream.write (" if (" + varName + "High < val)\n") - stream.write (" " + varName + "High = val;\n") - if self.style == "mma": - stream.write (" " + prefix + varName + "Count++;\n") - stream.write (" " + prefix + varName + "Total += val;\n") - stream.write (" if (" + prefix + varName + "Min > val)\n") - stream.write (" " + prefix + varName + "Min = val;\n") - stream.write (" if (" + prefix + varName + "Max < val)\n") - stream.write (" " + prefix + varName + "Max = val;\n") - if changeFlag != None: - stream.write (" " + changeFlag + " = true;\n") - stream.write (" }\n") - if self.style != "mma": - stream.write (" inline " + self.cpp + "& get_" + varName + "() {\n"); - if not self.perThread: - stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") - stream.write (" return " + prefix + varName + ";\n") - stream.write (" }\n") - if optional: - stream.write (" inline void clr_" + varName + "() {\n") - stream.write (" presenceMask[presenceByte_%s] &= ~presenceMask_%s;\n" % (varName, varName)) - if changeFlag != None: - stream.write (" " + changeFlag + " = true;\n") - stream.write (" }\n") - stream.write (" inline bool isSet_" + varName + "() {\n") - stream.write (" return (presenceMask[presenceByte_%s] & presenceMask_%s) != 0;\n" % (varName, varName)) - stream.write (" }\n") - elif self.accessor == "counter": - stream.write (" inline void inc_" + varName + " (" + self.cpp + " by = 1) {\n"); - if not self.perThread: - stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") - stream.write (" " + prefix + varName + " += by;\n") - if self.style == "wm": - stream.write (" if (" + varName + "High < " + varName + ")\n") - stream.write (" " + varName + "High = " + varName + ";\n") - if changeFlag != None: - stream.write (" " + changeFlag + " = true;\n") - stream.write (" }\n"); - stream.write (" inline void dec_" + varName + " (" + self.cpp + " by = 1) {\n"); - if not self.perThread: - stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") - stream.write (" " + prefix + varName + " -= by;\n") - if self.style == "wm": - stream.write (" if (" + varName + "Low > " + varName + ")\n") - stream.write (" " + varName + "Low = " + varName + ";\n") - if changeFlag != None: - stream.write (" " + changeFlag + " = true;\n") - stream.write (" }\n"); - - def genHiLoStatResets (self, stream, varName): - if self.style == "wm": - stream.write (" " + varName + "High = " + varName + ";\n") - stream.write (" " + varName + "Low = " + varName + ";\n") - if self.style == "mma": - stream.write (" " + varName + "Count = 0;\n") - stream.write (" " + varName + "Total = 0;\n") - stream.write (" " + varName + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") - stream.write (" " + varName + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") - - def genPerThreadHiLoStatResets (self, stream, varName, cpptype): - if self.style == "mma": - stream.write (" threadStats->" + varName + "Count = 0;\n") - stream.write (" threadStats->" + varName + "Total = 0;\n") - stream.write (" threadStats->" + varName + "Min = std::numeric_limits<" + cpptype + ">::max();\n") - stream.write (" threadStats->" + varName + "Max = std::numeric_limits<" + cpptype + ">::min();\n") - - def genWrite (self, stream, varName, indent=" "): - if self.style != "mma": - stream.write (indent + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") - if self.style == "wm": - stream.write (indent + self.encode.replace ("@", "buf") \ - .replace ("#", varName + "High") + ";\n") - stream.write (indent + self.encode.replace ("@", "buf") \ - .replace ("#", varName + "Low") + ";\n") - if self.style == "mma": - stream.write (indent + self.encode.replace ("@", "buf") \ - .replace ("#", varName + "Count") + ";\n") - stream.write (indent + self.encode.replace ("@", "buf") \ - .replace ("#", varName + "Count ? " + varName + "Min : 0") + ";\n") - stream.write (indent + self.encode.replace ("@", "buf") \ - .replace ("#", varName + "Max") + ";\n") - stream.write (indent + self.encode.replace ("@", "buf") \ - .replace ("#", varName + "Count ? " + varName + "Total / " + - varName + "Count : 0") + ";\n") - - - def getReadCode (self, varName, bufName): - result = self.decode.replace ("@", bufName).replace ("#", varName) - return result - - def getWriteCode (self, varName, bufName): - result = self.encode.replace ("@", bufName).replace ("#", varName) - return result - -#===================================================================================== -# -#===================================================================================== -class TypeSpec: - def __init__ (self, file): - self.types = {} - dom = parse (file) - document = dom.documentElement - if document.tagName != 'schema-types': - raise ValueError ("Expected 'schema-types' in type file") - - for child in document.childNodes: - if child.nodeType == Node.ELEMENT_NODE: - if child.nodeName == 'type': - stype = SchemaType (child) - self.types[stype.getName ()] = stype - else: - raise ValueError ("Unknown type tag '%s'" % child.nodeName) - - def getType (self, name): - return self.types[name] - - -#===================================================================================== -# -#===================================================================================== -class Type: - def __init__ (self, name, typespec): - self.type = typespec.getType (name) - -#===================================================================================== -# -#===================================================================================== -class SchemaProperty: - def __init__ (self, node, typespec): - self.name = None - self.type = None - self.ref = None - self.access = "RO" - self.isIndex = 0 - self.isParentRef = 0 - self.isGeneralRef = 0 - self.isOptional = 0 - self.unit = None - self.min = None - self.max = None - self.maxLen = None - self.desc = None - - attrs = node.attributes - for idx in range (attrs.length): - key = attrs.item(idx).nodeName - val = attrs.item(idx).nodeValue - if key == 'name': - self.name = makeValidCppSymbol(val) - - elif key == 'type': - self.type = Type (val, typespec) - if self.type.type.accessor != 'direct': - raise ValueError ("Class properties must have a type with a direct accessor") - - elif key == 'references': - self.ref = val - - elif key == 'access': - self.access = val - - elif key == 'index': - if val != 'y': - raise ValueError ("Expected 'y' in index attribute") - self.isIndex = 1 - - elif key == 'parentRef': - if val != 'y': - raise ValueError ("Expected 'y' in parentRef attribute") - self.isParentRef = 1 - - elif key == 'isGeneralReference': - if val != 'y': - raise ValueError ("Expected 'y' in isGeneralReference attribute") - self.isGeneralRef = 1 - - elif key == 'optional': - if val != 'y': - raise ValueError ("Expected 'y' in optional attribute") - self.isOptional = 1 - - elif key == 'unit': - self.unit = val - - elif key == 'min': - self.min = val - - elif key == 'max': - self.max = val - - elif key == 'maxlen': - self.maxLen = val - - elif key == 'desc': - self.desc = val - - else: - raise ValueError ("Unknown attribute in property '%s'" % key) - - if self.access == "RC" and self.isOptional == 1: - raise ValueError ("Properties with ReadCreate access must not be optional (%s)" % self.name) - - if self.name == None: - raise ValueError ("Missing 'name' attribute in property") - if self.type == None: - raise ValueError ("Missing 'type' attribute in property") - - def getName (self): - return self.name - - def isConstructorArg (self): - if self.access == "RC" and self.isParentRef == 0: - return 1 - return 0 - - def genDeclaration (self, stream, prefix=" "): - stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") - - def genFormalParam (self, stream, variables): - stream.write (self.type.type.cpp + " _" + self.name) - - def genAccessor (self, stream): - self.type.type.genAccessor (stream, self.name, "configChanged", self.isOptional == 1) - - def genSchema (self, stream): - stream.write (" ft = FieldTable ();\n") - stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") - stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") - stream.write (" ft.setInt (ACCESS, ACCESS_" + self.access + ");\n") - stream.write (" ft.setInt (INDEX, " + str (self.isIndex) + ");\n") - stream.write (" ft.setInt (OPTIONAL, " + str (self.isOptional) + ");\n") - if self.unit != None: - stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") - if self.min != None: - stream.write (" ft.setInt (MIN, " + self.min + ");\n") - if self.max != None: - stream.write (" ft.setInt (MAX, " + self.max + ");\n") - if self.maxLen != None: - stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") - if self.desc != None: - stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") - stream.write (" buf.put (ft);\n\n") - - def genWrite (self, stream): - indent = " " - if self.isOptional: - stream.write(" if (presenceMask[presenceByte_%s] & presenceMask_%s) {\n" % (self.name, self.name)) - indent = " " - self.type.type.genWrite (stream, self.name, indent) - if self.isOptional: - stream.write(" }\n") - - -#===================================================================================== -# -#===================================================================================== -class SchemaStatistic: - def __init__ (self, node, typespec): - self.name = None - self.type = None - self.unit = None - self.desc = None - self.assign = None - - attrs = node.attributes - for idx in range (attrs.length): - key = attrs.item(idx).nodeName - val = attrs.item(idx).nodeValue - if key == 'name': - self.name = makeValidCppSymbol(val) - - elif key == 'type': - self.type = Type (val, typespec) - - elif key == 'unit': - self.unit = val - - elif key == 'desc': - self.desc = val - - elif key == 'assign': - self.assign = val - - else: - raise ValueError ("Unknown attribute in statistic '%s'" % key) - - if self.name == None: - raise ValueError ("Missing 'name' attribute in statistic") - if self.type == None: - raise ValueError ("Missing 'type' attribute in statistic") - - def getName (self): - return self.name - - def genDeclaration (self, stream, prefix=" "): - if self.type.type.style != "mma": - stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") - if self.type.type.style == 'wm': - stream.write (prefix + self.type.type.cpp + " " + self.name + "High;\n") - stream.write (prefix + self.type.type.cpp + " " + self.name + "Low;\n") - if self.type.type.style == "mma": - stream.write (prefix + self.type.type.cpp + " " + self.name + "Count;\n") - stream.write (prefix + "uint64_t " + self.name + "Total;\n") - stream.write (prefix + self.type.type.cpp + " " + self.name + "Min;\n") - stream.write (prefix + self.type.type.cpp + " " + self.name + "Max;\n") - - def genAccessor (self, stream): - self.type.type.genAccessor (stream, self.name, "instChanged") - - def genHiLoStatResets (self, stream): - self.type.type.genHiLoStatResets (stream, self.name) - - def genPerThreadHiLoStatResets (self, stream): - self.type.type.genPerThreadHiLoStatResets (stream, self.name, self.type.type.cpp) - - def genSchemaText (self, stream, name, desc): - stream.write (" ft = FieldTable ();\n") - stream.write (" ft.setString (NAME, \"" + name + "\");\n") - stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") - if self.unit != None: - stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") - if desc != None: - stream.write (" ft.setString (DESC, \"" + desc + "\");\n") - stream.write (" buf.put (ft);\n\n") - - def genSchema (self, stream): - if self.type.type.style != "mma": - self.genSchemaText (stream, self.name, self.desc) - if self.type.type.style == "wm": - descHigh = self.desc - descLow = self.desc - if self.desc != None: - descHigh = descHigh + " (High)" - descLow = descLow + " (Low)" - self.genSchemaText (stream, self.name + "High", descHigh) - self.genSchemaText (stream, self.name + "Low", descLow) - if self.type.type.style == "mma": - descCount = self.desc - descMin = self.desc - descMax = self.desc - descAverage = self.desc - if self.desc != None: - descCount = descCount + " (Samples)" - descMin = descMin + " (Min)" - descMax = descMax + " (Max)" - descAverage = descAverage + " (Average)" - self.genSchemaText (stream, self.name + "Samples", descCount) - self.genSchemaText (stream, self.name + "Min", descMin) - self.genSchemaText (stream, self.name + "Max", descMax) - self.genSchemaText (stream, self.name + "Average", descAverage) - - def genAssign (self, stream): - if self.assign != None: - if self.type.type.perThread: - prefix = " threadStats->" - else: - prefix = "" - stream.write (" " + prefix + self.name + " = (" + self.type.type.cpp + - ") (" + self.assign + ");\n") - - def genWrite (self, stream): - if self.type.type.perThread: - self.type.type.genWrite (stream, "totals." + self.name) - else: - self.type.type.genWrite (stream, self.name) - - def genInitialize (self, stream, prefix="", indent=" "): - val = self.type.type.init - if self.type.type.style != "mma": - stream.write (indent + prefix + self.name + " = " + val + ";\n") - if self.type.type.style == "wm": - stream.write (indent + prefix + self.name + "High = " + val + ";\n") - stream.write (indent + prefix + self.name + "Low = " + val + ";\n") - if self.type.type.style == "mma": - stream.write (indent + prefix + self.name + "Count = 0;\n") - stream.write (indent + prefix + self.name + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") - stream.write (indent + prefix + self.name + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") - stream.write (indent + prefix + self.name + "Total = 0;\n") - - def genInitializeTotalPerThreadStats (self, stream): - if self.type.type.style == "mma": - stream.write (" totals->" + self.name + "Count = 0;\n") - stream.write (" totals->" + self.name + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") - stream.write (" totals->" + self.name + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") - stream.write (" totals->" + self.name + "Total = 0;\n") - else: - stream.write (" totals->" + self.name + " = 0;\n") - - def genAggregatePerThreadStats (self, stream): - if self.type.type.style == "mma": - stream.write (" totals->%sCount += threadStats->%sCount;\n" % (self.name, self.name)) - stream.write (" if (totals->%sMin > threadStats->%sMin)\n" % (self.name, self.name)) - stream.write (" totals->%sMin = threadStats->%sMin;\n" % (self.name, self.name)) - stream.write (" if (totals->%sMax < threadStats->%sMax)\n" % (self.name, self.name)) - stream.write (" totals->%sMax = threadStats->%sMax;\n" % (self.name, self.name)) - stream.write (" totals->%sTotal += threadStats->%sTotal;\n" % (self.name, self.name)) - else: - stream.write (" totals->%s += threadStats->%s;\n" % (self.name, self.name)) - -#===================================================================================== -# -#===================================================================================== -class SchemaArg: - def __init__ (self, node, typespec): - self.name = None - self.type = None - self.unit = None - self.dir = "I" - self.min = None - self.max = None - self.maxLen = None - self.desc = None - self.default = None - - attrs = node.attributes - for idx in range (attrs.length): - key = attrs.item(idx).nodeName - val = attrs.item(idx).nodeValue - if key == 'name': - self.name = makeValidCppSymbol(val) - - elif key == 'type': - self.type = Type (val, typespec) - - elif key == 'unit': - self.unit = val - - elif key == 'dir': - self.dir = val.upper () - - elif key == 'min': - self.min = val - - elif key == 'max': - self.max = val - - elif key == 'maxlen': - self.maxLen = val - - elif key == 'desc': - self.desc = val - - elif key == 'default': - self.default = val - - else: - raise ValueError ("Unknown attribute in arg '%s'" % key) - - if self.name == None: - raise ValueError ("Missing 'name' attribute in arg") - if self.type == None: - raise ValueError ("Missing 'type' attribute in arg") - - def getName (self): - return self.name - - def getDir (self): - return self.dir - - def genSchema (self, stream, event=False): - stream.write (" ft = FieldTable ();\n") - stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") - stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") - if (not event): - stream.write (" ft.setString (DIR, \"" + self.dir + "\");\n") - if self.unit != None: - stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") - if not event: - if self.min != None: - stream.write (" ft.setInt (MIN, " + self.min + ");\n") - if self.max != None: - stream.write (" ft.setInt (MAX, " + self.max + ");\n") - if self.maxLen != None: - stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") - if self.default != None: - stream.write (" ft.setString (DEFAULT, \"" + self.default + "\");\n") - if self.desc != None: - stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") - stream.write (" buf.put (ft);\n\n") - - def genFormalParam (self, stream, variables): - stream.write ("%s _%s" % (self.type.type.cpp, self.name)) - -#===================================================================================== -# -#===================================================================================== -class SchemaMethod: - def __init__ (self, parent, node, typespec): - self.parent = parent - self.name = None - self.desc = None - self.args = [] - - attrs = node.attributes - for idx in range (attrs.length): - key = attrs.item(idx).nodeName - val = attrs.item(idx).nodeValue - if key == 'name': - self.name = makeValidCppSymbol(val) - - elif key == 'desc': - self.desc = val - - else: - raise ValueError ("Unknown attribute in method '%s'" % key) - - for child in node.childNodes: - if child.nodeType == Node.ELEMENT_NODE: - if child.nodeName == 'arg': - arg = SchemaArg (child, typespec) - self.args.append (arg) - else: - raise ValueError ("Unknown method tag '%s'" % child.nodeName) - - def getName (self): - return self.name - - def getFullName (self): - return capitalize(self.parent.getName()) + self.name[0:1].upper() +\ - self.name[1:] - - def getArgCount (self): - return len (self.args) - - #=================================================================================== - # Code Generation Functions. The names of these functions (minus the leading "gen") - # match the substitution keywords in the template files. - #=================================================================================== - def genNameUpper (self, stream, variables): - stream.write (self.getFullName ().upper ()) - - def genNameCamel (self, stream, variables): - stream.write (self.getFullName ()) - - 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, variables): - stream.write (" ft = FieldTable ();\n") - stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") - stream.write (" ft.setInt (ARGCOUNT, " + str (len (self.args)) + ");\n") - if self.desc != None: - stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") - stream.write (" buf.put (ft);\n\n") - for arg in self.args: - arg.genSchema (stream) - -#===================================================================================== -# -#===================================================================================== -class SchemaEvent: - def __init__ (self, parent, node, typespec): - self.parent = parent - self.name = None - self.desc = None - self.args = [] - - attrs = node.attributes - for idx in range (attrs.length): - key = attrs.item(idx).nodeName - val = attrs.item(idx).nodeValue - if key == 'name': - self.name = val - - elif key == 'desc': - self.desc = val - - else: - raise ValueError ("Unknown attribute in event '%s'" % key) - - for child in node.childNodes: - if child.nodeType == Node.ELEMENT_NODE: - if child.nodeName == 'arg': - arg = SchemaArg (child, typespec) - self.args.append (arg) - else: - raise ValueError ("Unknown event tag '%s'" % child.nodeName) - - def getName (self): - return self.name - - def getFullName (self): - return capitalize(self.parent.getName()) + capitalize(self.name) - - def getArgCount (self): - return len (self.args) - - def genMethodBody (self, stream, variables, classObject): - stream.write("void ") - classObject.genNameCap(stream, variables) - stream.write("::event_%s(" % self.name) - count = 0 - for arg in self.args: - arg.genFormalParam(stream, variables) - count += 1 - if count < len(self.args): - stream.write(", ") - stream.write(") {\n") - stream.write(" sys::Mutex::ScopedLock mutex(getMutex());\n") - stream.write(" Buffer* buf = startEventLH();\n") - stream.write(" objectId.encode(*buf);\n") - stream.write(" buf->putShortString(packageName);\n") - stream.write(" buf->putShortString(className);\n") - stream.write(" buf->putBin128(md5Sum);\n") - stream.write(" buf->putShortString(\"%s\");\n" % self.name) - for arg in self.args: - stream.write(" %s;\n" % arg.type.type.encode.replace("@", "(*buf)").replace("#", "_" + arg.name)) - stream.write(" finishEventLH(buf);\n") - stream.write("}\n\n") - - def genMethodDecl (self, stream, variables): - stream.write(" void event_%s(" % self.name) - count = 0 - for arg in self.args: - arg.genFormalParam(stream, variables) - count += 1 - if count < len(self.args): - stream.write(", ") - stream.write(");\n") - - 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") - if self.desc != None: - stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") - stream.write (" buf.put (ft);\n\n") - for arg in self.args: - arg.genSchema (stream, True) - - - -class SchemaClass: - def __init__ (self, package, node, typespec, fragments, options): - self.packageName = package - self.properties = [] - self.statistics = [] - self.methods = [] - self.events = [] - self.options = options - self.md5Sum = md5.new () - - self.hash (node) - - attrs = node.attributes - self.name = makeValidCppSymbol(attrs['name'].nodeValue) - - children = node.childNodes - for child in children: - if child.nodeType == Node.ELEMENT_NODE: - if child.nodeName == 'property': - sub = SchemaProperty (child, typespec) - self.properties.append (sub) - - elif child.nodeName == 'statistic': - sub = SchemaStatistic (child, typespec) - self.statistics.append (sub) - - elif child.nodeName == 'method': - sub = SchemaMethod (self, child, typespec) - self.methods.append (sub) - - elif child.nodeName == 'event': - sub = SchemaEvent (self, child, typespec) - self.events.append (sub) - - elif child.nodeName == 'group': - self.expandFragment (child, fragments) - - else: - raise ValueError ("Unknown class tag '%s'" % child.nodeName) - - # Adjust the 'assign' attributes for each statistic - for stat in self.statistics: - if stat.assign != None and stat.type.type.perThread: - stat.assign = self.adjust (stat.assign, self.statistics) - - def adjust (self, text, statistics): - result = text - start = 0 - while True: - next = None - for stat in statistics: - pos = result.find (stat.name, start) - if pos != -1 and (next == None or pos < next[0]): - next = (pos, stat.name) - if next == None: - return result - pos = next[0] - result = result[0:pos] + "threadStats->" + result[pos:] - start = pos + 9 + len(next[1]) - - def hash (self, node): - attrs = node.attributes - self.md5Sum.update (node.nodeName) - - for idx in range (attrs.length): - self.md5Sum.update (attrs.item(idx).nodeName) - self.md5Sum.update (attrs.item(idx).nodeValue) - - for child in node.childNodes: - if child.nodeType == Node.ELEMENT_NODE: - self.hash (child) - - def expandFragment (self, node, fragments): - attrs = node.attributes - name = attrs['name'].nodeValue - for fragment in fragments: - if fragment.name == name: - self.md5Sum.update (fragment.md5Sum.digest()) - for config in fragment.properties: - self.properties.append (config) - for inst in fragment.statistics: - self.statistics.append (inst) - for method in fragment.methods: - self.methods.append (method) - for event in fragment.events: - self.events.append (event) - return - raise ValueError ("Undefined group '%s'" % name) - - def getName (self): - return self.name - - def getNameCap (self): - return capitalize(self.name) - - def getMethods (self): - return self.methods - - def getEvents (self): - return self.events - - def getPackageNameCap (self): - return capitalize(self.packageName) - - #=================================================================================== - # Code Generation Functions. The names of these functions (minus the leading "gen") - # match the substitution keywords in the template files. - #=================================================================================== - def testExistOptionals (self, variables): - for prop in self.properties: - if prop.isOptional == 1: - return True - return False - - def testExistPerThreadStats (self, variables): - for inst in self.statistics: - if inst.type.type.perThread: - return True - return False - - def testExistPerThreadAssign (self, variables): - for inst in self.statistics: - if inst.type.type.perThread and inst.assign != None: - return True - return False - - def testExistPerThreadResets (self, variables): - for inst in self.statistics: - if inst.type.type.perThread and inst.type.type.style == "mma": - return True - return False - - def testNoStatistics (self, variables): - return len (self.statistics) == 0 - - def genAccessorMethods (self, stream, variables): - for config in self.properties: - if config.access != "RC": - config.genAccessor (stream) - for inst in self.statistics: - if inst.assign == None: - inst.genAccessor (stream) - - def genConfigCount (self, stream, variables): - stream.write ("%d" % len (self.properties)) - - def genConfigDeclarations (self, stream, variables): - for element in self.properties: - element.genDeclaration (stream) - - def genConstructorArgs (self, stream, variables): - # Constructor args are config elements with read-create access - result = "" - for element in self.properties: - if element.isConstructorArg (): - stream.write (", ") - element.genFormalParam (stream, variables) - - def genConstructorInits (self, stream, variables): - for element in self.properties: - if element.isConstructorArg (): - stream.write ("," + element.getName () + "(_" + element.getName () + ")") - - def genDoMethodArgs (self, stream, variables): - methodCount = 0 - inArgCount = 0 - for method in self.methods: - methodCount = methodCount + 1 - for arg in method.args: - if arg.getDir () == "I" or arg.getDir () == "IO": - inArgCount = inArgCount + 1 - - if methodCount == 0: - stream.write ("string, Buffer&, Buffer& outBuf") - else: - if inArgCount == 0: - stream.write ("string methodName, Buffer&, Buffer& outBuf") - else: - stream.write ("string methodName, Buffer& inBuf, Buffer& outBuf") - - def genEventCount (self, stream, variables): - stream.write ("%d" % len (self.events)) - - def genEventMethodBodies (self, stream, variables): - for event in self.events: - event.genMethodBody (stream, variables, self) - - def genEventMethodDecls (self, stream, variables): - for event in self.events: - event.genMethodDecl (stream, variables) - - def genEventSchema (self, stream, variables): - for event in self.events: - event.genSchema (stream, variables) - - def genHiLoStatResets (self, stream, variables): - for inst in self.statistics: - if not inst.type.type.perThread: - inst.genHiLoStatResets (stream) - - def genPerThreadHiLoStatResets (self, stream, variables): - for inst in self.statistics: - if inst.type.type.perThread: - inst.genPerThreadHiLoStatResets (stream) - - def genInitializeElements (self, stream, variables): - for inst in self.statistics: - if not inst.type.type.perThread: - inst.genInitialize (stream) - - def genInitializePerThreadElements (self, stream, variables): - for inst in self.statistics: - if inst.type.type.perThread: - inst.genInitialize (stream, "threadStats->", " ") - - def genInitializeTotalPerThreadStats (self, stream, variables): - for inst in self.statistics: - if inst.type.type.perThread: - inst.genInitializeTotalPerThreadStats (stream) - - def genAggregatePerThreadStats (self, stream, variables): - for inst in self.statistics: - if inst.type.type.perThread: - inst.genAggregatePerThreadStats (stream) - - def genInstCount (self, stream, variables): - count = 0 - for inst in self.statistics: - count = count + 1 - if inst.type.type.style == "wm": - count = count + 2 - if inst.type.type.style == "mma": - count = count + 3 - stream.write ("%d" % count) - - def genInstDeclarations (self, stream, variables): - for element in self.statistics: - if not element.type.type.perThread: - element.genDeclaration (stream) - - def genPerThreadDeclarations (self, stream, variables): - for element in self.statistics: - if element.type.type.perThread: - element.genDeclaration (stream, " ") - - def genMethodArgIncludes (self, stream, variables): - for method in self.methods: - if method.getArgCount () > 0: - stream.write ("#include \"Args" + method.getFullName () + ".h\"\n") - - def genMethodCount (self, stream, variables): - stream.write ("%d" % len (self.methods)) - - def genMethodHandlers (self, stream, variables): - for method in self.methods: - stream.write ("\n if (methodName == \"" + method.getName () + "\") {\n") - if method.getArgCount () == 0: - stream.write (" ArgsNone ioArgs;\n") - else: - stream.write (" Args" + method.getFullName () + " ioArgs;\n") - for arg in method.args: - if arg.getDir () == "I" or arg.getDir () == "IO": - stream.write (" " +\ - arg.type.type.getReadCode ("ioArgs." +\ - arg.dir.lower () + "_" +\ - arg.name, "inBuf") + ";\n") - - stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ - method.getName().upper() + ", ioArgs);\n") - stream.write (" outBuf.putLong (status);\n") - stream.write (" outBuf.putShortString (Manageable::StatusText (status));\n") - for arg in method.args: - if arg.getDir () == "O" or arg.getDir () == "IO": - stream.write (" " +\ - arg.type.type.getWriteCode ("ioArgs." +\ - arg.dir.lower () + "_" +\ - arg.name, "outBuf") + ";\n") - stream.write (" return;\n }\n") - - def genPresenceMaskBytes (self, stream, variables): - count = 0 - for prop in self.properties: - if prop.isOptional == 1: - count += 1 - if count == 0: - stream.write("0") - else: - stream.write (str(((count - 1) / 8) + 1)) - - def genPresenceMaskConstants (self, stream, variables): - count = 0 - for prop in self.properties: - if prop.isOptional == 1: - stream.write(" static const uint8_t presenceByte_%s = %d;\n" % (prop.name, count / 8)) - stream.write(" static const uint8_t presenceMask_%s = %d;\n" % (prop.name, 1 << (count % 8))) - count += 1 - - def genPropertySchema (self, stream, variables): - for prop in self.properties: - prop.genSchema (stream) - - def genSetGeneralReferenceDeclaration (self, stream, variables): - for prop in self.properties: - if prop.isGeneralRef: - stream.write ("void setReference(ObjectId objectId) { " + prop.name + " = objectId; }\n") - - def genStatisticSchema (self, stream, variables): - for stat in self.statistics: - stat.genSchema (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, variables): - for method in self.methods: - method.genSchema (stream, variables) - - def genNameCap (self, stream, variables): - stream.write (capitalize(self.name)) - - def genNameLower (self, stream, variables): - stream.write (self.name.lower ()) - - def genNamePackageCap (self, stream, variables): - stream.write (self.getPackageNameCap ()) - - def genNamePackageLower (self, stream, variables): - stream.write (self.packageName.lower ()) - - def genNameUpper (self, stream, variables): - stream.write (self.name.upper ()) - - def genParentArg (self, stream, variables): - for config in self.properties: - if config.isParentRef == 1: - stream.write (", Manageable* _parent") - return - - def genParentRefAssignment (self, stream, variables): - for config in self.properties: - if config.isParentRef == 1: - stream.write (config.getName () + \ - " = _parent->GetManagementObject ()->getObjectId ();") - return - - def genSchemaMD5 (self, stream, variables): - sum = self.md5Sum.digest () - for idx in range (len (sum)): - if idx != 0: - stream.write (",") - stream.write (hex (ord (sum[idx]))) - - def genAssign (self, stream, variables): - for inst in self.statistics: - if not inst.type.type.perThread: - inst.genAssign (stream) - - def genPerThreadAssign (self, stream, variables): - for inst in self.statistics: - if inst.type.type.perThread: - inst.genAssign (stream) - - def genWriteProperties (self, stream, variables): - for prop in self.properties: - prop.genWrite (stream) - - def genWriteStatistics (self, stream, variables): - for stat in self.statistics: - stat.genWrite (stream) - - - -class PackageSchema: - def __init__ (self, typefile, schemafile, options): - - self.classes = [] - self.fragments = [] - self.typespec = TypeSpec (typefile) - - dom = parse (schemafile) - document = dom.documentElement - if document.tagName != 'schema': - raise ValueError ("Expected 'schema' node") - attrs = document.attributes - self.packageName = makeValidCppSymbol(attrs['package'].nodeValue) - - children = document.childNodes - for child in children: - if child.nodeType == Node.ELEMENT_NODE: - if child.nodeName == 'class': - cls = SchemaClass (self.packageName, child, self.typespec, - self.fragments, options) - self.classes.append (cls) - - elif child.nodeName == 'group': - cls = SchemaClass (self.packageName, child, self.typespec, - self.fragments, options) - self.fragments.append (cls) - - else: - raise ValueError ("Unknown schema tag '%s'" % child.nodeName) - - def getPackageName (self): - return self.packageName - - def getPackageNameCap (self): - return capitalize(self.packageName) - - def getClasses (self): - return self.classes - - def genPackageNameUpper (self, stream, variables): - stream.write (self.packageName.upper ()) - - def genPackageNameCap (self, stream, variables): - stream.write (self.getPackageNameCap ()) - - def genClassIncludes (self, stream, variables): - for _class in self.classes: - stream.write ("#include \"") - _class.genNameCap (stream, variables) - stream.write (".h\"\n") - - def genClassRegisters (self, stream, variables): - for _class in self.classes: - stream.write (" ") - _class.genNameCap (stream, variables) - stream.write ("::registerClass(agent);\n") - - -#===================================================================================== -# Utility Functions -#===================================================================================== - -# Create a valid C++ symbol from the input string so that it can be -# used in generated C++ source. For instance, change "qpid.mgmt" to -# "qpidMgmt". -# -# Input: Raw string (str) to process -# Output: String (str) suitable for use as a C++ symbol -# -# Limitations: Currently, only strips periods ('.') from strings, -# eventually should strip :'s and ,'s and ''s, oh my! -def makeValidCppSymbol(input): - output = str() - capitalize = False - - for char in input: - skip = False - - if char == ".": - capitalize = True - skip = True - - if not skip: - output += capitalize and char.upper() or char - - capitalize = False - - return output - -# Capitalize a string by /only/ forcing the first character to be -# uppercase. The rest of the string is left alone. This is different -# from str.capitalize(), which forces the first character to uppercase -# and the rest to lowercase. -# -# Input: A string (str) to capitalize -# Output: A string (str) with the first character as uppercase -def capitalize(input): - return input[0].upper() + input[1:] -- cgit v1.2.1 From 6c3647858be91b75c03498563071b91fd612b082 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Fri, 5 Sep 2008 16:07:57 +0000 Subject: QPID-1274 - Moved management-gen data files into the qmf subdirectory to fix an install problem git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@692475 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/Makefile.am | 20 ++- qpid/cpp/managementgen/management-types.xml | 56 ------- qpid/cpp/managementgen/qmf-gen | 6 +- qpid/cpp/managementgen/qmf/generate.py | 4 +- qpid/cpp/managementgen/qmf/management-types.xml | 56 +++++++ qpid/cpp/managementgen/qmf/templates/Args.h | 40 +++++ qpid/cpp/managementgen/qmf/templates/Class.cpp | 180 +++++++++++++++++++++++ qpid/cpp/managementgen/qmf/templates/Class.h | 106 +++++++++++++ qpid/cpp/managementgen/qmf/templates/Makefile.mk | 37 +++++ qpid/cpp/managementgen/qmf/templates/Package.cpp | 32 ++++ qpid/cpp/managementgen/qmf/templates/Package.h | 41 ++++++ qpid/cpp/managementgen/templates/Args.h | 40 ----- qpid/cpp/managementgen/templates/Class.cpp | 180 ----------------------- qpid/cpp/managementgen/templates/Class.h | 106 ------------- qpid/cpp/managementgen/templates/Makefile.mk | 37 ----- qpid/cpp/managementgen/templates/Package.cpp | 32 ---- qpid/cpp/managementgen/templates/Package.h | 41 ------ 17 files changed, 506 insertions(+), 508 deletions(-) delete mode 100644 qpid/cpp/managementgen/management-types.xml create mode 100644 qpid/cpp/managementgen/qmf/management-types.xml create mode 100644 qpid/cpp/managementgen/qmf/templates/Args.h create mode 100644 qpid/cpp/managementgen/qmf/templates/Class.cpp create mode 100644 qpid/cpp/managementgen/qmf/templates/Class.h create mode 100644 qpid/cpp/managementgen/qmf/templates/Makefile.mk create mode 100644 qpid/cpp/managementgen/qmf/templates/Package.cpp create mode 100644 qpid/cpp/managementgen/qmf/templates/Package.h delete mode 100644 qpid/cpp/managementgen/templates/Args.h delete mode 100644 qpid/cpp/managementgen/templates/Class.cpp delete mode 100644 qpid/cpp/managementgen/templates/Class.h delete mode 100644 qpid/cpp/managementgen/templates/Makefile.mk delete mode 100644 qpid/cpp/managementgen/templates/Package.cpp delete mode 100644 qpid/cpp/managementgen/templates/Package.h (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am index 7a415b4be6..c8c1e64492 100644 --- a/qpid/cpp/managementgen/Makefile.am +++ b/qpid/cpp/managementgen/Makefile.am @@ -1,18 +1,16 @@ -qmfdatadir = $(datadir)/qmf qmfpythondir = $(pythondir) dist_bin_SCRIPTS = \ qmf-gen -nobase_qmfdata_DATA = \ - templates/Args.h \ - templates/Class.cpp \ - templates/Class.h \ - templates/Makefile.mk \ - templates/Package.cpp \ - templates/Package.h \ - management-types.xml nobase_qmfpython_DATA = \ qmf/__init__.py \ qmf/generate.py \ - qmf/schema.py + qmf/schema.py \ + qmf/templates/Args.h \ + qmf/templates/Class.cpp \ + qmf/templates/Class.h \ + qmf/templates/Makefile.mk \ + qmf/templates/Package.cpp \ + qmf/templates/Package.h \ + qmf/management-types.xml -EXTRA_DIST = $(nobase_qmfdata_DATA) $(nobase_qmfpython_DATA) +EXTRA_DIST = $(nobase_qmfpython_DATA) diff --git a/qpid/cpp/managementgen/management-types.xml b/qpid/cpp/managementgen/management-types.xml deleted file mode 100644 index 31337b23bc..0000000000 --- a/qpid/cpp/managementgen/management-types.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index a29a4074fd..840733bf7b 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -24,16 +24,16 @@ from qmf.schema import PackageSchema, SchemaClass from qmf.generate import Generator from optparse import OptionParser -dataPath = os.path.dirname(sys.argv[0]) +dataPath = os.path.dirname(sys.argv[0]) + "/qmf/" # Set command line options usage = "usage: %prog [options] schema-document out-directory" parser = OptionParser (usage=usage) parser.add_option ("-m", "--makefile", dest="makefile", metavar="FILE", help="Makefile fragment") -parser.add_option ("-t", "--typefile", dest="typefile", metavar="FILE", default=dataPath + "/management-types.xml", +parser.add_option ("-t", "--typefile", dest="typefile", metavar="FILE", default=dataPath + "management-types.xml", help="Type descriptor file") -parser.add_option ("-d", "--templatedir", dest="templatedir", metavar="DIR", default=dataPath + "/templates", +parser.add_option ("-d", "--templatedir", dest="templatedir", metavar="DIR", default=dataPath + "templates", help="Template directory") (opts, args) = parser.parse_args () diff --git a/qpid/cpp/managementgen/qmf/generate.py b/qpid/cpp/managementgen/qmf/generate.py index c1edf0b8e2..70735b208a 100755 --- a/qpid/cpp/managementgen/qmf/generate.py +++ b/qpid/cpp/managementgen/qmf/generate.py @@ -110,7 +110,7 @@ class Makefile: stream.write (mdir + "/qmf-gen \\\n") stream.write (" " + mdir + "/qmf/generate.py \\\n") stream.write (" " + mdir + "/qmf/schema.py \\\n") - stream.write (" " + mdir + "/management-types.xml \\\n") + stream.write (" " + mdir + "/qmf/management-types.xml \\\n") stream.write (" " + sdir + "/management-schema.xml \\\n") first = True for template in self.templateFiles: @@ -119,7 +119,7 @@ class Makefile: stream.write (" ") else: stream.write (" \\\n ") - stream.write (mdir + "/templates/" + template) + stream.write (mdir + "/qmf/templates/" + template) def genGenCppFiles (self, stream, variables): first = True diff --git a/qpid/cpp/managementgen/qmf/management-types.xml b/qpid/cpp/managementgen/qmf/management-types.xml new file mode 100644 index 0000000000..31337b23bc --- /dev/null +++ b/qpid/cpp/managementgen/qmf/management-types.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/qpid/cpp/managementgen/qmf/templates/Args.h b/qpid/cpp/managementgen/qmf/templates/Args.h new file mode 100644 index 0000000000..576d891a3f --- /dev/null +++ b/qpid/cpp/managementgen/qmf/templates/Args.h @@ -0,0 +1,40 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _ARGS_/*MGEN:Method.NameUpper*/_ +#define _ARGS_/*MGEN:Method.NameUpper*/_ + +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/Args.h" +#include + +namespace qpid { +namespace management { + +class Args/*MGEN:Method.NameCamel*/ : public Args +{ + public: +/*MGEN:Method.Arguments*/ +}; + +}} + +#endif /*!_ARGS_/*MGEN:Method.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmf/templates/Class.cpp b/qpid/cpp/managementgen/qmf/templates/Class.cpp new file mode 100644 index 0000000000..2a0e55b34d --- /dev/null +++ b/qpid/cpp/managementgen/qmf/templates/Class.cpp @@ -0,0 +1,180 @@ +/*MGEN:commentPrefix=//*/ +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/log/Statement.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/management/Manageable.h" +#include "qpid/agent/ManagementAgent.h" +#include "/*MGEN:Class.NameCap*/.h" +/*MGEN:Class.MethodArgIncludes*/ + +using namespace qpid::management; +using namespace qpid::sys; +using namespace qpid::framing; +using std::string; + +string /*MGEN:Class.NameCap*/::packageName = string ("/*MGEN:Class.NamePackageLower*/"); +string /*MGEN:Class.NameCap*/::className = string ("/*MGEN:Class.NameLower*/"); +uint8_t /*MGEN:Class.NameCap*/::md5Sum[16] = + {/*MGEN:Class.SchemaMD5*/}; + +/*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (ManagementAgent* _agent, Manageable* _core/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/) : + ManagementObject(_agent, _core)/*MGEN:Class.ConstructorInits*/ +{ + /*MGEN:Class.ParentRefAssignment*/ +/*MGEN:Class.InitializeElements*/ +/*MGEN:IF(Class.ExistOptionals)*/ + // Optional properties start out not-present + for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) + presenceMask[idx] = 0; +/*MGEN:ENDIF*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + maxThreads = agent->getMaxThreads(); + perThreadStatsArray = new struct PerThreadStats*[maxThreads]; + for (int idx = 0; idx < maxThreads; idx++) + perThreadStatsArray[idx] = 0; +/*MGEN:ENDIF*/ +} + +/*MGEN:Class.NameCap*/::~/*MGEN:Class.NameCap*/ () +{ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + for (int idx = 0; idx < maxThreads; idx++) + if (perThreadStatsArray[idx] != 0) + delete perThreadStatsArray[idx]; + delete[] perThreadStatsArray; +/*MGEN:ENDIF*/ +} + +namespace { + const string NAME("name"); + const string TYPE("type"); + const string ACCESS("access"); + const string INDEX("index"); + const string OPTIONAL("optional"); + const string UNIT("unit"); + const string MIN("min"); + const string MAX("max"); + const string MAXLEN("maxlen"); + const string DESC("desc"); + const string ARGCOUNT("argCount"); + const string ARGS("args"); + const string DIR("dir"); + const string DEFAULT("default"); +} + +void /*MGEN:Class.NameCap*/::registerClass(ManagementAgent* agent) +{ + agent->RegisterClass(packageName, className, md5Sum, writeSchema); +} + +void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) +{ + FieldTable ft; + + // Schema class header: + buf.putShortString (packageName); // Package Name + buf.putShortString (className); // Class Name + buf.putBin128 (md5Sum); // Schema Hash + buf.putShort (/*MGEN:Class.ConfigCount*/); // Config Element Count + buf.putShort (/*MGEN:Class.InstCount*/); // Inst Element Count + buf.putShort (/*MGEN:Class.MethodCount*/); // Method Count + buf.putShort (/*MGEN:Class.EventCount*/); // Event Count + + // Properties +/*MGEN:Class.PropertySchema*/ + // Statistics +/*MGEN:Class.StatisticSchema*/ + // Methods +/*MGEN:Class.MethodSchema*/ + // Events +/*MGEN:Class.EventSchema*/ +} + +/*MGEN:IF(Class.ExistPerThreadStats)*/ +void /*MGEN:Class.NameCap*/::aggregatePerThreadStats(struct PerThreadStats* totals) +{ +/*MGEN:Class.InitializeTotalPerThreadStats*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.AggregatePerThreadStats*/ + } + } +} +/*MGEN:ENDIF*/ + +void /*MGEN:Class.NameCap*/::writeProperties (Buffer& buf) +{ + sys::Mutex::ScopedLock mutex(accessLock); + configChanged = false; + + writeTimestamps (buf); +/*MGEN:IF(Class.ExistOptionals)*/ + for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) + buf.putOctet(presenceMask[idx]); +/*MGEN:ENDIF*/ +/*MGEN:Class.WriteProperties*/ +} + +void /*MGEN:Class.NameCap*/::writeStatistics (Buffer& buf, bool skipHeaders) +{ + sys::Mutex::ScopedLock mutex(accessLock); + instChanged = false; +/*MGEN:IF(Class.ExistPerThreadAssign)*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.PerThreadAssign*/ + } + } +/*MGEN:ENDIF*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + struct PerThreadStats totals; + aggregatePerThreadStats(&totals); +/*MGEN:ENDIF*/ +/*MGEN:Class.Assign*/ + if (!skipHeaders) + writeTimestamps (buf); +/*MGEN:Class.WriteStatistics*/ + + // Maintenance of hi-lo statistics +/*MGEN:Class.HiLoStatResets*/ +/*MGEN:IF(Class.ExistPerThreadResets)*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.PerThreadHiLoStatResets*/ + } + } +/*MGEN:ENDIF*/ +} + +void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) +{ + Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; +/*MGEN:Class.MethodHandlers*/ + outBuf.putLong (status); + outBuf.putShortString (Manageable::StatusText (status)); +} + +/*MGEN:Class.EventMethodBodies*/ diff --git a/qpid/cpp/managementgen/qmf/templates/Class.h b/qpid/cpp/managementgen/qmf/templates/Class.h new file mode 100644 index 0000000000..40ad20eb85 --- /dev/null +++ b/qpid/cpp/managementgen/qmf/templates/Class.h @@ -0,0 +1,106 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _MANAGEMENT_/*MGEN:Class.NameUpper*/_ +#define _MANAGEMENT_/*MGEN:Class.NameUpper*/_ + +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/ManagementObject.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/framing/Uuid.h" + +namespace qpid { +namespace management { + +class /*MGEN:Class.NameCap*/ : public ManagementObject +{ + private: + + static std::string packageName; + static std::string className; + static uint8_t md5Sum[16]; +/*MGEN:IF(Class.ExistOptionals)*/ + uint8_t presenceMask[/*MGEN:Class.PresenceMaskBytes*/]; +/*MGEN:Class.PresenceMaskConstants*/ +/*MGEN:ENDIF*/ + + // Properties +/*MGEN:Class.ConfigDeclarations*/ + // Statistics +/*MGEN:Class.InstDeclarations*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + // Per-Thread Statistics + struct PerThreadStats { +/*MGEN:Class.PerThreadDeclarations*/ + }; + + struct PerThreadStats** perThreadStatsArray; + + inline struct PerThreadStats* getThreadStats() { + int index = getThreadIndex(); + struct PerThreadStats* threadStats = perThreadStatsArray[index]; + if (threadStats == 0) { + threadStats = new(PerThreadStats); + perThreadStatsArray[index] = threadStats; +/*MGEN:Class.InitializePerThreadElements*/ + } + return threadStats; + } + + void aggregatePerThreadStats(struct PerThreadStats*); +/*MGEN:ENDIF*/ + // Private Methods + static void writeSchema (qpid::framing::Buffer& buf); + void writeProperties (qpid::framing::Buffer& buf); + void writeStatistics (qpid::framing::Buffer& buf, + bool skipHeaders = false); + void doMethod (std::string methodName, + qpid::framing::Buffer& inBuf, + qpid::framing::Buffer& outBuf); + writeSchemaCall_t getWriteSchemaCall(void) { return writeSchema; } +/*MGEN:IF(Class.NoStatistics)*/ + // Stub for getInstChanged. There are no statistics in this class. + bool getInstChanged (void) { return false; } +/*MGEN:ENDIF*/ + public: + + /*MGEN:Class.NameCap*/ (ManagementAgent* agent, + Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); + ~/*MGEN:Class.NameCap*/ (void); + + /*MGEN:Class.SetGeneralReferenceDeclaration*/ + + static void registerClass (ManagementAgent* agent); + std::string& getPackageName (void) { return packageName; } + std::string& getClassName (void) { return className; } + uint8_t* getMd5Sum (void) { return md5Sum; } + + // Method IDs +/*MGEN:Class.MethodIdDeclarations*/ + // Accessor Methods +/*MGEN:Class.AccessorMethods*/ + // Event Methods +/*MGEN:Class.EventMethodDecls*/ +}; + +}} + +#endif /*!_MANAGEMENT_/*MGEN:Class.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmf/templates/Makefile.mk b/qpid/cpp/managementgen/qmf/templates/Makefile.mk new file mode 100644 index 0000000000..0e6454c13a --- /dev/null +++ b/qpid/cpp/managementgen/qmf/templates/Makefile.mk @@ -0,0 +1,37 @@ +# +# 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. +# +/*MGEN:commentPrefix=#*/ +/*MGEN:mgenDir=$(mgen_dir)*/ +/*MGEN:specDir=$(top_srcdir)/../specs*/ +/*MGEN:Root.Disclaimer*/ + +mgen_generator=/*MGEN:Makefile.GenSources*/ + +mgen_broker_cpp=/*MGEN:Makefile.GenCppFiles*/ + +# Header file install rules. +qpid_managementdir = $(includedir)/qpid/management +dist_qpid_management_HEADERS = /*MGEN:Makefile.GenHFiles*/ + +if GENERATE +$(srcdir)/managementgen.mk: $(mgen_generator) + $(mgen_cmd) + +$(mgen_generator): +endif diff --git a/qpid/cpp/managementgen/qmf/templates/Package.cpp b/qpid/cpp/managementgen/qmf/templates/Package.cpp new file mode 100644 index 0000000000..15e7fc15ec --- /dev/null +++ b/qpid/cpp/managementgen/qmf/templates/Package.cpp @@ -0,0 +1,32 @@ +/*MGEN:commentPrefix=//*/ +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "Package/*MGEN:Schema.PackageNameCap*/.h" +/*MGEN:Schema.ClassIncludes*/ + +using namespace qpid::management; + +Package/*MGEN:Schema.PackageNameCap*/::Package/*MGEN:Schema.PackageNameCap*/ (ManagementAgent* agent) +{ +/*MGEN:Schema.ClassRegisters*/ +} + diff --git a/qpid/cpp/managementgen/qmf/templates/Package.h b/qpid/cpp/managementgen/qmf/templates/Package.h new file mode 100644 index 0000000000..3f3ac35ffc --- /dev/null +++ b/qpid/cpp/managementgen/qmf/templates/Package.h @@ -0,0 +1,41 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ +#define _MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ + +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/agent/ManagementAgent.h" + +namespace qpid { +namespace management { + +class Package/*MGEN:Schema.PackageNameCap*/ +{ + public: + Package/*MGEN:Schema.PackageNameCap*/ (ManagementAgent* agent); + ~Package/*MGEN:Schema.PackageNameCap*/ () {} +}; + +}} + + +#endif /*!_MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_*/ diff --git a/qpid/cpp/managementgen/templates/Args.h b/qpid/cpp/managementgen/templates/Args.h deleted file mode 100644 index 576d891a3f..0000000000 --- a/qpid/cpp/managementgen/templates/Args.h +++ /dev/null @@ -1,40 +0,0 @@ -/*MGEN:commentPrefix=//*/ -#ifndef _ARGS_/*MGEN:Method.NameUpper*/_ -#define _ARGS_/*MGEN:Method.NameUpper*/_ - -// -// 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. -// - -/*MGEN:Root.Disclaimer*/ - -#include "qpid/management/Args.h" -#include - -namespace qpid { -namespace management { - -class Args/*MGEN:Method.NameCamel*/ : public Args -{ - public: -/*MGEN:Method.Arguments*/ -}; - -}} - -#endif /*!_ARGS_/*MGEN:Method.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp deleted file mode 100644 index 2a0e55b34d..0000000000 --- a/qpid/cpp/managementgen/templates/Class.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/*MGEN:commentPrefix=//*/ -// -// 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. -// - -/*MGEN:Root.Disclaimer*/ - -#include "qpid/log/Statement.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/management/Manageable.h" -#include "qpid/agent/ManagementAgent.h" -#include "/*MGEN:Class.NameCap*/.h" -/*MGEN:Class.MethodArgIncludes*/ - -using namespace qpid::management; -using namespace qpid::sys; -using namespace qpid::framing; -using std::string; - -string /*MGEN:Class.NameCap*/::packageName = string ("/*MGEN:Class.NamePackageLower*/"); -string /*MGEN:Class.NameCap*/::className = string ("/*MGEN:Class.NameLower*/"); -uint8_t /*MGEN:Class.NameCap*/::md5Sum[16] = - {/*MGEN:Class.SchemaMD5*/}; - -/*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (ManagementAgent* _agent, Manageable* _core/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/) : - ManagementObject(_agent, _core)/*MGEN:Class.ConstructorInits*/ -{ - /*MGEN:Class.ParentRefAssignment*/ -/*MGEN:Class.InitializeElements*/ -/*MGEN:IF(Class.ExistOptionals)*/ - // Optional properties start out not-present - for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) - presenceMask[idx] = 0; -/*MGEN:ENDIF*/ -/*MGEN:IF(Class.ExistPerThreadStats)*/ - maxThreads = agent->getMaxThreads(); - perThreadStatsArray = new struct PerThreadStats*[maxThreads]; - for (int idx = 0; idx < maxThreads; idx++) - perThreadStatsArray[idx] = 0; -/*MGEN:ENDIF*/ -} - -/*MGEN:Class.NameCap*/::~/*MGEN:Class.NameCap*/ () -{ -/*MGEN:IF(Class.ExistPerThreadStats)*/ - for (int idx = 0; idx < maxThreads; idx++) - if (perThreadStatsArray[idx] != 0) - delete perThreadStatsArray[idx]; - delete[] perThreadStatsArray; -/*MGEN:ENDIF*/ -} - -namespace { - const string NAME("name"); - const string TYPE("type"); - const string ACCESS("access"); - const string INDEX("index"); - const string OPTIONAL("optional"); - const string UNIT("unit"); - const string MIN("min"); - const string MAX("max"); - const string MAXLEN("maxlen"); - const string DESC("desc"); - const string ARGCOUNT("argCount"); - const string ARGS("args"); - const string DIR("dir"); - const string DEFAULT("default"); -} - -void /*MGEN:Class.NameCap*/::registerClass(ManagementAgent* agent) -{ - agent->RegisterClass(packageName, className, md5Sum, writeSchema); -} - -void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) -{ - FieldTable ft; - - // Schema class header: - buf.putShortString (packageName); // Package Name - buf.putShortString (className); // Class Name - buf.putBin128 (md5Sum); // Schema Hash - buf.putShort (/*MGEN:Class.ConfigCount*/); // Config Element Count - buf.putShort (/*MGEN:Class.InstCount*/); // Inst Element Count - buf.putShort (/*MGEN:Class.MethodCount*/); // Method Count - buf.putShort (/*MGEN:Class.EventCount*/); // Event Count - - // Properties -/*MGEN:Class.PropertySchema*/ - // Statistics -/*MGEN:Class.StatisticSchema*/ - // Methods -/*MGEN:Class.MethodSchema*/ - // Events -/*MGEN:Class.EventSchema*/ -} - -/*MGEN:IF(Class.ExistPerThreadStats)*/ -void /*MGEN:Class.NameCap*/::aggregatePerThreadStats(struct PerThreadStats* totals) -{ -/*MGEN:Class.InitializeTotalPerThreadStats*/ - for (int idx = 0; idx < maxThreads; idx++) { - struct PerThreadStats* threadStats = perThreadStatsArray[idx]; - if (threadStats != 0) { -/*MGEN:Class.AggregatePerThreadStats*/ - } - } -} -/*MGEN:ENDIF*/ - -void /*MGEN:Class.NameCap*/::writeProperties (Buffer& buf) -{ - sys::Mutex::ScopedLock mutex(accessLock); - configChanged = false; - - writeTimestamps (buf); -/*MGEN:IF(Class.ExistOptionals)*/ - for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) - buf.putOctet(presenceMask[idx]); -/*MGEN:ENDIF*/ -/*MGEN:Class.WriteProperties*/ -} - -void /*MGEN:Class.NameCap*/::writeStatistics (Buffer& buf, bool skipHeaders) -{ - sys::Mutex::ScopedLock mutex(accessLock); - instChanged = false; -/*MGEN:IF(Class.ExistPerThreadAssign)*/ - for (int idx = 0; idx < maxThreads; idx++) { - struct PerThreadStats* threadStats = perThreadStatsArray[idx]; - if (threadStats != 0) { -/*MGEN:Class.PerThreadAssign*/ - } - } -/*MGEN:ENDIF*/ -/*MGEN:IF(Class.ExistPerThreadStats)*/ - struct PerThreadStats totals; - aggregatePerThreadStats(&totals); -/*MGEN:ENDIF*/ -/*MGEN:Class.Assign*/ - if (!skipHeaders) - writeTimestamps (buf); -/*MGEN:Class.WriteStatistics*/ - - // Maintenance of hi-lo statistics -/*MGEN:Class.HiLoStatResets*/ -/*MGEN:IF(Class.ExistPerThreadResets)*/ - for (int idx = 0; idx < maxThreads; idx++) { - struct PerThreadStats* threadStats = perThreadStatsArray[idx]; - if (threadStats != 0) { -/*MGEN:Class.PerThreadHiLoStatResets*/ - } - } -/*MGEN:ENDIF*/ -} - -void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) -{ - Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; -/*MGEN:Class.MethodHandlers*/ - outBuf.putLong (status); - outBuf.putShortString (Manageable::StatusText (status)); -} - -/*MGEN:Class.EventMethodBodies*/ diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h deleted file mode 100644 index 40ad20eb85..0000000000 --- a/qpid/cpp/managementgen/templates/Class.h +++ /dev/null @@ -1,106 +0,0 @@ -/*MGEN:commentPrefix=//*/ -#ifndef _MANAGEMENT_/*MGEN:Class.NameUpper*/_ -#define _MANAGEMENT_/*MGEN:Class.NameUpper*/_ - -// -// 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. -// - -/*MGEN:Root.Disclaimer*/ - -#include "qpid/management/ManagementObject.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/framing/Uuid.h" - -namespace qpid { -namespace management { - -class /*MGEN:Class.NameCap*/ : public ManagementObject -{ - private: - - static std::string packageName; - static std::string className; - static uint8_t md5Sum[16]; -/*MGEN:IF(Class.ExistOptionals)*/ - uint8_t presenceMask[/*MGEN:Class.PresenceMaskBytes*/]; -/*MGEN:Class.PresenceMaskConstants*/ -/*MGEN:ENDIF*/ - - // Properties -/*MGEN:Class.ConfigDeclarations*/ - // Statistics -/*MGEN:Class.InstDeclarations*/ -/*MGEN:IF(Class.ExistPerThreadStats)*/ - // Per-Thread Statistics - struct PerThreadStats { -/*MGEN:Class.PerThreadDeclarations*/ - }; - - struct PerThreadStats** perThreadStatsArray; - - inline struct PerThreadStats* getThreadStats() { - int index = getThreadIndex(); - struct PerThreadStats* threadStats = perThreadStatsArray[index]; - if (threadStats == 0) { - threadStats = new(PerThreadStats); - perThreadStatsArray[index] = threadStats; -/*MGEN:Class.InitializePerThreadElements*/ - } - return threadStats; - } - - void aggregatePerThreadStats(struct PerThreadStats*); -/*MGEN:ENDIF*/ - // Private Methods - static void writeSchema (qpid::framing::Buffer& buf); - void writeProperties (qpid::framing::Buffer& buf); - void writeStatistics (qpid::framing::Buffer& buf, - bool skipHeaders = false); - void doMethod (std::string methodName, - qpid::framing::Buffer& inBuf, - qpid::framing::Buffer& outBuf); - writeSchemaCall_t getWriteSchemaCall(void) { return writeSchema; } -/*MGEN:IF(Class.NoStatistics)*/ - // Stub for getInstChanged. There are no statistics in this class. - bool getInstChanged (void) { return false; } -/*MGEN:ENDIF*/ - public: - - /*MGEN:Class.NameCap*/ (ManagementAgent* agent, - Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); - ~/*MGEN:Class.NameCap*/ (void); - - /*MGEN:Class.SetGeneralReferenceDeclaration*/ - - static void registerClass (ManagementAgent* agent); - std::string& getPackageName (void) { return packageName; } - std::string& getClassName (void) { return className; } - uint8_t* getMd5Sum (void) { return md5Sum; } - - // Method IDs -/*MGEN:Class.MethodIdDeclarations*/ - // Accessor Methods -/*MGEN:Class.AccessorMethods*/ - // Event Methods -/*MGEN:Class.EventMethodDecls*/ -}; - -}} - -#endif /*!_MANAGEMENT_/*MGEN:Class.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/templates/Makefile.mk b/qpid/cpp/managementgen/templates/Makefile.mk deleted file mode 100644 index 0e6454c13a..0000000000 --- a/qpid/cpp/managementgen/templates/Makefile.mk +++ /dev/null @@ -1,37 +0,0 @@ -# -# 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. -# -/*MGEN:commentPrefix=#*/ -/*MGEN:mgenDir=$(mgen_dir)*/ -/*MGEN:specDir=$(top_srcdir)/../specs*/ -/*MGEN:Root.Disclaimer*/ - -mgen_generator=/*MGEN:Makefile.GenSources*/ - -mgen_broker_cpp=/*MGEN:Makefile.GenCppFiles*/ - -# Header file install rules. -qpid_managementdir = $(includedir)/qpid/management -dist_qpid_management_HEADERS = /*MGEN:Makefile.GenHFiles*/ - -if GENERATE -$(srcdir)/managementgen.mk: $(mgen_generator) - $(mgen_cmd) - -$(mgen_generator): -endif diff --git a/qpid/cpp/managementgen/templates/Package.cpp b/qpid/cpp/managementgen/templates/Package.cpp deleted file mode 100644 index 15e7fc15ec..0000000000 --- a/qpid/cpp/managementgen/templates/Package.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/*MGEN:commentPrefix=//*/ -// -// 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. -// - -/*MGEN:Root.Disclaimer*/ - -#include "Package/*MGEN:Schema.PackageNameCap*/.h" -/*MGEN:Schema.ClassIncludes*/ - -using namespace qpid::management; - -Package/*MGEN:Schema.PackageNameCap*/::Package/*MGEN:Schema.PackageNameCap*/ (ManagementAgent* agent) -{ -/*MGEN:Schema.ClassRegisters*/ -} - diff --git a/qpid/cpp/managementgen/templates/Package.h b/qpid/cpp/managementgen/templates/Package.h deleted file mode 100644 index 3f3ac35ffc..0000000000 --- a/qpid/cpp/managementgen/templates/Package.h +++ /dev/null @@ -1,41 +0,0 @@ -/*MGEN:commentPrefix=//*/ -#ifndef _MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ -#define _MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ - -// -// 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. -// - -/*MGEN:Root.Disclaimer*/ - -#include "qpid/agent/ManagementAgent.h" - -namespace qpid { -namespace management { - -class Package/*MGEN:Schema.PackageNameCap*/ -{ - public: - Package/*MGEN:Schema.PackageNameCap*/ (ManagementAgent* agent); - ~Package/*MGEN:Schema.PackageNameCap*/ () {} -}; - -}} - - -#endif /*!_MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_*/ -- cgit v1.2.1 From 79ffcd4b5cf08b435881dd28d1a673f287d42532 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Fri, 5 Sep 2008 18:37:36 +0000 Subject: QPID-1274 - Made qmf-gen smarter about finding its data files git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@692508 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf-gen | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index 840733bf7b..10750f2a34 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -25,15 +25,32 @@ from qmf.generate import Generator from optparse import OptionParser dataPath = os.path.dirname(sys.argv[0]) + "/qmf/" +defaultTypeFile = dataPath + "management-types.xml" +defaultTemplateDir = dataPath + "templates" +found = True + +try: + s = os.stat(defaultTypeFile) +except: + found = False + +if not found: + path = sys.path + for item in path: + if os.path.basename(item) == "site-packages": + found = True + dataPath = item + "/qmf/" + defaultTypeFile = dataPath + "management-types.xml" + defaultTemplateDir = dataPath + "templates" # Set command line options usage = "usage: %prog [options] schema-document out-directory" parser = OptionParser (usage=usage) parser.add_option ("-m", "--makefile", dest="makefile", metavar="FILE", help="Makefile fragment") -parser.add_option ("-t", "--typefile", dest="typefile", metavar="FILE", default=dataPath + "management-types.xml", +parser.add_option ("-t", "--typefile", dest="typefile", metavar="FILE", default=defaultTypeFile, help="Type descriptor file") -parser.add_option ("-d", "--templatedir", dest="templatedir", metavar="DIR", default=dataPath + "templates", +parser.add_option ("-d", "--templatedir", dest="templatedir", metavar="DIR", default=defaultTemplateDir, help="Template directory") (opts, args) = parser.parse_args () -- cgit v1.2.1 From c513257dc8159a6ba70298e00926a45666840a91 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Tue, 9 Sep 2008 17:31:47 +0000 Subject: QPID-1274 - qmf-gen can now generate code from multiple schema files. Uses __file__ as a better way to locate data files. Added code generation for ACL schema. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@693523 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf-gen | 49 +++++++++++++--------------------- qpid/cpp/managementgen/qmf/generate.py | 5 ++++ qpid/cpp/managementgen/qmf/schema.py | 4 +++ 3 files changed, 27 insertions(+), 31 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index 10750f2a34..a6f022926c 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -24,27 +24,12 @@ from qmf.schema import PackageSchema, SchemaClass from qmf.generate import Generator from optparse import OptionParser -dataPath = os.path.dirname(sys.argv[0]) + "/qmf/" -defaultTypeFile = dataPath + "management-types.xml" -defaultTemplateDir = dataPath + "templates" -found = True - -try: - s = os.stat(defaultTypeFile) -except: - found = False - -if not found: - path = sys.path - for item in path: - if os.path.basename(item) == "site-packages": - found = True - dataPath = item + "/qmf/" - defaultTypeFile = dataPath + "management-types.xml" - defaultTemplateDir = dataPath + "templates" +dataPath = os.path.dirname(Generator.getModulePath()) +defaultTypeFile = dataPath + "/management-types.xml" +defaultTemplateDir = dataPath + "/templates" # Set command line options -usage = "usage: %prog [options] schema-document out-directory" +usage = "usage: %prog [options] schema-document..." parser = OptionParser (usage=usage) parser.add_option ("-m", "--makefile", dest="makefile", metavar="FILE", help="Makefile fragment") @@ -52,26 +37,28 @@ parser.add_option ("-t", "--typefile", dest="typefile", metavar="FILE", default= help="Type descriptor file") parser.add_option ("-d", "--templatedir", dest="templatedir", metavar="DIR", default=defaultTemplateDir, help="Template directory") +parser.add_option ("-o", "--outputdir", dest="outputdir", metavar="DIR", default="./", + help="Output directory") (opts, args) = parser.parse_args () -if len (args) < 2: - parser.error ("Too few arguments") - typefile = opts.typefile templatedir = opts.templatedir +outdir = opts.outputdir +gen = Generator (outdir, templatedir) -schemafile = args[0] -outdir = args[1] +if len(args) == 0: + print "no input files" + parser.exit() -gen = Generator (outdir, templatedir) -schema = PackageSchema (typefile, schemafile, opts) +for schemafile in args: + schema = PackageSchema (typefile, schemafile, opts) -gen.makeClassFiles ("Class.h", schema) -gen.makeClassFiles ("Class.cpp", schema) -gen.makeMethodFiles ("Args.h", schema) -gen.makePackageFile ("Package.h", schema) -gen.makePackageFile ("Package.cpp", schema) + gen.makeClassFiles ("Class.h", schema) + gen.makeClassFiles ("Class.cpp", schema) + gen.makeMethodFiles ("Args.h", schema) + gen.makePackageFile ("Package.h", schema) + gen.makePackageFile ("Package.cpp", schema) if opts.makefile != None: gen.makeSingleFile ("Makefile.mk", opts.makefile, force=True) diff --git a/qpid/cpp/managementgen/qmf/generate.py b/qpid/cpp/managementgen/qmf/generate.py index 70735b208a..e977ce2e9d 100755 --- a/qpid/cpp/managementgen/qmf/generate.py +++ b/qpid/cpp/managementgen/qmf/generate.py @@ -298,3 +298,8 @@ class Generator: self.templateFiles.append (templateFile) stream = template.expand (makefile) self.writeIfChanged (stream, target, force) + + @staticmethod + def getModulePath(): + return __file__ + diff --git a/qpid/cpp/managementgen/qmf/schema.py b/qpid/cpp/managementgen/qmf/schema.py index e666bdbb39..9263c29543 100755 --- a/qpid/cpp/managementgen/qmf/schema.py +++ b/qpid/cpp/managementgen/qmf/schema.py @@ -656,6 +656,7 @@ class SchemaEvent: self.name = None self.desc = None self.args = [] + self.defaultSeverity = None attrs = node.attributes for idx in range (attrs.length): @@ -667,6 +668,9 @@ class SchemaEvent: elif key == 'desc': self.desc = val + elif key == 'defaultSeverity': + self.defaultSeverity = val + else: raise ValueError ("Unknown attribute in event '%s'" % key) -- cgit v1.2.1 From 4fd4650b7f657610e94a909cdb14f0b06ac5c4a4 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Tue, 9 Sep 2008 18:25:48 +0000 Subject: Removed @staticmethod decorator which is unsupported by older Python versions git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@693548 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf/generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf/generate.py b/qpid/cpp/managementgen/qmf/generate.py index e977ce2e9d..9050ca8ced 100755 --- a/qpid/cpp/managementgen/qmf/generate.py +++ b/qpid/cpp/managementgen/qmf/generate.py @@ -299,7 +299,7 @@ class Generator: stream = template.expand (makefile) self.writeIfChanged (stream, target, force) - @staticmethod def getModulePath(): return __file__ + getModulePath = staticmethod(getModulePath) -- cgit v1.2.1 From f64522fbecc560ad4d0335fe95f4c294760232b0 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 10 Sep 2008 19:14:01 +0000 Subject: QPID-1279 Implementations of management methods can now return error strings along with its own error codes git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@693933 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf/schema.py | 4 ++-- qpid/cpp/managementgen/qmf/templates/Class.cpp | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf/schema.py b/qpid/cpp/managementgen/qmf/schema.py index 9263c29543..26bad618f7 100755 --- a/qpid/cpp/managementgen/qmf/schema.py +++ b/qpid/cpp/managementgen/qmf/schema.py @@ -1004,9 +1004,9 @@ class SchemaClass: arg.name, "inBuf") + ";\n") stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ - method.getName().upper() + ", ioArgs);\n") + method.getName().upper() + ", ioArgs, text);\n") stream.write (" outBuf.putLong (status);\n") - stream.write (" outBuf.putShortString (Manageable::StatusText (status));\n") + stream.write (" outBuf.putShortString (Manageable::StatusText (status, text));\n") for arg in method.args: if arg.getDir () == "O" or arg.getDir () == "IO": stream.write (" " +\ diff --git a/qpid/cpp/managementgen/qmf/templates/Class.cpp b/qpid/cpp/managementgen/qmf/templates/Class.cpp index 2a0e55b34d..018f325ff1 100644 --- a/qpid/cpp/managementgen/qmf/templates/Class.cpp +++ b/qpid/cpp/managementgen/qmf/templates/Class.cpp @@ -172,9 +172,10 @@ void /*MGEN:Class.NameCap*/::writeStatistics (Buffer& buf, bool skipHeaders) void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) { Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; + std::string text; /*MGEN:Class.MethodHandlers*/ - outBuf.putLong (status); - outBuf.putShortString (Manageable::StatusText (status)); + outBuf.putLong(status); + outBuf.putShortString(Manageable::StatusText(status, text)); } /*MGEN:Class.EventMethodBodies*/ -- cgit v1.2.1 From 9659efe01f8d8cb2b4b3e1a27d16de35bd8d7db7 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Mon, 15 Sep 2008 15:37:59 +0000 Subject: QPID-1274 - Changed C++ namespace for generated management code. Improved efficiency of generated functions to use const references for non-simple types. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@695511 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf-gen | 15 ++-- qpid/cpp/managementgen/qmf/generate.py | 19 +++-- qpid/cpp/managementgen/qmf/management-types.xml | 12 ++-- qpid/cpp/managementgen/qmf/schema.py | 88 ++++++++++++++++++------ qpid/cpp/managementgen/qmf/templates/Args.h | 8 +-- qpid/cpp/managementgen/qmf/templates/Class.cpp | 11 +-- qpid/cpp/managementgen/qmf/templates/Class.h | 24 +++---- qpid/cpp/managementgen/qmf/templates/Package.cpp | 6 +- qpid/cpp/managementgen/qmf/templates/Package.h | 12 ++-- 9 files changed, 126 insertions(+), 69 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index a6f022926c..523579fe6c 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -20,7 +20,7 @@ # import sys import os -from qmf.schema import PackageSchema, SchemaClass +from qmf.schema import SchemaPackage, SchemaClass from qmf.generate import Generator from optparse import OptionParser @@ -52,13 +52,14 @@ if len(args) == 0: parser.exit() for schemafile in args: - schema = PackageSchema (typefile, schemafile, opts) + package = SchemaPackage (typefile, schemafile, opts) - gen.makeClassFiles ("Class.h", schema) - gen.makeClassFiles ("Class.cpp", schema) - gen.makeMethodFiles ("Args.h", schema) - gen.makePackageFile ("Package.h", schema) - gen.makePackageFile ("Package.cpp", schema) + gen.setPackage (package.packageName) + gen.makeClassFiles ("Class.h", package) + gen.makeClassFiles ("Class.cpp", package) + gen.makeMethodFiles ("Args.h", package) + gen.makePackageFile ("Package.h", package) + gen.makePackageFile ("Package.cpp", package) if opts.makefile != None: gen.makeSingleFile ("Makefile.mk", opts.makefile, force=True) diff --git a/qpid/cpp/managementgen/qmf/generate.py b/qpid/cpp/managementgen/qmf/generate.py index 9050ca8ced..8b8eb43252 100755 --- a/qpid/cpp/managementgen/qmf/generate.py +++ b/qpid/cpp/managementgen/qmf/generate.py @@ -168,15 +168,20 @@ class Generator: return newpath + "/" def __init__ (self, destDir, templateDir): - self.dest = self.normalize (destDir) - self.input = self.normalize (templateDir) - self.filelists = {} + self.dest = self.normalize (destDir) + self.input = self.normalize (templateDir) + self.packagePath = self.dest + self.filelists = {} self.filelists["h"] = [] self.filelists["cpp"] = [] self.filelists["mk"] = [] self.templateFiles = [] self.variables = {} + def setPackage (self, packageName): + path = "/".join(packageName.split(".")) + self.packagePath = self.normalize(self.dest + path) + def genDisclaimer (self, stream, variables): prefix = variables["commentPrefix"] stream.write (prefix + " This source file was created by a code generator.\n") @@ -191,7 +196,7 @@ class Generator: def writeIfChanged (self, stream, target, force=False): ext = self.fileExt (target) self.filelists[ext].append (target) - tempFile = self.dest + "gen.tmp" + tempFile = self.packagePath + "gen.tmp" fd = open (tempFile, "w") fd.write (stream.getvalue ()) fd.close () @@ -216,7 +221,7 @@ class Generator: if dot == -1: raise ValueError ("Invalid template file name %s" % templateFile) extension = templateFile[dot:len (templateFile)] - path = self.dest + "Package" + schema.getPackageNameCap() + extension + path = self.packagePath + "Package" + extension return path def targetClassFile (self, _class, templateFile): @@ -224,7 +229,7 @@ class Generator: if dot == -1: raise ValueError ("Invalid template file name %s" % templateFile) extension = templateFile[dot:len (templateFile)] - path = self.dest + _class.getNameCap () + extension + path = self.packagePath + _class.getNameCap () + extension return path def targetMethodFile (self, method, templateFile): @@ -233,7 +238,7 @@ class Generator: if dot == -1: raise ValueError ("Invalid template file name %s" % templateFile) extension = templateFile[dot:] - path = self.dest + "Args" + method.getFullName () + extension + path = self.packagePath + "Args" + method.getFullName () + extension return path def initExpansion (self): diff --git a/qpid/cpp/managementgen/qmf/management-types.xml b/qpid/cpp/managementgen/qmf/management-types.xml index 31337b23bc..56d2488803 100644 --- a/qpid/cpp/managementgen/qmf/management-types.xml +++ b/qpid/cpp/managementgen/qmf/management-types.xml @@ -19,7 +19,7 @@ under the License. --> - + @@ -29,14 +29,14 @@ - - - + + + - - + + diff --git a/qpid/cpp/managementgen/qmf/schema.py b/qpid/cpp/managementgen/qmf/schema.py index 26bad618f7..12a325ed80 100755 --- a/qpid/cpp/managementgen/qmf/schema.py +++ b/qpid/cpp/managementgen/qmf/schema.py @@ -35,6 +35,7 @@ class SchemaType: self.accessor = None self.init = "0" self.perThread = False + self.byRef = False attrs = node.attributes for idx in range (attrs.length): @@ -69,6 +70,11 @@ class SchemaType: raise ValueError ("Expected 'y' in perThread attribute") self.perThread = True + elif key == 'byRef': + if val != 'y': + raise ValueError ("Expected 'y' in byRef attribute") + self.byRef = True + else: raise ValueError ("Unknown attribute in type '%s'" % key) @@ -76,6 +82,11 @@ class SchemaType: self.encode == None or self.decode == None: raise ValueError ("Missing required attribute(s) in type") + if self.byRef: + self.asArg = "const " + self.cpp + "&" + else: + self.asArg = self.cpp + def getName (self): return self.name @@ -87,9 +98,9 @@ class SchemaType: else: prefix = "" if self.accessor == "direct": - stream.write (" inline void set_" + varName + " (" + self.cpp + " val) {\n"); + stream.write (" inline void set_" + varName + " (" + self.asArg + " val) {\n"); if not self.perThread: - stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") if self.style != "mma": stream.write (" " + prefix + varName + " = val;\n") if optional: @@ -110,9 +121,9 @@ class SchemaType: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n") if self.style != "mma": - stream.write (" inline " + self.cpp + "& get_" + varName + "() {\n"); + stream.write (" inline " + self.asArg + " get_" + varName + "() {\n"); if not self.perThread: - stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") stream.write (" return " + prefix + varName + ";\n") stream.write (" }\n") if optional: @@ -125,9 +136,9 @@ class SchemaType: stream.write (" return (presenceMask[presenceByte_%s] & presenceMask_%s) != 0;\n" % (varName, varName)) stream.write (" }\n") elif self.accessor == "counter": - stream.write (" inline void inc_" + varName + " (" + self.cpp + " by = 1) {\n"); + stream.write (" inline void inc_" + varName + " (" + self.asArg + " by = 1) {\n"); if not self.perThread: - stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") stream.write (" " + prefix + varName + " += by;\n") if self.style == "wm": stream.write (" if (" + varName + "High < " + varName + ")\n") @@ -135,9 +146,9 @@ class SchemaType: if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") stream.write (" }\n"); - stream.write (" inline void dec_" + varName + " (" + self.cpp + " by = 1) {\n"); + stream.write (" inline void dec_" + varName + " (" + self.asArg + " by = 1) {\n"); if not self.perThread: - stream.write (" sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") stream.write (" " + prefix + varName + " -= by;\n") if self.style == "wm": stream.write (" if (" + varName + "Low > " + varName + ")\n") @@ -316,7 +327,7 @@ class SchemaProperty: stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") def genFormalParam (self, stream, variables): - stream.write (self.type.type.cpp + " _" + self.name) + stream.write (self.type.type.asArg + " _" + self.name) def genAccessor (self, stream): self.type.type.genAccessor (stream, self.name, "configChanged", self.isOptional == 1) @@ -578,7 +589,7 @@ class SchemaArg: stream.write (" buf.put (ft);\n\n") def genFormalParam (self, stream, variables): - stream.write ("%s _%s" % (self.type.type.cpp, self.name)) + stream.write ("%s _%s" % (self.type.type.asArg, self.name)) #===================================================================================== # @@ -631,12 +642,21 @@ class SchemaMethod: def genNameCamel (self, stream, variables): stream.write (self.getFullName ()) + def genOpenNamespaces (self, stream, variables): + self.parent.genOpenNamespaces(stream, variables) + + def genCloseNamespaces (self, stream, variables): + self.parent.genCloseNamespaces(stream, variables) + 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 genNamePackageLower (self, stream, variables): + self.parent.genNamePackageLower(stream, variables) + def genSchema (self, stream, variables): stream.write (" ft = FieldTable ();\n") stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") @@ -702,7 +722,7 @@ class SchemaEvent: if count < len(self.args): stream.write(", ") stream.write(") {\n") - stream.write(" sys::Mutex::ScopedLock mutex(getMutex());\n") + stream.write(" ::qpid::sys::Mutex::ScopedLock mutex(getMutex());\n") stream.write(" Buffer* buf = startEventLH();\n") stream.write(" objectId.encode(*buf);\n") stream.write(" buf->putShortString(packageName);\n") @@ -879,6 +899,10 @@ class SchemaClass: if inst.assign == None: inst.genAccessor (stream) + def genCloseNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("}") + def genConfigCount (self, stream, variables): stream.write ("%d" % len (self.properties)) @@ -981,6 +1005,9 @@ class SchemaClass: if element.type.type.perThread: element.genDeclaration (stream, " ") + def genNamespace (self, stream, variables): + stream.write("::".join(self.packageName.split("."))) + def genMethodArgIncludes (self, stream, variables): for method in self.methods: if method.getArgCount () > 0: @@ -993,7 +1020,7 @@ class SchemaClass: for method in self.methods: stream.write ("\n if (methodName == \"" + method.getName () + "\") {\n") if method.getArgCount () == 0: - stream.write (" ArgsNone ioArgs;\n") + stream.write (" ::qpid::management::ArgsNone ioArgs;\n") else: stream.write (" Args" + method.getFullName () + " ioArgs;\n") for arg in method.args: @@ -1006,7 +1033,7 @@ class SchemaClass: stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ method.getName().upper() + ", ioArgs, text);\n") stream.write (" outBuf.putLong (status);\n") - stream.write (" outBuf.putShortString (Manageable::StatusText (status, text));\n") + stream.write (" outBuf.putShortString (::qpid::management::Manageable::StatusText (status, text));\n") for arg in method.args: if arg.getDir () == "O" or arg.getDir () == "IO": stream.write (" " +\ @@ -1015,6 +1042,10 @@ class SchemaClass: arg.name, "outBuf") + ";\n") stream.write (" return;\n }\n") + def genOpenNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("namespace %s {\n" % item) + def genPresenceMaskBytes (self, stream, variables): count = 0 for prop in self.properties: @@ -1040,7 +1071,7 @@ class SchemaClass: def genSetGeneralReferenceDeclaration (self, stream, variables): for prop in self.properties: if prop.isGeneralRef: - stream.write ("void setReference(ObjectId objectId) { " + prop.name + " = objectId; }\n") + stream.write ("void setReference(::qpid::management::ObjectId objectId) { " + prop.name + " = objectId; }\n") def genStatisticSchema (self, stream, variables): for stat in self.statistics: @@ -1075,7 +1106,7 @@ class SchemaClass: def genParentArg (self, stream, variables): for config in self.properties: if config.isParentRef == 1: - stream.write (", Manageable* _parent") + stream.write (", ::qpid::management::Manageable* _parent") return def genParentRefAssignment (self, stream, variables): @@ -1112,7 +1143,7 @@ class SchemaClass: -class PackageSchema: +class SchemaPackage: def __init__ (self, typefile, schemafile, options): self.classes = [] @@ -1124,7 +1155,9 @@ class PackageSchema: if document.tagName != 'schema': raise ValueError ("Expected 'schema' node") attrs = document.attributes - self.packageName = makeValidCppSymbol(attrs['package'].nodeValue) + pname = attrs['package'].nodeValue + namelist = pname.split('.') + self.packageName = ".".join(namelist) children = document.childNodes for child in children: @@ -1148,14 +1181,29 @@ class PackageSchema: def getPackageNameCap (self): return capitalize(self.packageName) + def getPackageNameLower (self): + return self.packageName.lower() + def getClasses (self): return self.classes + def genCloseNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("}") + + def genNamespace (self, stream, variables): + stream.write("::".join(self.packageName.split("."))) + + def genOpenNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("namespace %s {\n" % item) + def genPackageNameUpper (self, stream, variables): - stream.write (self.packageName.upper ()) + up = "_".join(self.packageName.split(".")) + stream.write (up.upper()) - def genPackageNameCap (self, stream, variables): - stream.write (self.getPackageNameCap ()) + def genNamePackageLower (self, stream, variables): + stream.write (self.packageName.lower ()) def genClassIncludes (self, stream, variables): for _class in self.classes: diff --git a/qpid/cpp/managementgen/qmf/templates/Args.h b/qpid/cpp/managementgen/qmf/templates/Args.h index 576d891a3f..89a5bec9b9 100644 --- a/qpid/cpp/managementgen/qmf/templates/Args.h +++ b/qpid/cpp/managementgen/qmf/templates/Args.h @@ -26,15 +26,15 @@ #include "qpid/management/Args.h" #include -namespace qpid { -namespace management { +namespace qmf { +/*MGEN:Method.OpenNamespaces*/ -class Args/*MGEN:Method.NameCamel*/ : public Args + class Args/*MGEN:Method.NameCamel*/ : public ::qpid::management::Args { public: /*MGEN:Method.Arguments*/ }; -}} +}/*MGEN:Method.CloseNamespaces*/ #endif /*!_ARGS_/*MGEN:Method.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmf/templates/Class.cpp b/qpid/cpp/managementgen/qmf/templates/Class.cpp index 018f325ff1..964e6f8349 100644 --- a/qpid/cpp/managementgen/qmf/templates/Class.cpp +++ b/qpid/cpp/managementgen/qmf/templates/Class.cpp @@ -27,9 +27,12 @@ #include "/*MGEN:Class.NameCap*/.h" /*MGEN:Class.MethodArgIncludes*/ -using namespace qpid::management; -using namespace qpid::sys; +using namespace qmf::/*MGEN:Class.Namespace*/; using namespace qpid::framing; +using qpid::management::ManagementAgent; +using qpid::management::Manageable; +using qpid::management::ManagementObject; +using qpid::management::Args; using std::string; string /*MGEN:Class.NameCap*/::packageName = string ("/*MGEN:Class.NamePackageLower*/"); @@ -125,7 +128,7 @@ void /*MGEN:Class.NameCap*/::aggregatePerThreadStats(struct PerThreadStats* tota void /*MGEN:Class.NameCap*/::writeProperties (Buffer& buf) { - sys::Mutex::ScopedLock mutex(accessLock); + ::qpid::sys::Mutex::ScopedLock mutex(accessLock); configChanged = false; writeTimestamps (buf); @@ -138,7 +141,7 @@ void /*MGEN:Class.NameCap*/::writeProperties (Buffer& buf) void /*MGEN:Class.NameCap*/::writeStatistics (Buffer& buf, bool skipHeaders) { - sys::Mutex::ScopedLock mutex(accessLock); + ::qpid::sys::Mutex::ScopedLock mutex(accessLock); instChanged = false; /*MGEN:IF(Class.ExistPerThreadAssign)*/ for (int idx = 0; idx < maxThreads; idx++) { diff --git a/qpid/cpp/managementgen/qmf/templates/Class.h b/qpid/cpp/managementgen/qmf/templates/Class.h index 40ad20eb85..99ebc68789 100644 --- a/qpid/cpp/managementgen/qmf/templates/Class.h +++ b/qpid/cpp/managementgen/qmf/templates/Class.h @@ -27,10 +27,10 @@ #include "qpid/framing/FieldTable.h" #include "qpid/framing/Uuid.h" -namespace qpid { -namespace management { +namespace qmf { +/*MGEN:Class.OpenNamespaces*/ -class /*MGEN:Class.NameCap*/ : public ManagementObject +class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject { private: @@ -68,13 +68,13 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject void aggregatePerThreadStats(struct PerThreadStats*); /*MGEN:ENDIF*/ // Private Methods - static void writeSchema (qpid::framing::Buffer& buf); - void writeProperties (qpid::framing::Buffer& buf); - void writeStatistics (qpid::framing::Buffer& buf, + static void writeSchema (::qpid::framing::Buffer& buf); + void writeProperties (::qpid::framing::Buffer& buf); + void writeStatistics (::qpid::framing::Buffer& buf, bool skipHeaders = false); void doMethod (std::string methodName, - qpid::framing::Buffer& inBuf, - qpid::framing::Buffer& outBuf); + ::qpid::framing::Buffer& inBuf, + ::qpid::framing::Buffer& outBuf); writeSchemaCall_t getWriteSchemaCall(void) { return writeSchema; } /*MGEN:IF(Class.NoStatistics)*/ // Stub for getInstChanged. There are no statistics in this class. @@ -82,13 +82,13 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject /*MGEN:ENDIF*/ public: - /*MGEN:Class.NameCap*/ (ManagementAgent* agent, - Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); + /*MGEN:Class.NameCap*/ (::qpid::management::ManagementAgent* agent, + ::qpid::management::Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); ~/*MGEN:Class.NameCap*/ (void); /*MGEN:Class.SetGeneralReferenceDeclaration*/ - static void registerClass (ManagementAgent* agent); + static void registerClass (::qpid::management::ManagementAgent* agent); std::string& getPackageName (void) { return packageName; } std::string& getClassName (void) { return className; } uint8_t* getMd5Sum (void) { return md5Sum; } @@ -101,6 +101,6 @@ class /*MGEN:Class.NameCap*/ : public ManagementObject /*MGEN:Class.EventMethodDecls*/ }; -}} +}/*MGEN:Class.CloseNamespaces*/ #endif /*!_MANAGEMENT_/*MGEN:Class.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmf/templates/Package.cpp b/qpid/cpp/managementgen/qmf/templates/Package.cpp index 15e7fc15ec..f6bd7f4654 100644 --- a/qpid/cpp/managementgen/qmf/templates/Package.cpp +++ b/qpid/cpp/managementgen/qmf/templates/Package.cpp @@ -20,12 +20,12 @@ /*MGEN:Root.Disclaimer*/ -#include "Package/*MGEN:Schema.PackageNameCap*/.h" +#include "Package.h" /*MGEN:Schema.ClassIncludes*/ -using namespace qpid::management; +using namespace qmf::/*MGEN:Schema.Namespace*/; -Package/*MGEN:Schema.PackageNameCap*/::Package/*MGEN:Schema.PackageNameCap*/ (ManagementAgent* agent) +Package::Package (::qpid::management::ManagementAgent* agent) { /*MGEN:Schema.ClassRegisters*/ } diff --git a/qpid/cpp/managementgen/qmf/templates/Package.h b/qpid/cpp/managementgen/qmf/templates/Package.h index 3f3ac35ffc..0ad7060b9e 100644 --- a/qpid/cpp/managementgen/qmf/templates/Package.h +++ b/qpid/cpp/managementgen/qmf/templates/Package.h @@ -25,17 +25,17 @@ #include "qpid/agent/ManagementAgent.h" -namespace qpid { -namespace management { +namespace qmf { +/*MGEN:Class.OpenNamespaces*/ -class Package/*MGEN:Schema.PackageNameCap*/ +class Package { public: - Package/*MGEN:Schema.PackageNameCap*/ (ManagementAgent* agent); - ~Package/*MGEN:Schema.PackageNameCap*/ () {} + Package (::qpid::management::ManagementAgent* agent); + ~Package () {} }; -}} +}/*MGEN:Class.CloseNamespaces*/ #endif /*!_MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_*/ -- cgit v1.2.1 From e4b313f1120a520d353808ff48cc0d37d9e3728d Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Mon, 15 Sep 2008 19:01:32 +0000 Subject: Fixed a bug affecting 'make install' for generated qmf headers git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@695580 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf/templates/Makefile.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf/templates/Makefile.mk b/qpid/cpp/managementgen/qmf/templates/Makefile.mk index 0e6454c13a..06b600272a 100644 --- a/qpid/cpp/managementgen/qmf/templates/Makefile.mk +++ b/qpid/cpp/managementgen/qmf/templates/Makefile.mk @@ -26,8 +26,8 @@ mgen_generator=/*MGEN:Makefile.GenSources*/ mgen_broker_cpp=/*MGEN:Makefile.GenCppFiles*/ # Header file install rules. -qpid_managementdir = $(includedir)/qpid/management -dist_qpid_management_HEADERS = /*MGEN:Makefile.GenHFiles*/ +qpid_managementdir = $(includedir)/qmf +nobase_dist_qpid_management_HEADERS = /*MGEN:Makefile.GenHFiles*/ if GENERATE $(srcdir)/managementgen.mk: $(mgen_generator) -- cgit v1.2.1 From e307d4138fff7b2635ce808eea50f01f4d542a85 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Mon, 15 Sep 2008 21:45:01 +0000 Subject: An improved way of dealing with installed headers git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@695646 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf/generate.py | 22 ++++++++++++++++++++-- qpid/cpp/managementgen/qmf/templates/Makefile.mk | 4 +--- 2 files changed, 21 insertions(+), 5 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf/generate.py b/qpid/cpp/managementgen/qmf/generate.py index 8b8eb43252..7346200a28 100755 --- a/qpid/cpp/managementgen/qmf/generate.py +++ b/qpid/cpp/managementgen/qmf/generate.py @@ -100,9 +100,10 @@ class Template: class Makefile: """ Object representing a makefile fragment """ - def __init__ (self, filelists, templateFiles): + def __init__ (self, filelists, templateFiles, packagelist): self.filelists = filelists self.templateFiles = templateFiles + self.packagelist = packagelist def genGenSources (self, stream, variables): mdir = variables["mgenDir"] @@ -139,6 +140,21 @@ class Makefile: stream.write (" \\\n ") stream.write (file) + def genHeaderInstalls (self, stream, variables): + for package in self.packagelist: + name = "_".join(package.split("/")) + stream.write(name + "dir = $(includedir)/qmf/" + package + "\n") + stream.write("dist_" + name + "_HEADERS = ") + first = True + for file in self.filelists["h"]: + if file.find("gen/qmf/" + package) == 0: + if first: + first = False + else: + stream.write (" \\\n ") + stream.write(file) + stream.write("\n\n") + class Generator: """ @@ -175,11 +191,13 @@ class Generator: self.filelists["h"] = [] self.filelists["cpp"] = [] self.filelists["mk"] = [] + self.packagelist = [] self.templateFiles = [] self.variables = {} def setPackage (self, packageName): path = "/".join(packageName.split(".")) + self.packagelist.append(path) self.packagePath = self.normalize(self.dest + path) def genDisclaimer (self, stream, variables): @@ -298,7 +316,7 @@ class Generator: def makeSingleFile (self, templateFile, target, force=False): """ Generate a single expanded template """ - makefile = Makefile (self.filelists, self.templateFiles) + makefile = Makefile (self.filelists, self.templateFiles, self.packagelist) template = Template (self.input + templateFile, self) self.templateFiles.append (templateFile) stream = template.expand (makefile) diff --git a/qpid/cpp/managementgen/qmf/templates/Makefile.mk b/qpid/cpp/managementgen/qmf/templates/Makefile.mk index 06b600272a..6b06e74b46 100644 --- a/qpid/cpp/managementgen/qmf/templates/Makefile.mk +++ b/qpid/cpp/managementgen/qmf/templates/Makefile.mk @@ -26,9 +26,7 @@ mgen_generator=/*MGEN:Makefile.GenSources*/ mgen_broker_cpp=/*MGEN:Makefile.GenCppFiles*/ # Header file install rules. -qpid_managementdir = $(includedir)/qmf -nobase_dist_qpid_management_HEADERS = /*MGEN:Makefile.GenHFiles*/ - +/*MGEN:Makefile.HeaderInstalls*/ if GENERATE $(srcdir)/managementgen.mk: $(mgen_generator) $(mgen_cmd) -- cgit v1.2.1 From ae02447d15e50a59c3d5f6bd69e3c1c9fb65f6ac Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 17 Sep 2008 12:48:08 +0000 Subject: Added missing Makefile dependencies for ACL and Cluster schema files git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@696280 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf-gen | 2 +- qpid/cpp/managementgen/qmf/generate.py | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index 523579fe6c..a1d76ae234 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -54,7 +54,7 @@ if len(args) == 0: for schemafile in args: package = SchemaPackage (typefile, schemafile, opts) - gen.setPackage (package.packageName) + gen.setPackage (package.packageName, schemafile) gen.makeClassFiles ("Class.h", package) gen.makeClassFiles ("Class.cpp", package) gen.makeMethodFiles ("Args.h", package) diff --git a/qpid/cpp/managementgen/qmf/generate.py b/qpid/cpp/managementgen/qmf/generate.py index 7346200a28..a6b3932357 100755 --- a/qpid/cpp/managementgen/qmf/generate.py +++ b/qpid/cpp/managementgen/qmf/generate.py @@ -100,10 +100,11 @@ class Template: class Makefile: """ Object representing a makefile fragment """ - def __init__ (self, filelists, templateFiles, packagelist): + def __init__ (self, filelists, templateFiles, packagelist, inputList): self.filelists = filelists self.templateFiles = templateFiles self.packagelist = packagelist + self.inputList = inputList def genGenSources (self, stream, variables): mdir = variables["mgenDir"] @@ -112,15 +113,21 @@ class Makefile: stream.write (" " + mdir + "/qmf/generate.py \\\n") stream.write (" " + mdir + "/qmf/schema.py \\\n") stream.write (" " + mdir + "/qmf/management-types.xml \\\n") - stream.write (" " + sdir + "/management-schema.xml \\\n") first = True for template in self.templateFiles: if first: first = False - stream.write (" ") + stream.write(" ") else: - stream.write (" \\\n ") - stream.write (mdir + "/qmf/templates/" + template) + stream.write(" \\\n ") + stream.write(mdir + "/qmf/templates/" + template) + for input in self.inputList: + if first: + first = False + srteam.write(" ") + else: + stream.write(" \\\n ") + stream.write("$(srcdir)/" + input) def genGenCppFiles (self, stream, variables): first = True @@ -192,10 +199,12 @@ class Generator: self.filelists["cpp"] = [] self.filelists["mk"] = [] self.packagelist = [] + self.inputList = [] self.templateFiles = [] self.variables = {} - def setPackage (self, packageName): + def setPackage (self, packageName, schemaFile): + self.inputList.append(schemaFile) path = "/".join(packageName.split(".")) self.packagelist.append(path) self.packagePath = self.normalize(self.dest + path) @@ -316,7 +325,7 @@ class Generator: def makeSingleFile (self, templateFile, target, force=False): """ Generate a single expanded template """ - makefile = Makefile (self.filelists, self.templateFiles, self.packagelist) + makefile = Makefile (self.filelists, self.templateFiles, self.packagelist, self.inputList) template = Template (self.input + templateFile, self) self.templateFiles.append (templateFile) stream = template.expand (makefile) -- cgit v1.2.1 From ad193f01aa1b7b89aa33d9c19e71c27cd0419f40 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 17 Sep 2008 13:00:22 +0000 Subject: Removed some dead code git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@696283 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf/generate.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf/generate.py b/qpid/cpp/managementgen/qmf/generate.py index a6b3932357..31154db864 100755 --- a/qpid/cpp/managementgen/qmf/generate.py +++ b/qpid/cpp/managementgen/qmf/generate.py @@ -122,12 +122,7 @@ class Makefile: stream.write(" \\\n ") stream.write(mdir + "/qmf/templates/" + template) for input in self.inputList: - if first: - first = False - srteam.write(" ") - else: - stream.write(" \\\n ") - stream.write("$(srcdir)/" + input) + stream.write(" \\\n $(srcdir)/" + input) def genGenCppFiles (self, stream, variables): first = True -- cgit v1.2.1 From bde0ee136725cda6556b18368046d5957c1a04c6 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 17 Sep 2008 14:20:07 +0000 Subject: Backed out makefile-dependency changes. They break vpath builds git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@696314 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf-gen | 2 +- qpid/cpp/managementgen/qmf/generate.py | 18 +++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index a1d76ae234..523579fe6c 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -54,7 +54,7 @@ if len(args) == 0: for schemafile in args: package = SchemaPackage (typefile, schemafile, opts) - gen.setPackage (package.packageName, schemafile) + gen.setPackage (package.packageName) gen.makeClassFiles ("Class.h", package) gen.makeClassFiles ("Class.cpp", package) gen.makeMethodFiles ("Args.h", package) diff --git a/qpid/cpp/managementgen/qmf/generate.py b/qpid/cpp/managementgen/qmf/generate.py index 31154db864..7346200a28 100755 --- a/qpid/cpp/managementgen/qmf/generate.py +++ b/qpid/cpp/managementgen/qmf/generate.py @@ -100,11 +100,10 @@ class Template: class Makefile: """ Object representing a makefile fragment """ - def __init__ (self, filelists, templateFiles, packagelist, inputList): + def __init__ (self, filelists, templateFiles, packagelist): self.filelists = filelists self.templateFiles = templateFiles self.packagelist = packagelist - self.inputList = inputList def genGenSources (self, stream, variables): mdir = variables["mgenDir"] @@ -113,16 +112,15 @@ class Makefile: stream.write (" " + mdir + "/qmf/generate.py \\\n") stream.write (" " + mdir + "/qmf/schema.py \\\n") stream.write (" " + mdir + "/qmf/management-types.xml \\\n") + stream.write (" " + sdir + "/management-schema.xml \\\n") first = True for template in self.templateFiles: if first: first = False - stream.write(" ") + stream.write (" ") else: - stream.write(" \\\n ") - stream.write(mdir + "/qmf/templates/" + template) - for input in self.inputList: - stream.write(" \\\n $(srcdir)/" + input) + stream.write (" \\\n ") + stream.write (mdir + "/qmf/templates/" + template) def genGenCppFiles (self, stream, variables): first = True @@ -194,12 +192,10 @@ class Generator: self.filelists["cpp"] = [] self.filelists["mk"] = [] self.packagelist = [] - self.inputList = [] self.templateFiles = [] self.variables = {} - def setPackage (self, packageName, schemaFile): - self.inputList.append(schemaFile) + def setPackage (self, packageName): path = "/".join(packageName.split(".")) self.packagelist.append(path) self.packagePath = self.normalize(self.dest + path) @@ -320,7 +316,7 @@ class Generator: def makeSingleFile (self, templateFile, target, force=False): """ Generate a single expanded template """ - makefile = Makefile (self.filelists, self.templateFiles, self.packagelist, self.inputList) + makefile = Makefile (self.filelists, self.templateFiles, self.packagelist) template = Template (self.input + templateFile, self) self.templateFiles.append (templateFile) stream = template.expand (makefile) -- cgit v1.2.1 From 052bab51a84dc7115e26f8addc24c087d37c2b00 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Mon, 22 Sep 2008 16:02:01 +0000 Subject: Added needed includes for generated Arg*.h files git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@697877 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf/templates/Args.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf/templates/Args.h b/qpid/cpp/managementgen/qmf/templates/Args.h index 89a5bec9b9..074ccf9940 100644 --- a/qpid/cpp/managementgen/qmf/templates/Args.h +++ b/qpid/cpp/managementgen/qmf/templates/Args.h @@ -24,6 +24,8 @@ /*MGEN:Root.Disclaimer*/ #include "qpid/management/Args.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/framing/Uuid.h" #include namespace qmf { -- cgit v1.2.1 From 2b1d069f6877abc6259596059a62cdc002f0f851 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Mon, 22 Sep 2008 19:35:54 +0000 Subject: Add initialization for properties not in the constructor arguments git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@697961 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf/management-types.xml | 6 +++--- qpid/cpp/managementgen/qmf/schema.py | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf/management-types.xml b/qpid/cpp/managementgen/qmf/management-types.xml index 56d2488803..6e34421d99 100644 --- a/qpid/cpp/managementgen/qmf/management-types.xml +++ b/qpid/cpp/managementgen/qmf/management-types.xml @@ -19,7 +19,7 @@ under the License. --> - + @@ -35,8 +35,8 @@ - - + + diff --git a/qpid/cpp/managementgen/qmf/schema.py b/qpid/cpp/managementgen/qmf/schema.py index 12a325ed80..2ecf9c351f 100755 --- a/qpid/cpp/managementgen/qmf/schema.py +++ b/qpid/cpp/managementgen/qmf/schema.py @@ -332,6 +332,10 @@ class SchemaProperty: def genAccessor (self, stream): self.type.type.genAccessor (stream, self.name, "configChanged", self.isOptional == 1) + def genInitialize (self, stream, prefix="", indent=" "): + val = self.type.type.init + stream.write (indent + prefix + self.name + " = " + val + ";\n") + def genSchema (self, stream): stream.write (" ft = FieldTable ();\n") stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") @@ -966,6 +970,9 @@ class SchemaClass: inst.genPerThreadHiLoStatResets (stream) def genInitializeElements (self, stream, variables): + for prop in self.properties: + if not prop.isConstructorArg() and not prop.isParentRef: + prop.genInitialize(stream) for inst in self.statistics: if not inst.type.type.perThread: inst.genInitialize (stream) -- cgit v1.2.1 From b56f731ad9d5d4b4b21f953dbd1103662b3d0b06 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Tue, 7 Oct 2008 21:47:35 +0000 Subject: QPID-1327 - Event support for Management git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@702651 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf-gen | 2 + qpid/cpp/managementgen/qmf/generate.py | 18 ++ qpid/cpp/managementgen/qmf/management-types.xml | 2 +- qpid/cpp/managementgen/qmf/schema.py | 246 +++++++++++++++--------- qpid/cpp/managementgen/qmf/templates/Class.cpp | 11 +- qpid/cpp/managementgen/qmf/templates/Class.h | 12 +- qpid/cpp/managementgen/qmf/templates/Event.cpp | 77 ++++++++ qpid/cpp/managementgen/qmf/templates/Event.h | 58 ++++++ 8 files changed, 315 insertions(+), 111 deletions(-) create mode 100644 qpid/cpp/managementgen/qmf/templates/Event.cpp create mode 100644 qpid/cpp/managementgen/qmf/templates/Event.h (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index 523579fe6c..62362e3cad 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -58,6 +58,8 @@ for schemafile in args: gen.makeClassFiles ("Class.h", package) gen.makeClassFiles ("Class.cpp", package) gen.makeMethodFiles ("Args.h", package) + gen.makeEventFiles ("Event.h", package) + gen.makeEventFiles ("Event.cpp", package) gen.makePackageFile ("Package.h", package) gen.makePackageFile ("Package.cpp", package) diff --git a/qpid/cpp/managementgen/qmf/generate.py b/qpid/cpp/managementgen/qmf/generate.py index 7346200a28..958728d739 100755 --- a/qpid/cpp/managementgen/qmf/generate.py +++ b/qpid/cpp/managementgen/qmf/generate.py @@ -250,6 +250,14 @@ class Generator: path = self.packagePath + _class.getNameCap () + extension return path + def targetEventFile (self, event, templateFile): + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + extension = templateFile[dot:len (templateFile)] + path = self.packagePath + "Event" + event.getNameCap () + extension + return path + def targetMethodFile (self, method, templateFile): """ Return the file name for a method file """ dot = templateFile.rfind(".") @@ -293,6 +301,16 @@ class Generator: stream = template.expand (_class) self.writeIfChanged (stream, target, force) + def makeEventFiles (self, templateFile, schema, force=False): + """ Generate an expanded template per schema event """ + events = schema.getEvents() + template = Template (self.input + templateFile, self) + self.templateFiles.append (templateFile) + for event in events: + target = self.targetEventFile(event, templateFile) + stream = template.expand(event) + self.writeIfChanged(stream, target, force) + def makeMethodFiles (self, templateFile, schema, force=False): """ Generate an expanded template per method-with-arguments """ classes = schema.getClasses () diff --git a/qpid/cpp/managementgen/qmf/management-types.xml b/qpid/cpp/managementgen/qmf/management-types.xml index 6e34421d99..626880afb3 100644 --- a/qpid/cpp/managementgen/qmf/management-types.xml +++ b/qpid/cpp/managementgen/qmf/management-types.xml @@ -30,7 +30,7 @@ - + diff --git a/qpid/cpp/managementgen/qmf/schema.py b/qpid/cpp/managementgen/qmf/schema.py index 2ecf9c351f..48e697ab4a 100755 --- a/qpid/cpp/managementgen/qmf/schema.py +++ b/qpid/cpp/managementgen/qmf/schema.py @@ -21,6 +21,32 @@ from xml.dom.minidom import parse, parseString, Node from cStringIO import StringIO import md5 +class Hash: + """ Manage the hash of an XML sub-tree """ + def __init__(self, node): + self.md5Sum = md5.new() + self._compute(node) + + def addSubHash(self, hash): + """ Use this method to add the hash of a dependend-on XML fragment that is not in the sub-tree """ + self.md5Sum.update(hash.getDigest()) + + def getDigest(self): + return self.md5Sum.digest() + + def _compute(self, node): + attrs = node.attributes + self.md5Sum.update(node.nodeName) + + for idx in range(attrs.length): + self.md5Sum.update(attrs.item(idx).nodeName) + self.md5Sum.update(attrs.item(idx).nodeValue) + + for child in node.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self._compute(child) + + #===================================================================================== # #===================================================================================== @@ -525,6 +551,7 @@ class SchemaArg: self.maxLen = None self.desc = None self.default = None + self.hash = Hash(node) attrs = node.attributes for idx in range (attrs.length): @@ -675,12 +702,12 @@ class SchemaMethod: # #===================================================================================== class SchemaEvent: - def __init__ (self, parent, node, typespec): - self.parent = parent - self.name = None - self.desc = None - self.args = [] - self.defaultSeverity = None + def __init__ (self, package, node, typespec, argset): + self.packageName = package + self.name = None + self.desc = None + self.args = [] + self.hash = Hash(node) attrs = node.attributes for idx in range (attrs.length): @@ -692,72 +719,96 @@ class SchemaEvent: elif key == 'desc': self.desc = val - elif key == 'defaultSeverity': - self.defaultSeverity = val + elif key == 'args': + list = val.replace(" ", "").split(",") + for item in list: + if item not in argset.args: + raise Exception("undefined argument '%s' in event" % item) + self.args.append(argset.args[item]) + self.hash.addSubHash(argset.args[item].hash) else: raise ValueError ("Unknown attribute in event '%s'" % key) - for child in node.childNodes: - if child.nodeType == Node.ELEMENT_NODE: - if child.nodeName == 'arg': - arg = SchemaArg (child, typespec) - self.args.append (arg) - else: - raise ValueError ("Unknown event tag '%s'" % child.nodeName) - def getName (self): return self.name + def getNameCap(self): + return capitalize(self.name) + def getFullName (self): - return capitalize(self.parent.getName()) + capitalize(self.name) + return capitalize(self.package + capitalize(self.name)) def getArgCount (self): return len (self.args) - def genMethodBody (self, stream, variables, classObject): - stream.write("void ") - classObject.genNameCap(stream, variables) - stream.write("::event_%s(" % self.name) - count = 0 + def genArgCount (self, stream, variables): + stream.write("%d" % len(self.args)) + + def genArgDeclarations(self, stream, variables): for arg in self.args: - arg.genFormalParam(stream, variables) - count += 1 - if count < len(self.args): - stream.write(", ") - stream.write(") {\n") - stream.write(" ::qpid::sys::Mutex::ScopedLock mutex(getMutex());\n") - stream.write(" Buffer* buf = startEventLH();\n") - stream.write(" objectId.encode(*buf);\n") - stream.write(" buf->putShortString(packageName);\n") - stream.write(" buf->putShortString(className);\n") - stream.write(" buf->putBin128(md5Sum);\n") - stream.write(" buf->putShortString(\"%s\");\n" % self.name) + if arg.type.type.byRef: + ref = "&" + else: + ref = "" + stream.write(" const %s%s %s;\n" % (arg.type.type.cpp, ref, arg.name)) + + def genCloseNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("}") + + def genConstructorArgs(self, stream, variables): + pre = "" for arg in self.args: - stream.write(" %s;\n" % arg.type.type.encode.replace("@", "(*buf)").replace("#", "_" + arg.name)) - stream.write(" finishEventLH(buf);\n") - stream.write("}\n\n") + if arg.type.type.byRef: + ref = "&" + else: + ref = "" + stream.write("%sconst %s%s _%s" % (pre, arg.type.type.cpp, ref, arg.name)) + pre = ",\n " - def genMethodDecl (self, stream, variables): - stream.write(" void event_%s(" % self.name) - count = 0 + def genConstructorInits(self, stream, variables): + pre = "" for arg in self.args: - arg.genFormalParam(stream, variables) - count += 1 - if count < len(self.args): - stream.write(", ") - stream.write(");\n") + stream.write("%s%s(_%s)" % (pre, arg.name, arg.name)) + pre = ",\n " - 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") - if self.desc != None: - stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") - stream.write (" buf.put (ft);\n\n") + def genName(self, stream, variables): + stream.write(self.name) + + def genNameCap(self, stream, variables): + stream.write(capitalize(self.name)) + + def genNamespace (self, stream, variables): + stream.write("::".join(self.packageName.split("."))) + + def genNameLower(self, stream, variables): + stream.write(self.name.lower()) + + def genNameUpper(self, stream, variables): + stream.write(self.name.upper()) + + def genNamePackageLower(self, stream, variables): + stream.write(self.packageName.lower()) + + def genOpenNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("namespace %s {\n" % item) + + def genArgEncodes(self, stream, variables): + for arg in self.args: + stream.write(" " + arg.type.type.encode.replace("@", "buf").replace("#", arg.name) + ";\n") + + def genArgSchema(self, stream, variables): for arg in self.args: - arg.genSchema (stream, True) + arg.genSchema(stream, True) + def genSchemaMD5(self, stream, variables): + sum = self.hash.getDigest() + for idx in range (len (sum)): + if idx != 0: + stream.write (",") + stream.write (hex (ord (sum[idx]))) class SchemaClass: @@ -768,9 +819,7 @@ class SchemaClass: self.methods = [] self.events = [] self.options = options - self.md5Sum = md5.new () - - self.hash (node) + self.hash = Hash(node) attrs = node.attributes self.name = makeValidCppSymbol(attrs['name'].nodeValue) @@ -790,10 +839,6 @@ class SchemaClass: sub = SchemaMethod (self, child, typespec) self.methods.append (sub) - elif child.nodeName == 'event': - sub = SchemaEvent (self, child, typespec) - self.events.append (sub) - elif child.nodeName == 'group': self.expandFragment (child, fragments) @@ -820,24 +865,12 @@ class SchemaClass: result = result[0:pos] + "threadStats->" + result[pos:] start = pos + 9 + len(next[1]) - def hash (self, node): - attrs = node.attributes - self.md5Sum.update (node.nodeName) - - for idx in range (attrs.length): - self.md5Sum.update (attrs.item(idx).nodeName) - self.md5Sum.update (attrs.item(idx).nodeValue) - - for child in node.childNodes: - if child.nodeType == Node.ELEMENT_NODE: - self.hash (child) - def expandFragment (self, node, fragments): attrs = node.attributes name = attrs['name'].nodeValue for fragment in fragments: if fragment.name == name: - self.md5Sum.update (fragment.md5Sum.digest()) + self.hash.addSubHash(fragment.hash) for config in fragment.properties: self.properties.append (config) for inst in fragment.statistics: @@ -937,27 +970,12 @@ class SchemaClass: inArgCount = inArgCount + 1 if methodCount == 0: - stream.write ("string, Buffer&, Buffer& outBuf") + stream.write ("string&, Buffer&, Buffer& outBuf") else: if inArgCount == 0: - stream.write ("string methodName, Buffer&, Buffer& outBuf") + stream.write ("string& methodName, Buffer&, Buffer& outBuf") else: - stream.write ("string methodName, Buffer& inBuf, Buffer& outBuf") - - def genEventCount (self, stream, variables): - stream.write ("%d" % len (self.events)) - - def genEventMethodBodies (self, stream, variables): - for event in self.events: - event.genMethodBody (stream, variables, self) - - def genEventMethodDecls (self, stream, variables): - for event in self.events: - event.genMethodDecl (stream, variables) - - def genEventSchema (self, stream, variables): - for event in self.events: - event.genSchema (stream, variables) + stream.write ("string& methodName, Buffer& inBuf, Buffer& outBuf") def genHiLoStatResets (self, stream, variables): for inst in self.statistics: @@ -1124,7 +1142,7 @@ class SchemaClass: return def genSchemaMD5 (self, stream, variables): - sum = self.md5Sum.digest () + sum = self.hash.getDigest() for idx in range (len (sum)): if idx != 0: stream.write (",") @@ -1149,6 +1167,20 @@ class SchemaClass: stat.genWrite (stream) +class SchemaEventArgs: + def __init__(self, package, node, typespec, fragments, options): + self.packageName = package + self.options = options + self.args = {} + + children = node.childNodes + for child in children: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'arg': + arg = SchemaArg(child, typespec) + self.args[arg.name] = arg + else: + raise Exception("Unknown tag '%s' in " % child.nodeName) class SchemaPackage: def __init__ (self, typefile, schemafile, options): @@ -1156,6 +1188,8 @@ class SchemaPackage: self.classes = [] self.fragments = [] self.typespec = TypeSpec (typefile) + self.eventArgSet = None + self.events = [] dom = parse (schemafile) document = dom.documentElement @@ -1179,6 +1213,15 @@ class SchemaPackage: self.fragments, options) self.fragments.append (cls) + elif child.nodeName == 'eventArguments': + if self.eventArgSet: + raise Exception("Only one may appear in a package") + self.eventArgSet = SchemaEventArgs(self.packageName, child, self.typespec, self.fragments, options) + + elif child.nodeName == 'event': + event = SchemaEvent(self.packageName, child, self.typespec, self.eventArgSet) + self.events.append(event) + else: raise ValueError ("Unknown schema tag '%s'" % child.nodeName) @@ -1194,6 +1237,9 @@ class SchemaPackage: def getClasses (self): return self.classes + def getEvents(self): + return self.events + def genCloseNamespaces (self, stream, variables): for item in self.packageName.split("."): stream.write ("}") @@ -1217,12 +1263,20 @@ class SchemaPackage: stream.write ("#include \"") _class.genNameCap (stream, variables) stream.write (".h\"\n") + for _event in self.events: + stream.write ("#include \"Event") + _event.genNameCap(stream, variables) + stream.write (".h\"\n") - def genClassRegisters (self, stream, variables): + def genClassRegisters(self, stream, variables): for _class in self.classes: - stream.write (" ") - _class.genNameCap (stream, variables) - stream.write ("::registerClass(agent);\n") + stream.write(" ") + _class.genNameCap(stream, variables) + stream.write("::registerSelf(agent);\n") + for _event in self.events: + stream.write(" Event") + _event.genNameCap(stream, variables) + stream.write("::registerSelf(agent);\n") #===================================================================================== diff --git a/qpid/cpp/managementgen/qmf/templates/Class.cpp b/qpid/cpp/managementgen/qmf/templates/Class.cpp index 964e6f8349..0a69939821 100644 --- a/qpid/cpp/managementgen/qmf/templates/Class.cpp +++ b/qpid/cpp/managementgen/qmf/templates/Class.cpp @@ -85,9 +85,9 @@ namespace { const string DEFAULT("default"); } -void /*MGEN:Class.NameCap*/::registerClass(ManagementAgent* agent) +void /*MGEN:Class.NameCap*/::registerSelf(ManagementAgent* agent) { - agent->RegisterClass(packageName, className, md5Sum, writeSchema); + agent->registerClass(packageName, className, md5Sum, writeSchema); } void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) @@ -95,13 +95,13 @@ void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) FieldTable ft; // Schema class header: + buf.putOctet (CLASS_KIND_TABLE); buf.putShortString (packageName); // Package Name buf.putShortString (className); // Class Name buf.putBin128 (md5Sum); // Schema Hash buf.putShort (/*MGEN:Class.ConfigCount*/); // Config Element Count buf.putShort (/*MGEN:Class.InstCount*/); // Inst Element Count buf.putShort (/*MGEN:Class.MethodCount*/); // Method Count - buf.putShort (/*MGEN:Class.EventCount*/); // Event Count // Properties /*MGEN:Class.PropertySchema*/ @@ -109,8 +109,6 @@ void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) /*MGEN:Class.StatisticSchema*/ // Methods /*MGEN:Class.MethodSchema*/ - // Events -/*MGEN:Class.EventSchema*/ } /*MGEN:IF(Class.ExistPerThreadStats)*/ @@ -176,9 +174,8 @@ void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) { Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; std::string text; + /*MGEN:Class.MethodHandlers*/ outBuf.putLong(status); outBuf.putShortString(Manageable::StatusText(status, text)); } - -/*MGEN:Class.EventMethodBodies*/ diff --git a/qpid/cpp/managementgen/qmf/templates/Class.h b/qpid/cpp/managementgen/qmf/templates/Class.h index 99ebc68789..2a995c95a5 100644 --- a/qpid/cpp/managementgen/qmf/templates/Class.h +++ b/qpid/cpp/managementgen/qmf/templates/Class.h @@ -72,7 +72,7 @@ class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject void writeProperties (::qpid::framing::Buffer& buf); void writeStatistics (::qpid::framing::Buffer& buf, bool skipHeaders = false); - void doMethod (std::string methodName, + void doMethod (std::string& methodName, ::qpid::framing::Buffer& inBuf, ::qpid::framing::Buffer& outBuf); writeSchemaCall_t getWriteSchemaCall(void) { return writeSchema; } @@ -88,17 +88,15 @@ class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject /*MGEN:Class.SetGeneralReferenceDeclaration*/ - static void registerClass (::qpid::management::ManagementAgent* agent); - std::string& getPackageName (void) { return packageName; } - std::string& getClassName (void) { return className; } - uint8_t* getMd5Sum (void) { return md5Sum; } + static void registerSelf (::qpid::management::ManagementAgent* agent); + std::string& getPackageName (void) const { return packageName; } + std::string& getClassName (void) const { return className; } + uint8_t* getMd5Sum (void) const { return md5Sum; } // Method IDs /*MGEN:Class.MethodIdDeclarations*/ // Accessor Methods /*MGEN:Class.AccessorMethods*/ - // Event Methods -/*MGEN:Class.EventMethodDecls*/ }; }/*MGEN:Class.CloseNamespaces*/ diff --git a/qpid/cpp/managementgen/qmf/templates/Event.cpp b/qpid/cpp/managementgen/qmf/templates/Event.cpp new file mode 100644 index 0000000000..cdb40c6d79 --- /dev/null +++ b/qpid/cpp/managementgen/qmf/templates/Event.cpp @@ -0,0 +1,77 @@ +/*MGEN:commentPrefix=//*/ +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/log/Statement.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/management/Manageable.h" +#include "qpid/agent/ManagementAgent.h" +#include "Event/*MGEN:Event.NameCap*/.h" + +using namespace qmf::/*MGEN:Event.Namespace*/; +using namespace qpid::framing; +using qpid::management::ManagementAgent; +using qpid::management::Manageable; +using qpid::management::ManagementObject; +using qpid::management::Args; +using std::string; + +string Event/*MGEN:Event.NameCap*/::packageName = string ("/*MGEN:Event.NamePackageLower*/"); +string Event/*MGEN:Event.NameCap*/::eventName = string ("/*MGEN:Event.Name*/"); +uint8_t Event/*MGEN:Event.NameCap*/::md5Sum[16] = + {/*MGEN:Event.SchemaMD5*/}; + +Event/*MGEN:Event.NameCap*/::Event/*MGEN:Event.NameCap*/ (/*MGEN:Event.ConstructorArgs*/) : + /*MGEN:Event.ConstructorInits*/ +{} + +namespace { + const string NAME("name"); + const string TYPE("type"); + const string DESC("desc"); + const string ARGCOUNT("argCount"); + const string ARGS("args"); +} + +void Event/*MGEN:Event.NameCap*/::registerSelf(ManagementAgent* agent) +{ + agent->registerEvent(packageName, eventName, md5Sum, writeSchema); +} + +void Event/*MGEN:Event.NameCap*/::writeSchema (Buffer& buf) +{ + FieldTable ft; + + // Schema class header: + buf.putOctet (CLASS_KIND_EVENT); + buf.putShortString (packageName); // Package Name + buf.putShortString (eventName); // Event Name + buf.putBin128 (md5Sum); // Schema Hash + buf.putShort (/*MGEN:Event.ArgCount*/); // Argument Count + + // Arguments +/*MGEN:Event.ArgSchema*/ +} + +void Event/*MGEN:Event.NameCap*/::encode(::qpid::framing::Buffer& buf) const +{ +/*MGEN:Event.ArgEncodes*/ +} diff --git a/qpid/cpp/managementgen/qmf/templates/Event.h b/qpid/cpp/managementgen/qmf/templates/Event.h new file mode 100644 index 0000000000..a943c0c501 --- /dev/null +++ b/qpid/cpp/managementgen/qmf/templates/Event.h @@ -0,0 +1,58 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _MANAGEMENT_/*MGEN:Event.NameUpper*/_ +#define _MANAGEMENT_/*MGEN:Event.NameUpper*/_ + +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/ManagementEvent.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/framing/Uuid.h" + +namespace qmf { +/*MGEN:Event.OpenNamespaces*/ + +class Event/*MGEN:Event.NameCap*/ : public ::qpid::management::ManagementEvent +{ + private: + static void writeSchema (::qpid::framing::Buffer& buf); + static std::string packageName; + static std::string eventName; + static uint8_t md5Sum[16]; + +/*MGEN:Event.ArgDeclarations*/ + + public: + writeSchemaCall_t getWriteSchemaCall(void) { return writeSchema; } + + Event/*MGEN:Event.NameCap*/(/*MGEN:Event.ConstructorArgs*/); + ~Event/*MGEN:Class.NameCap*/() {}; + + static void registerSelf(::qpid::management::ManagementAgent* agent); + std::string& getPackageName() const { return packageName; } + std::string& getEventName() const { return eventName; } + uint8_t* getMd5Sum() const { return md5Sum; } + void encode(::qpid::framing::Buffer& buffer) const; +}; + +}/*MGEN:Event.CloseNamespaces*/ + +#endif /*!_MANAGEMENT_/*MGEN:Event.NameUpper*/_*/ -- cgit v1.2.1 From 2b1094951e46edd11ff5533597389798c6d5521e Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 8 Oct 2008 13:57:18 +0000 Subject: Fixed a couple of distribution bugs git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@702880 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am index c8c1e64492..c9a20b06a7 100644 --- a/qpid/cpp/managementgen/Makefile.am +++ b/qpid/cpp/managementgen/Makefile.am @@ -8,6 +8,8 @@ nobase_qmfpython_DATA = \ qmf/templates/Args.h \ qmf/templates/Class.cpp \ qmf/templates/Class.h \ + qmf/templates/Event.cpp \ + qmf/templates/Event.h \ qmf/templates/Makefile.mk \ qmf/templates/Package.cpp \ qmf/templates/Package.h \ -- cgit v1.2.1 From 7f4b58e6a0d93de091ff14efc07bb49f42294b81 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 8 Oct 2008 19:44:24 +0000 Subject: QPID-1327 - Added severity field to events, cleaned up routing key usage git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@702977 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf/schema.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf/schema.py b/qpid/cpp/managementgen/qmf/schema.py index 48e697ab4a..7f008c19e3 100755 --- a/qpid/cpp/managementgen/qmf/schema.py +++ b/qpid/cpp/managementgen/qmf/schema.py @@ -706,6 +706,7 @@ class SchemaEvent: self.packageName = package self.name = None self.desc = None + self.sevText = "inform" self.args = [] self.hash = Hash(node) @@ -719,6 +720,9 @@ class SchemaEvent: elif key == 'desc': self.desc = val + elif key == 'sev': + self.sevText = val + elif key == 'args': list = val.replace(" ", "").split(",") for item in list: @@ -730,6 +734,17 @@ class SchemaEvent: else: raise ValueError ("Unknown attribute in event '%s'" % key) + if self.sevText == "emerg" : self.sev = 0 + elif self.sevText == "alert" : self.sev = 1 + elif self.sevText == "crit" : self.sev = 2 + elif self.sevText == "error" : self.sev = 3 + elif self.sevText == "warn" : self.sev = 4 + elif self.sevText == "notice" : self.sev = 5 + elif self.sevText == "inform" : self.sev = 6 + elif self.sevText == "debug" : self.sev = 7 + else: + raise ValueError("Unknown severity '%s' in event '%s'" % (self.sevText, self.name)) + def getName (self): return self.name @@ -796,6 +811,7 @@ class SchemaEvent: stream.write ("namespace %s {\n" % item) def genArgEncodes(self, stream, variables): + stream.write(" buf.putOctet(%d);\n" % self.sev) for arg in self.args: stream.write(" " + arg.type.type.encode.replace("@", "buf").replace("#", arg.name) + ";\n") -- cgit v1.2.1 From 90f05a2c343bdddda6863f80563702eaf5eece8a Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Thu, 9 Oct 2008 13:47:48 +0000 Subject: QPID-1327 - Added optional severity override in the eventRaise method git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@703164 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf/schema.py | 4 +++- qpid/cpp/managementgen/qmf/templates/Event.h | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf/schema.py b/qpid/cpp/managementgen/qmf/schema.py index 7f008c19e3..72ee762fc5 100755 --- a/qpid/cpp/managementgen/qmf/schema.py +++ b/qpid/cpp/managementgen/qmf/schema.py @@ -810,8 +810,10 @@ class SchemaEvent: for item in self.packageName.split("."): stream.write ("namespace %s {\n" % item) + def genSeverity(self, stream, variables): + stream.write("%d" % self.sev) + def genArgEncodes(self, stream, variables): - stream.write(" buf.putOctet(%d);\n" % self.sev) for arg in self.args: stream.write(" " + arg.type.type.encode.replace("@", "buf").replace("#", arg.name) + ";\n") diff --git a/qpid/cpp/managementgen/qmf/templates/Event.h b/qpid/cpp/managementgen/qmf/templates/Event.h index a943c0c501..b5c2a211d1 100644 --- a/qpid/cpp/managementgen/qmf/templates/Event.h +++ b/qpid/cpp/managementgen/qmf/templates/Event.h @@ -44,12 +44,13 @@ class Event/*MGEN:Event.NameCap*/ : public ::qpid::management::ManagementEvent writeSchemaCall_t getWriteSchemaCall(void) { return writeSchema; } Event/*MGEN:Event.NameCap*/(/*MGEN:Event.ConstructorArgs*/); - ~Event/*MGEN:Class.NameCap*/() {}; + ~Event/*MGEN:Event.NameCap*/() {}; static void registerSelf(::qpid::management::ManagementAgent* agent); std::string& getPackageName() const { return packageName; } std::string& getEventName() const { return eventName; } uint8_t* getMd5Sum() const { return md5Sum; } + uint8_t getSeverity() const { return /*MGEN:Event.Severity*/; } void encode(::qpid::framing::Buffer& buffer) const; }; -- cgit v1.2.1 From 978185bafb2b08d89c0b675263dd2b1f715c9e69 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 15 Oct 2008 15:51:15 +0000 Subject: QPID-1360 - Scaling improvements for QMF git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@704944 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf/templates/Class.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf/templates/Class.h b/qpid/cpp/managementgen/qmf/templates/Class.h index 2a995c95a5..7796914d51 100644 --- a/qpid/cpp/managementgen/qmf/templates/Class.h +++ b/qpid/cpp/managementgen/qmf/templates/Class.h @@ -55,11 +55,11 @@ class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject struct PerThreadStats** perThreadStatsArray; inline struct PerThreadStats* getThreadStats() { - int index = getThreadIndex(); - struct PerThreadStats* threadStats = perThreadStatsArray[index]; + int idx = getThreadIndex(); + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; if (threadStats == 0) { threadStats = new(PerThreadStats); - perThreadStatsArray[index] = threadStats; + perThreadStatsArray[idx] = threadStats; /*MGEN:Class.InitializePerThreadElements*/ } return threadStats; -- cgit v1.2.1 From 92c702abaa7ef5731212ac7fb4acbad7428a34c7 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Fri, 24 Oct 2008 15:15:59 +0000 Subject: Use a str16 instead of str8 for qmf method response text git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@707653 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf/schema.py b/qpid/cpp/managementgen/qmf/schema.py index 72ee762fc5..031721f47f 100755 --- a/qpid/cpp/managementgen/qmf/schema.py +++ b/qpid/cpp/managementgen/qmf/schema.py @@ -1076,7 +1076,7 @@ class SchemaClass: stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ method.getName().upper() + ", ioArgs, text);\n") stream.write (" outBuf.putLong (status);\n") - stream.write (" outBuf.putShortString (::qpid::management::Manageable::StatusText (status, text));\n") + stream.write (" outBuf.putMediumString(::qpid::management::Manageable::StatusText (status, text));\n") for arg in method.args: if arg.getDir () == "O" or arg.getDir () == "IO": stream.write (" " +\ -- cgit v1.2.1 From 170a1b268baf547677d827e64762c82500d7aff7 Mon Sep 17 00:00:00 2001 From: "Stephen D. Huston" Date: Tue, 28 Oct 2008 22:27:34 +0000 Subject: Fix to build needed directory tree on Windows; fixes QPID-1407 git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@708703 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf/generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf/generate.py b/qpid/cpp/managementgen/qmf/generate.py index 958728d739..9b48c41ac4 100755 --- a/qpid/cpp/managementgen/qmf/generate.py +++ b/qpid/cpp/managementgen/qmf/generate.py @@ -166,7 +166,7 @@ class Generator: try: mode = os.stat (path)[ST_MODE] except OSError, (err,text): - if err == ENOENT: + if err == ENOENT or err == ESRCH: exists = False else: raise -- cgit v1.2.1 From e5a0e6860db70da8a272a16f44252fc25af0377d Mon Sep 17 00:00:00 2001 From: "Stephen D. Huston" Date: Tue, 28 Oct 2008 22:28:48 +0000 Subject: Rename schema names OPTIONAL and INDEX to IS_OPTIONAL and IS_INDEX to avoid name clashes in Windows header files; fixes QPID-1408 git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@708704 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf/schema.py | 4 ++-- qpid/cpp/managementgen/qmf/templates/Class.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf/schema.py b/qpid/cpp/managementgen/qmf/schema.py index 031721f47f..692a474992 100755 --- a/qpid/cpp/managementgen/qmf/schema.py +++ b/qpid/cpp/managementgen/qmf/schema.py @@ -367,8 +367,8 @@ class SchemaProperty: stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") stream.write (" ft.setInt (ACCESS, ACCESS_" + self.access + ");\n") - stream.write (" ft.setInt (INDEX, " + str (self.isIndex) + ");\n") - stream.write (" ft.setInt (OPTIONAL, " + str (self.isOptional) + ");\n") + stream.write (" ft.setInt (IS_INDEX, " + str (self.isIndex) + ");\n") + stream.write (" ft.setInt (IS_OPTIONAL, " + str (self.isOptional) + ");\n") if self.unit != None: stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") if self.min != None: diff --git a/qpid/cpp/managementgen/qmf/templates/Class.cpp b/qpid/cpp/managementgen/qmf/templates/Class.cpp index 0a69939821..247e1090ff 100644 --- a/qpid/cpp/managementgen/qmf/templates/Class.cpp +++ b/qpid/cpp/managementgen/qmf/templates/Class.cpp @@ -72,8 +72,8 @@ namespace { const string NAME("name"); const string TYPE("type"); const string ACCESS("access"); - const string INDEX("index"); - const string OPTIONAL("optional"); + const string IS_INDEX("index"); + const string IS_OPTIONAL("optional"); const string UNIT("unit"); const string MIN("min"); const string MAX("max"); -- cgit v1.2.1 From df671aa249edfd7ad1693cb73253a30abf7e618b Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 12 Nov 2008 19:50:11 +0000 Subject: Generalized the creation of makefile fragments in qmf code generation. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@713476 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf-gen | 33 ++++++++++++++---------- qpid/cpp/managementgen/qmf/generate.py | 25 +++++++++++++++++- qpid/cpp/managementgen/qmf/templates/Makefile.mk | 7 ++++- 3 files changed, 50 insertions(+), 15 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index 62362e3cad..d71097b4b4 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -30,29 +30,33 @@ defaultTemplateDir = dataPath + "/templates" # Set command line options usage = "usage: %prog [options] schema-document..." -parser = OptionParser (usage=usage) -parser.add_option ("-m", "--makefile", dest="makefile", metavar="FILE", - help="Makefile fragment") -parser.add_option ("-t", "--typefile", dest="typefile", metavar="FILE", default=defaultTypeFile, - help="Type descriptor file") -parser.add_option ("-d", "--templatedir", dest="templatedir", metavar="DIR", default=defaultTemplateDir, - help="Template directory") -parser.add_option ("-o", "--outputdir", dest="outputdir", metavar="DIR", default="./", - help="Output directory") +parser = OptionParser(usage=usage) +parser.add_option("-o", "--outputdir", dest="outputdir", metavar="DIR", default="./", + help="Output directory") +parser.add_option("-m", "--makefile", dest="makefile", metavar="FILE", + help="Makefile fragment") +parser.add_option("-t", "--typefile", dest="typefile", metavar="FILE", default=defaultTypeFile, + help="Override type descriptor file") +parser.add_option("-d", "--templatedir", dest="templatedir", metavar="DIR", default=defaultTemplateDir, + help="Override template directory") +parser.add_option("-p", "--gen-prefix", dest="genprefix", default="", + help="Prefix for generated files in make dependencies") +parser.add_option("-q", "--qpid-broker", dest="qpidbroker", default=False, action="store_true", + help="Generate makefile for Qpid broker") -(opts, args) = parser.parse_args () +(opts, args) = parser.parse_args() typefile = opts.typefile templatedir = opts.templatedir outdir = opts.outputdir -gen = Generator (outdir, templatedir) +gen = Generator(outdir, templatedir) if len(args) == 0: print "no input files" parser.exit() for schemafile in args: - package = SchemaPackage (typefile, schemafile, opts) + package = SchemaPackage(typefile, schemafile, opts) gen.setPackage (package.packageName) gen.makeClassFiles ("Class.h", package) @@ -64,4 +68,7 @@ for schemafile in args: gen.makePackageFile ("Package.cpp", package) if opts.makefile != None: - gen.makeSingleFile ("Makefile.mk", opts.makefile, force=True) + args = {} + args["qpidbroker"] = opts.qpidbroker + args["genprefix"] = opts.genprefix + gen.makeSingleFile("Makefile.mk", opts.makefile, force=True, vars=args) diff --git a/qpid/cpp/managementgen/qmf/generate.py b/qpid/cpp/managementgen/qmf/generate.py index 9b48c41ac4..2f2d51a1e2 100755 --- a/qpid/cpp/managementgen/qmf/generate.py +++ b/qpid/cpp/managementgen/qmf/generate.py @@ -140,6 +140,21 @@ class Makefile: stream.write (" \\\n ") stream.write (file) + def genGeneratedFiles(self, stream, variables): + first = True + extensions = ("h", "cpp") + for ext in extensions: + for file in self.filelists[ext]: + if first: + first = False + else: + stream.write(" \\\n ") + if "genprefix" in variables: + prefix = variables["genprefix"] + if prefix != "": + stream.write(prefix + "/") + stream.write(file) + def genHeaderInstalls (self, stream, variables): for package in self.packagelist: name = "_".join(package.split("/")) @@ -155,6 +170,11 @@ class Makefile: stream.write(file) stream.write("\n\n") + def testQpidBroker(self, variables): + if "qpidbroker" in variables: + return variables["qpidbroker"] + return False + class Generator: """ @@ -332,10 +352,13 @@ class Generator: stream = template.expand (schema) self.writeIfChanged (stream, target, force) - def makeSingleFile (self, templateFile, target, force=False): + def makeSingleFile (self, templateFile, target, force=False, vars=None): """ Generate a single expanded template """ makefile = Makefile (self.filelists, self.templateFiles, self.packagelist) template = Template (self.input + templateFile, self) + if vars: + for arg in vars: + self.setVariable(arg, vars[arg]) self.templateFiles.append (templateFile) stream = template.expand (makefile) self.writeIfChanged (stream, target, force) diff --git a/qpid/cpp/managementgen/qmf/templates/Makefile.mk b/qpid/cpp/managementgen/qmf/templates/Makefile.mk index 6b06e74b46..2b32c7c0f2 100644 --- a/qpid/cpp/managementgen/qmf/templates/Makefile.mk +++ b/qpid/cpp/managementgen/qmf/templates/Makefile.mk @@ -17,9 +17,10 @@ # under the License. # /*MGEN:commentPrefix=#*/ +/*MGEN:Root.Disclaimer*/ +/*MGEN:IF(Makefile.QpidBroker)*/ /*MGEN:mgenDir=$(mgen_dir)*/ /*MGEN:specDir=$(top_srcdir)/../specs*/ -/*MGEN:Root.Disclaimer*/ mgen_generator=/*MGEN:Makefile.GenSources*/ @@ -33,3 +34,7 @@ $(srcdir)/managementgen.mk: $(mgen_generator) $(mgen_generator): endif +/*MGEN:ENDIF*/ + +qmfgen_sources=/*MGEN:Makefile.GeneratedFiles*/ + -- cgit v1.2.1 From 284d5014e4881605ee63f774a42bb54f05ea9f22 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Fri, 21 Nov 2008 18:46:24 +0000 Subject: Renamed the python package for the qmf code generation as it conflicts with the package for the qmf apis. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@719671 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/Makefile.am | 24 +- qpid/cpp/managementgen/qmf-gen | 6 +- qpid/cpp/managementgen/qmf/__init__.py | 19 - qpid/cpp/managementgen/qmf/generate.py | 369 ------ qpid/cpp/managementgen/qmf/management-types.xml | 56 - qpid/cpp/managementgen/qmf/schema.py | 1339 -------------------- qpid/cpp/managementgen/qmf/templates/Args.h | 42 - qpid/cpp/managementgen/qmf/templates/Class.cpp | 181 --- qpid/cpp/managementgen/qmf/templates/Class.h | 104 -- qpid/cpp/managementgen/qmf/templates/Event.cpp | 77 -- qpid/cpp/managementgen/qmf/templates/Event.h | 59 - qpid/cpp/managementgen/qmf/templates/Makefile.mk | 40 - qpid/cpp/managementgen/qmf/templates/Package.cpp | 32 - qpid/cpp/managementgen/qmf/templates/Package.h | 41 - qpid/cpp/managementgen/qmfgen/__init__.py | 19 + qpid/cpp/managementgen/qmfgen/generate.py | 369 ++++++ qpid/cpp/managementgen/qmfgen/management-types.xml | 56 + qpid/cpp/managementgen/qmfgen/schema.py | 1339 ++++++++++++++++++++ qpid/cpp/managementgen/qmfgen/templates/Args.h | 42 + qpid/cpp/managementgen/qmfgen/templates/Class.cpp | 181 +++ qpid/cpp/managementgen/qmfgen/templates/Class.h | 104 ++ qpid/cpp/managementgen/qmfgen/templates/Event.cpp | 77 ++ qpid/cpp/managementgen/qmfgen/templates/Event.h | 59 + .../cpp/managementgen/qmfgen/templates/Makefile.mk | 40 + .../cpp/managementgen/qmfgen/templates/Package.cpp | 32 + qpid/cpp/managementgen/qmfgen/templates/Package.h | 41 + 26 files changed, 2374 insertions(+), 2374 deletions(-) delete mode 100644 qpid/cpp/managementgen/qmf/__init__.py delete mode 100755 qpid/cpp/managementgen/qmf/generate.py delete mode 100644 qpid/cpp/managementgen/qmf/management-types.xml delete mode 100755 qpid/cpp/managementgen/qmf/schema.py delete mode 100644 qpid/cpp/managementgen/qmf/templates/Args.h delete mode 100644 qpid/cpp/managementgen/qmf/templates/Class.cpp delete mode 100644 qpid/cpp/managementgen/qmf/templates/Class.h delete mode 100644 qpid/cpp/managementgen/qmf/templates/Event.cpp delete mode 100644 qpid/cpp/managementgen/qmf/templates/Event.h delete mode 100644 qpid/cpp/managementgen/qmf/templates/Makefile.mk delete mode 100644 qpid/cpp/managementgen/qmf/templates/Package.cpp delete mode 100644 qpid/cpp/managementgen/qmf/templates/Package.h create mode 100644 qpid/cpp/managementgen/qmfgen/__init__.py create mode 100755 qpid/cpp/managementgen/qmfgen/generate.py create mode 100644 qpid/cpp/managementgen/qmfgen/management-types.xml create mode 100755 qpid/cpp/managementgen/qmfgen/schema.py create mode 100644 qpid/cpp/managementgen/qmfgen/templates/Args.h create mode 100644 qpid/cpp/managementgen/qmfgen/templates/Class.cpp create mode 100644 qpid/cpp/managementgen/qmfgen/templates/Class.h create mode 100644 qpid/cpp/managementgen/qmfgen/templates/Event.cpp create mode 100644 qpid/cpp/managementgen/qmfgen/templates/Event.h create mode 100644 qpid/cpp/managementgen/qmfgen/templates/Makefile.mk create mode 100644 qpid/cpp/managementgen/qmfgen/templates/Package.cpp create mode 100644 qpid/cpp/managementgen/qmfgen/templates/Package.h (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am index c9a20b06a7..f4f4b35e40 100644 --- a/qpid/cpp/managementgen/Makefile.am +++ b/qpid/cpp/managementgen/Makefile.am @@ -2,17 +2,17 @@ qmfpythondir = $(pythondir) dist_bin_SCRIPTS = \ qmf-gen nobase_qmfpython_DATA = \ - qmf/__init__.py \ - qmf/generate.py \ - qmf/schema.py \ - qmf/templates/Args.h \ - qmf/templates/Class.cpp \ - qmf/templates/Class.h \ - qmf/templates/Event.cpp \ - qmf/templates/Event.h \ - qmf/templates/Makefile.mk \ - qmf/templates/Package.cpp \ - qmf/templates/Package.h \ - qmf/management-types.xml + qmfgen/__init__.py \ + qmfgen/generate.py \ + qmfgen/schema.py \ + qmfgen/templates/Args.h \ + qmfgen/templates/Class.cpp \ + qmfgen/templates/Class.h \ + qmfgen/templates/Event.cpp \ + qmfgen/templates/Event.h \ + qmfgen/templates/Makefile.mk \ + qmfgen/templates/Package.cpp \ + qmfgen/templates/Package.h \ + qmfgen/management-types.xml EXTRA_DIST = $(nobase_qmfpython_DATA) diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index d71097b4b4..21c42dc107 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -20,9 +20,9 @@ # import sys import os -from qmf.schema import SchemaPackage, SchemaClass -from qmf.generate import Generator -from optparse import OptionParser +from qmfgen.schema import SchemaPackage, SchemaClass +from qmfgen.generate import Generator +from optparse import OptionParser dataPath = os.path.dirname(Generator.getModulePath()) defaultTypeFile = dataPath + "/management-types.xml" diff --git a/qpid/cpp/managementgen/qmf/__init__.py b/qpid/cpp/managementgen/qmf/__init__.py deleted file mode 100644 index caef6cc58b..0000000000 --- a/qpid/cpp/managementgen/qmf/__init__.py +++ /dev/null @@ -1,19 +0,0 @@ -# -# 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. -# - diff --git a/qpid/cpp/managementgen/qmf/generate.py b/qpid/cpp/managementgen/qmf/generate.py deleted file mode 100755 index 2f2d51a1e2..0000000000 --- a/qpid/cpp/managementgen/qmf/generate.py +++ /dev/null @@ -1,369 +0,0 @@ -# -# 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: - """ - 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), - checking conditions (testCondition), and expanding tags (substHandler). - """ - def __init__ (self, filename, handler): - self.filename = filename - self.handler = handler - self.handler.initExpansion () - self.writing = True - - def expandLine (self, line, stream, object): - cursor = 0 - while 1: - sub = line.find ("/*MGEN:", cursor) - if sub == -1: - if self.writing: - stream.write (line[cursor:len (line)]) - return - - subend = line.find("*/", sub) - if self.writing: - stream.write (line[cursor:sub]) - cursor = subend + 2 - - tag = line[sub:subend] - - if tag[7:10] == "IF(": - close = tag.find(")") - if close == -1: - raise ValueError ("Missing ')' on condition") - cond = tag[10:close] - dotPos = cond.find (".") - if dotPos == -1: - raise ValueError ("Invalid condition tag: %s" % cond) - tagObject = cond[0:dotPos] - tagName = cond[dotPos + 1 : len(cond)] - if not self.handler.testCondition(object, tagObject, tagName): - self.writing = False - - elif tag[7:12] == "ENDIF": - self.writing = True - - else: - 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)] - if self.writing: - self.handler.substHandler (object, stream, tagObject, tagName) - else: - tagKey = tag[7:equalPos] - tagVal = tag[equalPos + 1:len (tag)] - if self.writing: - 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, packagelist): - self.filelists = filelists - self.templateFiles = templateFiles - self.packagelist = packagelist - - def genGenSources (self, stream, variables): - mdir = variables["mgenDir"] - sdir = variables["specDir"] - stream.write (mdir + "/qmf-gen \\\n") - stream.write (" " + mdir + "/qmf/generate.py \\\n") - stream.write (" " + mdir + "/qmf/schema.py \\\n") - stream.write (" " + mdir + "/qmf/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 + "/qmf/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) - - def genGeneratedFiles(self, stream, variables): - first = True - extensions = ("h", "cpp") - for ext in extensions: - for file in self.filelists[ext]: - if first: - first = False - else: - stream.write(" \\\n ") - if "genprefix" in variables: - prefix = variables["genprefix"] - if prefix != "": - stream.write(prefix + "/") - stream.write(file) - - def genHeaderInstalls (self, stream, variables): - for package in self.packagelist: - name = "_".join(package.split("/")) - stream.write(name + "dir = $(includedir)/qmf/" + package + "\n") - stream.write("dist_" + name + "_HEADERS = ") - first = True - for file in self.filelists["h"]: - if file.find("gen/qmf/" + package) == 0: - if first: - first = False - else: - stream.write (" \\\n ") - stream.write(file) - stream.write("\n\n") - - def testQpidBroker(self, variables): - if "qpidbroker" in variables: - return variables["qpidbroker"] - return False - - -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: - mode = os.stat (path)[ST_MODE] - except OSError, (err,text): - if err == ENOENT or err == ESRCH: - 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) - if pair[0] != '': - 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.packagePath = self.dest - self.filelists = {} - self.filelists["h"] = [] - self.filelists["cpp"] = [] - self.filelists["mk"] = [] - self.packagelist = [] - self.templateFiles = [] - self.variables = {} - - def setPackage (self, packageName): - path = "/".join(packageName.split(".")) - self.packagelist.append(path) - self.packagePath = self.normalize(self.dest + path) - - 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 (".") - 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.packagePath + "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 targetPackageFile (self, schema, templateFile): - dot = templateFile.find(".") - if dot == -1: - raise ValueError ("Invalid template file name %s" % templateFile) - extension = templateFile[dot:len (templateFile)] - path = self.packagePath + "Package" + extension - return path - - 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.packagePath + _class.getNameCap () + extension - return path - - def targetEventFile (self, event, templateFile): - dot = templateFile.find(".") - if dot == -1: - raise ValueError ("Invalid template file name %s" % templateFile) - extension = templateFile[dot:len (templateFile)] - path = self.packagePath + "Event" + event.getNameCap () + 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.packagePath + "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, self.variables)" - eval (call) - - def testCondition (self, object, tagObject, tag): - if tagObject == "Root": - obj = "self" - else: - obj = "object" # MUST be the same as the 2nd formal parameter - - call = obj + ".test" + tag + "(self.variables)" - return eval (call) - - 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) - self.templateFiles.append (templateFile) - for _class in classes: - target = self.targetClassFile (_class, templateFile) - stream = template.expand (_class) - self.writeIfChanged (stream, target, force) - - def makeEventFiles (self, templateFile, schema, force=False): - """ Generate an expanded template per schema event """ - events = schema.getEvents() - template = Template (self.input + templateFile, self) - self.templateFiles.append (templateFile) - for event in events: - target = self.targetEventFile(event, templateFile) - stream = template.expand(event) - self.writeIfChanged(stream, target, force) - - def makeMethodFiles (self, templateFile, schema, force=False): - """ Generate an expanded template per method-with-arguments """ - classes = schema.getClasses () - template = Template (self.input + templateFile, self) - 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, force) - - def makePackageFile (self, templateFile, schema, force=False): - """ Generate a package-specific file """ - template = Template (self.input + templateFile, self) - self.templateFiles.append (templateFile) - target = self.targetPackageFile (schema, templateFile) - stream = template.expand (schema) - self.writeIfChanged (stream, target, force) - - def makeSingleFile (self, templateFile, target, force=False, vars=None): - """ Generate a single expanded template """ - makefile = Makefile (self.filelists, self.templateFiles, self.packagelist) - template = Template (self.input + templateFile, self) - if vars: - for arg in vars: - self.setVariable(arg, vars[arg]) - self.templateFiles.append (templateFile) - stream = template.expand (makefile) - self.writeIfChanged (stream, target, force) - - def getModulePath(): - return __file__ - - getModulePath = staticmethod(getModulePath) diff --git a/qpid/cpp/managementgen/qmf/management-types.xml b/qpid/cpp/managementgen/qmf/management-types.xml deleted file mode 100644 index 626880afb3..0000000000 --- a/qpid/cpp/managementgen/qmf/management-types.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/qpid/cpp/managementgen/qmf/schema.py b/qpid/cpp/managementgen/qmf/schema.py deleted file mode 100755 index 692a474992..0000000000 --- a/qpid/cpp/managementgen/qmf/schema.py +++ /dev/null @@ -1,1339 +0,0 @@ -# -# 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 -import md5 - -class Hash: - """ Manage the hash of an XML sub-tree """ - def __init__(self, node): - self.md5Sum = md5.new() - self._compute(node) - - def addSubHash(self, hash): - """ Use this method to add the hash of a dependend-on XML fragment that is not in the sub-tree """ - self.md5Sum.update(hash.getDigest()) - - def getDigest(self): - return self.md5Sum.digest() - - def _compute(self, node): - attrs = node.attributes - self.md5Sum.update(node.nodeName) - - for idx in range(attrs.length): - self.md5Sum.update(attrs.item(idx).nodeName) - self.md5Sum.update(attrs.item(idx).nodeValue) - - for child in node.childNodes: - if child.nodeType == Node.ELEMENT_NODE: - self._compute(child) - - -#===================================================================================== -# -#===================================================================================== -class SchemaType: - def __init__ (self, node): - self.name = None - self.base = None - self.cpp = None - self.encode = None - self.decode = None - self.style = "normal" - self.accessor = None - self.init = "0" - self.perThread = False - self.byRef = False - - attrs = node.attributes - for idx in range (attrs.length): - key = attrs.item(idx).nodeName - val = attrs.item(idx).nodeValue - if key == 'name': - self.name = val - - elif key == 'base': - self.base = val - - elif key == 'cpp': - self.cpp = val - - elif key == 'encode': - self.encode = val - - elif key == 'decode': - self.decode = val - - elif key == 'style': - self.style = val - - elif key == 'accessor': - self.accessor = val - - elif key == 'init': - self.init = val - - elif key == 'perThread': - if val != 'y': - raise ValueError ("Expected 'y' in perThread attribute") - self.perThread = True - - elif key == 'byRef': - if val != 'y': - raise ValueError ("Expected 'y' in byRef attribute") - self.byRef = True - - else: - raise ValueError ("Unknown attribute in type '%s'" % key) - - if self.name == None or self.base == None or self.cpp == None or \ - self.encode == None or self.decode == None: - raise ValueError ("Missing required attribute(s) in type") - - if self.byRef: - self.asArg = "const " + self.cpp + "&" - else: - self.asArg = self.cpp - - def getName (self): - return self.name - - def genAccessor (self, stream, varName, changeFlag = None, optional = False): - if self.perThread: - prefix = "getThreadStats()->" - if self.style == "wm": - raise ValueError ("'wm' style types can't be per-thread") - else: - prefix = "" - if self.accessor == "direct": - stream.write (" inline void set_" + varName + " (" + self.asArg + " val) {\n"); - if not self.perThread: - stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") - if self.style != "mma": - stream.write (" " + prefix + varName + " = val;\n") - if optional: - stream.write (" presenceMask[presenceByte_%s] |= presenceMask_%s;\n" % (varName, varName)) - if self.style == "wm": - stream.write (" if (" + varName + "Low > val)\n") - stream.write (" " + varName + "Low = val;\n") - stream.write (" if (" + varName + "High < val)\n") - stream.write (" " + varName + "High = val;\n") - if self.style == "mma": - stream.write (" " + prefix + varName + "Count++;\n") - stream.write (" " + prefix + varName + "Total += val;\n") - stream.write (" if (" + prefix + varName + "Min > val)\n") - stream.write (" " + prefix + varName + "Min = val;\n") - stream.write (" if (" + prefix + varName + "Max < val)\n") - stream.write (" " + prefix + varName + "Max = val;\n") - if changeFlag != None: - stream.write (" " + changeFlag + " = true;\n") - stream.write (" }\n") - if self.style != "mma": - stream.write (" inline " + self.asArg + " get_" + varName + "() {\n"); - if not self.perThread: - stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") - stream.write (" return " + prefix + varName + ";\n") - stream.write (" }\n") - if optional: - stream.write (" inline void clr_" + varName + "() {\n") - stream.write (" presenceMask[presenceByte_%s] &= ~presenceMask_%s;\n" % (varName, varName)) - if changeFlag != None: - stream.write (" " + changeFlag + " = true;\n") - stream.write (" }\n") - stream.write (" inline bool isSet_" + varName + "() {\n") - stream.write (" return (presenceMask[presenceByte_%s] & presenceMask_%s) != 0;\n" % (varName, varName)) - stream.write (" }\n") - elif self.accessor == "counter": - stream.write (" inline void inc_" + varName + " (" + self.asArg + " by = 1) {\n"); - if not self.perThread: - stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") - stream.write (" " + prefix + varName + " += by;\n") - if self.style == "wm": - stream.write (" if (" + varName + "High < " + varName + ")\n") - stream.write (" " + varName + "High = " + varName + ";\n") - if changeFlag != None: - stream.write (" " + changeFlag + " = true;\n") - stream.write (" }\n"); - stream.write (" inline void dec_" + varName + " (" + self.asArg + " by = 1) {\n"); - if not self.perThread: - stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") - stream.write (" " + prefix + varName + " -= by;\n") - if self.style == "wm": - stream.write (" if (" + varName + "Low > " + varName + ")\n") - stream.write (" " + varName + "Low = " + varName + ";\n") - if changeFlag != None: - stream.write (" " + changeFlag + " = true;\n") - stream.write (" }\n"); - - def genHiLoStatResets (self, stream, varName): - if self.style == "wm": - stream.write (" " + varName + "High = " + varName + ";\n") - stream.write (" " + varName + "Low = " + varName + ";\n") - if self.style == "mma": - stream.write (" " + varName + "Count = 0;\n") - stream.write (" " + varName + "Total = 0;\n") - stream.write (" " + varName + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") - stream.write (" " + varName + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") - - def genPerThreadHiLoStatResets (self, stream, varName, cpptype): - if self.style == "mma": - stream.write (" threadStats->" + varName + "Count = 0;\n") - stream.write (" threadStats->" + varName + "Total = 0;\n") - stream.write (" threadStats->" + varName + "Min = std::numeric_limits<" + cpptype + ">::max();\n") - stream.write (" threadStats->" + varName + "Max = std::numeric_limits<" + cpptype + ">::min();\n") - - def genWrite (self, stream, varName, indent=" "): - if self.style != "mma": - stream.write (indent + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") - if self.style == "wm": - stream.write (indent + self.encode.replace ("@", "buf") \ - .replace ("#", varName + "High") + ";\n") - stream.write (indent + self.encode.replace ("@", "buf") \ - .replace ("#", varName + "Low") + ";\n") - if self.style == "mma": - stream.write (indent + self.encode.replace ("@", "buf") \ - .replace ("#", varName + "Count") + ";\n") - stream.write (indent + self.encode.replace ("@", "buf") \ - .replace ("#", varName + "Count ? " + varName + "Min : 0") + ";\n") - stream.write (indent + self.encode.replace ("@", "buf") \ - .replace ("#", varName + "Max") + ";\n") - stream.write (indent + self.encode.replace ("@", "buf") \ - .replace ("#", varName + "Count ? " + varName + "Total / " + - varName + "Count : 0") + ";\n") - - - def getReadCode (self, varName, bufName): - result = self.decode.replace ("@", bufName).replace ("#", varName) - return result - - def getWriteCode (self, varName, bufName): - result = self.encode.replace ("@", bufName).replace ("#", varName) - return result - -#===================================================================================== -# -#===================================================================================== -class TypeSpec: - def __init__ (self, file): - self.types = {} - dom = parse (file) - document = dom.documentElement - if document.tagName != 'schema-types': - raise ValueError ("Expected 'schema-types' in type file") - - for child in document.childNodes: - if child.nodeType == Node.ELEMENT_NODE: - if child.nodeName == 'type': - stype = SchemaType (child) - self.types[stype.getName ()] = stype - else: - raise ValueError ("Unknown type tag '%s'" % child.nodeName) - - def getType (self, name): - return self.types[name] - - -#===================================================================================== -# -#===================================================================================== -class Type: - def __init__ (self, name, typespec): - self.type = typespec.getType (name) - -#===================================================================================== -# -#===================================================================================== -class SchemaProperty: - def __init__ (self, node, typespec): - self.name = None - self.type = None - self.ref = None - self.access = "RO" - self.isIndex = 0 - self.isParentRef = 0 - self.isGeneralRef = 0 - self.isOptional = 0 - self.unit = None - self.min = None - self.max = None - self.maxLen = None - self.desc = None - - attrs = node.attributes - for idx in range (attrs.length): - key = attrs.item(idx).nodeName - val = attrs.item(idx).nodeValue - if key == 'name': - self.name = makeValidCppSymbol(val) - - elif key == 'type': - self.type = Type (val, typespec) - if self.type.type.accessor != 'direct': - raise ValueError ("Class properties must have a type with a direct accessor") - - elif key == 'references': - self.ref = val - - elif key == 'access': - self.access = val - - elif key == 'index': - if val != 'y': - raise ValueError ("Expected 'y' in index attribute") - self.isIndex = 1 - - elif key == 'parentRef': - if val != 'y': - raise ValueError ("Expected 'y' in parentRef attribute") - self.isParentRef = 1 - - elif key == 'isGeneralReference': - if val != 'y': - raise ValueError ("Expected 'y' in isGeneralReference attribute") - self.isGeneralRef = 1 - - elif key == 'optional': - if val != 'y': - raise ValueError ("Expected 'y' in optional attribute") - self.isOptional = 1 - - elif key == 'unit': - self.unit = val - - elif key == 'min': - self.min = val - - elif key == 'max': - self.max = val - - elif key == 'maxlen': - self.maxLen = val - - elif key == 'desc': - self.desc = val - - else: - raise ValueError ("Unknown attribute in property '%s'" % key) - - if self.access == "RC" and self.isOptional == 1: - raise ValueError ("Properties with ReadCreate access must not be optional (%s)" % self.name) - - if self.name == None: - raise ValueError ("Missing 'name' attribute in property") - if self.type == None: - raise ValueError ("Missing 'type' attribute in property") - - def getName (self): - return self.name - - def isConstructorArg (self): - if self.access == "RC" and self.isParentRef == 0: - return 1 - return 0 - - def genDeclaration (self, stream, prefix=" "): - stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") - - def genFormalParam (self, stream, variables): - stream.write (self.type.type.asArg + " _" + self.name) - - def genAccessor (self, stream): - self.type.type.genAccessor (stream, self.name, "configChanged", self.isOptional == 1) - - def genInitialize (self, stream, prefix="", indent=" "): - val = self.type.type.init - stream.write (indent + prefix + self.name + " = " + val + ";\n") - - def genSchema (self, stream): - stream.write (" ft = FieldTable ();\n") - stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") - stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") - stream.write (" ft.setInt (ACCESS, ACCESS_" + self.access + ");\n") - stream.write (" ft.setInt (IS_INDEX, " + str (self.isIndex) + ");\n") - stream.write (" ft.setInt (IS_OPTIONAL, " + str (self.isOptional) + ");\n") - if self.unit != None: - stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") - if self.min != None: - stream.write (" ft.setInt (MIN, " + self.min + ");\n") - if self.max != None: - stream.write (" ft.setInt (MAX, " + self.max + ");\n") - if self.maxLen != None: - stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") - if self.desc != None: - stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") - stream.write (" buf.put (ft);\n\n") - - def genWrite (self, stream): - indent = " " - if self.isOptional: - stream.write(" if (presenceMask[presenceByte_%s] & presenceMask_%s) {\n" % (self.name, self.name)) - indent = " " - self.type.type.genWrite (stream, self.name, indent) - if self.isOptional: - stream.write(" }\n") - - -#===================================================================================== -# -#===================================================================================== -class SchemaStatistic: - def __init__ (self, node, typespec): - self.name = None - self.type = None - self.unit = None - self.desc = None - self.assign = None - - attrs = node.attributes - for idx in range (attrs.length): - key = attrs.item(idx).nodeName - val = attrs.item(idx).nodeValue - if key == 'name': - self.name = makeValidCppSymbol(val) - - elif key == 'type': - self.type = Type (val, typespec) - - elif key == 'unit': - self.unit = val - - elif key == 'desc': - self.desc = val - - elif key == 'assign': - self.assign = val - - else: - raise ValueError ("Unknown attribute in statistic '%s'" % key) - - if self.name == None: - raise ValueError ("Missing 'name' attribute in statistic") - if self.type == None: - raise ValueError ("Missing 'type' attribute in statistic") - - def getName (self): - return self.name - - def genDeclaration (self, stream, prefix=" "): - if self.type.type.style != "mma": - stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") - if self.type.type.style == 'wm': - stream.write (prefix + self.type.type.cpp + " " + self.name + "High;\n") - stream.write (prefix + self.type.type.cpp + " " + self.name + "Low;\n") - if self.type.type.style == "mma": - stream.write (prefix + self.type.type.cpp + " " + self.name + "Count;\n") - stream.write (prefix + "uint64_t " + self.name + "Total;\n") - stream.write (prefix + self.type.type.cpp + " " + self.name + "Min;\n") - stream.write (prefix + self.type.type.cpp + " " + self.name + "Max;\n") - - def genAccessor (self, stream): - self.type.type.genAccessor (stream, self.name, "instChanged") - - def genHiLoStatResets (self, stream): - self.type.type.genHiLoStatResets (stream, self.name) - - def genPerThreadHiLoStatResets (self, stream): - self.type.type.genPerThreadHiLoStatResets (stream, self.name, self.type.type.cpp) - - def genSchemaText (self, stream, name, desc): - stream.write (" ft = FieldTable ();\n") - stream.write (" ft.setString (NAME, \"" + name + "\");\n") - stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") - if self.unit != None: - stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") - if desc != None: - stream.write (" ft.setString (DESC, \"" + desc + "\");\n") - stream.write (" buf.put (ft);\n\n") - - def genSchema (self, stream): - if self.type.type.style != "mma": - self.genSchemaText (stream, self.name, self.desc) - if self.type.type.style == "wm": - descHigh = self.desc - descLow = self.desc - if self.desc != None: - descHigh = descHigh + " (High)" - descLow = descLow + " (Low)" - self.genSchemaText (stream, self.name + "High", descHigh) - self.genSchemaText (stream, self.name + "Low", descLow) - if self.type.type.style == "mma": - descCount = self.desc - descMin = self.desc - descMax = self.desc - descAverage = self.desc - if self.desc != None: - descCount = descCount + " (Samples)" - descMin = descMin + " (Min)" - descMax = descMax + " (Max)" - descAverage = descAverage + " (Average)" - self.genSchemaText (stream, self.name + "Samples", descCount) - self.genSchemaText (stream, self.name + "Min", descMin) - self.genSchemaText (stream, self.name + "Max", descMax) - self.genSchemaText (stream, self.name + "Average", descAverage) - - def genAssign (self, stream): - if self.assign != None: - if self.type.type.perThread: - prefix = " threadStats->" - else: - prefix = "" - stream.write (" " + prefix + self.name + " = (" + self.type.type.cpp + - ") (" + self.assign + ");\n") - - def genWrite (self, stream): - if self.type.type.perThread: - self.type.type.genWrite (stream, "totals." + self.name) - else: - self.type.type.genWrite (stream, self.name) - - def genInitialize (self, stream, prefix="", indent=" "): - val = self.type.type.init - if self.type.type.style != "mma": - stream.write (indent + prefix + self.name + " = " + val + ";\n") - if self.type.type.style == "wm": - stream.write (indent + prefix + self.name + "High = " + val + ";\n") - stream.write (indent + prefix + self.name + "Low = " + val + ";\n") - if self.type.type.style == "mma": - stream.write (indent + prefix + self.name + "Count = 0;\n") - stream.write (indent + prefix + self.name + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") - stream.write (indent + prefix + self.name + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") - stream.write (indent + prefix + self.name + "Total = 0;\n") - - def genInitializeTotalPerThreadStats (self, stream): - if self.type.type.style == "mma": - stream.write (" totals->" + self.name + "Count = 0;\n") - stream.write (" totals->" + self.name + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") - stream.write (" totals->" + self.name + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") - stream.write (" totals->" + self.name + "Total = 0;\n") - else: - stream.write (" totals->" + self.name + " = 0;\n") - - def genAggregatePerThreadStats (self, stream): - if self.type.type.style == "mma": - stream.write (" totals->%sCount += threadStats->%sCount;\n" % (self.name, self.name)) - stream.write (" if (totals->%sMin > threadStats->%sMin)\n" % (self.name, self.name)) - stream.write (" totals->%sMin = threadStats->%sMin;\n" % (self.name, self.name)) - stream.write (" if (totals->%sMax < threadStats->%sMax)\n" % (self.name, self.name)) - stream.write (" totals->%sMax = threadStats->%sMax;\n" % (self.name, self.name)) - stream.write (" totals->%sTotal += threadStats->%sTotal;\n" % (self.name, self.name)) - else: - stream.write (" totals->%s += threadStats->%s;\n" % (self.name, self.name)) - -#===================================================================================== -# -#===================================================================================== -class SchemaArg: - def __init__ (self, node, typespec): - self.name = None - self.type = None - self.unit = None - self.dir = "I" - self.min = None - self.max = None - self.maxLen = None - self.desc = None - self.default = None - self.hash = Hash(node) - - attrs = node.attributes - for idx in range (attrs.length): - key = attrs.item(idx).nodeName - val = attrs.item(idx).nodeValue - if key == 'name': - self.name = makeValidCppSymbol(val) - - elif key == 'type': - self.type = Type (val, typespec) - - elif key == 'unit': - self.unit = val - - elif key == 'dir': - self.dir = val.upper () - - elif key == 'min': - self.min = val - - elif key == 'max': - self.max = val - - elif key == 'maxlen': - self.maxLen = val - - elif key == 'desc': - self.desc = val - - elif key == 'default': - self.default = val - - else: - raise ValueError ("Unknown attribute in arg '%s'" % key) - - if self.name == None: - raise ValueError ("Missing 'name' attribute in arg") - if self.type == None: - raise ValueError ("Missing 'type' attribute in arg") - - def getName (self): - return self.name - - def getDir (self): - return self.dir - - def genSchema (self, stream, event=False): - stream.write (" ft = FieldTable ();\n") - stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") - stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") - if (not event): - stream.write (" ft.setString (DIR, \"" + self.dir + "\");\n") - if self.unit != None: - stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") - if not event: - if self.min != None: - stream.write (" ft.setInt (MIN, " + self.min + ");\n") - if self.max != None: - stream.write (" ft.setInt (MAX, " + self.max + ");\n") - if self.maxLen != None: - stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") - if self.default != None: - stream.write (" ft.setString (DEFAULT, \"" + self.default + "\");\n") - if self.desc != None: - stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") - stream.write (" buf.put (ft);\n\n") - - def genFormalParam (self, stream, variables): - stream.write ("%s _%s" % (self.type.type.asArg, self.name)) - -#===================================================================================== -# -#===================================================================================== -class SchemaMethod: - def __init__ (self, parent, node, typespec): - self.parent = parent - self.name = None - self.desc = None - self.args = [] - - attrs = node.attributes - for idx in range (attrs.length): - key = attrs.item(idx).nodeName - val = attrs.item(idx).nodeValue - if key == 'name': - self.name = makeValidCppSymbol(val) - - elif key == 'desc': - self.desc = val - - else: - raise ValueError ("Unknown attribute in method '%s'" % key) - - for child in node.childNodes: - if child.nodeType == Node.ELEMENT_NODE: - if child.nodeName == 'arg': - arg = SchemaArg (child, typespec) - self.args.append (arg) - else: - raise ValueError ("Unknown method tag '%s'" % child.nodeName) - - def getName (self): - return self.name - - def getFullName (self): - return capitalize(self.parent.getName()) + self.name[0:1].upper() +\ - self.name[1:] - - def getArgCount (self): - return len (self.args) - - #=================================================================================== - # Code Generation Functions. The names of these functions (minus the leading "gen") - # match the substitution keywords in the template files. - #=================================================================================== - def genNameUpper (self, stream, variables): - stream.write (self.getFullName ().upper ()) - - def genNameCamel (self, stream, variables): - stream.write (self.getFullName ()) - - def genOpenNamespaces (self, stream, variables): - self.parent.genOpenNamespaces(stream, variables) - - def genCloseNamespaces (self, stream, variables): - self.parent.genCloseNamespaces(stream, variables) - - 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 genNamePackageLower (self, stream, variables): - self.parent.genNamePackageLower(stream, variables) - - 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") - if self.desc != None: - stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") - stream.write (" buf.put (ft);\n\n") - for arg in self.args: - arg.genSchema (stream) - -#===================================================================================== -# -#===================================================================================== -class SchemaEvent: - def __init__ (self, package, node, typespec, argset): - self.packageName = package - self.name = None - self.desc = None - self.sevText = "inform" - self.args = [] - self.hash = Hash(node) - - attrs = node.attributes - for idx in range (attrs.length): - key = attrs.item(idx).nodeName - val = attrs.item(idx).nodeValue - if key == 'name': - self.name = val - - elif key == 'desc': - self.desc = val - - elif key == 'sev': - self.sevText = val - - elif key == 'args': - list = val.replace(" ", "").split(",") - for item in list: - if item not in argset.args: - raise Exception("undefined argument '%s' in event" % item) - self.args.append(argset.args[item]) - self.hash.addSubHash(argset.args[item].hash) - - else: - raise ValueError ("Unknown attribute in event '%s'" % key) - - if self.sevText == "emerg" : self.sev = 0 - elif self.sevText == "alert" : self.sev = 1 - elif self.sevText == "crit" : self.sev = 2 - elif self.sevText == "error" : self.sev = 3 - elif self.sevText == "warn" : self.sev = 4 - elif self.sevText == "notice" : self.sev = 5 - elif self.sevText == "inform" : self.sev = 6 - elif self.sevText == "debug" : self.sev = 7 - else: - raise ValueError("Unknown severity '%s' in event '%s'" % (self.sevText, self.name)) - - def getName (self): - return self.name - - def getNameCap(self): - return capitalize(self.name) - - def getFullName (self): - return capitalize(self.package + capitalize(self.name)) - - def getArgCount (self): - return len (self.args) - - def genArgCount (self, stream, variables): - stream.write("%d" % len(self.args)) - - def genArgDeclarations(self, stream, variables): - for arg in self.args: - if arg.type.type.byRef: - ref = "&" - else: - ref = "" - stream.write(" const %s%s %s;\n" % (arg.type.type.cpp, ref, arg.name)) - - def genCloseNamespaces (self, stream, variables): - for item in self.packageName.split("."): - stream.write ("}") - - def genConstructorArgs(self, stream, variables): - pre = "" - for arg in self.args: - if arg.type.type.byRef: - ref = "&" - else: - ref = "" - stream.write("%sconst %s%s _%s" % (pre, arg.type.type.cpp, ref, arg.name)) - pre = ",\n " - - def genConstructorInits(self, stream, variables): - pre = "" - for arg in self.args: - stream.write("%s%s(_%s)" % (pre, arg.name, arg.name)) - pre = ",\n " - - def genName(self, stream, variables): - stream.write(self.name) - - def genNameCap(self, stream, variables): - stream.write(capitalize(self.name)) - - def genNamespace (self, stream, variables): - stream.write("::".join(self.packageName.split("."))) - - def genNameLower(self, stream, variables): - stream.write(self.name.lower()) - - def genNameUpper(self, stream, variables): - stream.write(self.name.upper()) - - def genNamePackageLower(self, stream, variables): - stream.write(self.packageName.lower()) - - def genOpenNamespaces (self, stream, variables): - for item in self.packageName.split("."): - stream.write ("namespace %s {\n" % item) - - def genSeverity(self, stream, variables): - stream.write("%d" % self.sev) - - def genArgEncodes(self, stream, variables): - for arg in self.args: - stream.write(" " + arg.type.type.encode.replace("@", "buf").replace("#", arg.name) + ";\n") - - def genArgSchema(self, stream, variables): - for arg in self.args: - arg.genSchema(stream, True) - - def genSchemaMD5(self, stream, variables): - sum = self.hash.getDigest() - for idx in range (len (sum)): - if idx != 0: - stream.write (",") - stream.write (hex (ord (sum[idx]))) - - -class SchemaClass: - def __init__ (self, package, node, typespec, fragments, options): - self.packageName = package - self.properties = [] - self.statistics = [] - self.methods = [] - self.events = [] - self.options = options - self.hash = Hash(node) - - attrs = node.attributes - self.name = makeValidCppSymbol(attrs['name'].nodeValue) - - children = node.childNodes - for child in children: - if child.nodeType == Node.ELEMENT_NODE: - if child.nodeName == 'property': - sub = SchemaProperty (child, typespec) - self.properties.append (sub) - - elif child.nodeName == 'statistic': - sub = SchemaStatistic (child, typespec) - self.statistics.append (sub) - - elif child.nodeName == 'method': - sub = SchemaMethod (self, child, typespec) - self.methods.append (sub) - - elif child.nodeName == 'group': - self.expandFragment (child, fragments) - - else: - raise ValueError ("Unknown class tag '%s'" % child.nodeName) - - # Adjust the 'assign' attributes for each statistic - for stat in self.statistics: - if stat.assign != None and stat.type.type.perThread: - stat.assign = self.adjust (stat.assign, self.statistics) - - def adjust (self, text, statistics): - result = text - start = 0 - while True: - next = None - for stat in statistics: - pos = result.find (stat.name, start) - if pos != -1 and (next == None or pos < next[0]): - next = (pos, stat.name) - if next == None: - return result - pos = next[0] - result = result[0:pos] + "threadStats->" + result[pos:] - start = pos + 9 + len(next[1]) - - def expandFragment (self, node, fragments): - attrs = node.attributes - name = attrs['name'].nodeValue - for fragment in fragments: - if fragment.name == name: - self.hash.addSubHash(fragment.hash) - for config in fragment.properties: - self.properties.append (config) - for inst in fragment.statistics: - self.statistics.append (inst) - for method in fragment.methods: - self.methods.append (method) - for event in fragment.events: - self.events.append (event) - return - raise ValueError ("Undefined group '%s'" % name) - - def getName (self): - return self.name - - def getNameCap (self): - return capitalize(self.name) - - def getMethods (self): - return self.methods - - def getEvents (self): - return self.events - - def getPackageNameCap (self): - return capitalize(self.packageName) - - #=================================================================================== - # Code Generation Functions. The names of these functions (minus the leading "gen") - # match the substitution keywords in the template files. - #=================================================================================== - def testExistOptionals (self, variables): - for prop in self.properties: - if prop.isOptional == 1: - return True - return False - - def testExistPerThreadStats (self, variables): - for inst in self.statistics: - if inst.type.type.perThread: - return True - return False - - def testExistPerThreadAssign (self, variables): - for inst in self.statistics: - if inst.type.type.perThread and inst.assign != None: - return True - return False - - def testExistPerThreadResets (self, variables): - for inst in self.statistics: - if inst.type.type.perThread and inst.type.type.style == "mma": - return True - return False - - def testNoStatistics (self, variables): - return len (self.statistics) == 0 - - def genAccessorMethods (self, stream, variables): - for config in self.properties: - if config.access != "RC": - config.genAccessor (stream) - for inst in self.statistics: - if inst.assign == None: - inst.genAccessor (stream) - - def genCloseNamespaces (self, stream, variables): - for item in self.packageName.split("."): - stream.write ("}") - - def genConfigCount (self, stream, variables): - stream.write ("%d" % len (self.properties)) - - def genConfigDeclarations (self, stream, variables): - for element in self.properties: - element.genDeclaration (stream) - - def genConstructorArgs (self, stream, variables): - # Constructor args are config elements with read-create access - result = "" - for element in self.properties: - if element.isConstructorArg (): - stream.write (", ") - element.genFormalParam (stream, variables) - - def genConstructorInits (self, stream, variables): - for element in self.properties: - if element.isConstructorArg (): - stream.write ("," + element.getName () + "(_" + element.getName () + ")") - - def genDoMethodArgs (self, stream, variables): - methodCount = 0 - inArgCount = 0 - for method in self.methods: - methodCount = methodCount + 1 - for arg in method.args: - if arg.getDir () == "I" or arg.getDir () == "IO": - inArgCount = inArgCount + 1 - - if methodCount == 0: - stream.write ("string&, Buffer&, Buffer& outBuf") - else: - if inArgCount == 0: - stream.write ("string& methodName, Buffer&, Buffer& outBuf") - else: - stream.write ("string& methodName, Buffer& inBuf, Buffer& outBuf") - - def genHiLoStatResets (self, stream, variables): - for inst in self.statistics: - if not inst.type.type.perThread: - inst.genHiLoStatResets (stream) - - def genPerThreadHiLoStatResets (self, stream, variables): - for inst in self.statistics: - if inst.type.type.perThread: - inst.genPerThreadHiLoStatResets (stream) - - def genInitializeElements (self, stream, variables): - for prop in self.properties: - if not prop.isConstructorArg() and not prop.isParentRef: - prop.genInitialize(stream) - for inst in self.statistics: - if not inst.type.type.perThread: - inst.genInitialize (stream) - - def genInitializePerThreadElements (self, stream, variables): - for inst in self.statistics: - if inst.type.type.perThread: - inst.genInitialize (stream, "threadStats->", " ") - - def genInitializeTotalPerThreadStats (self, stream, variables): - for inst in self.statistics: - if inst.type.type.perThread: - inst.genInitializeTotalPerThreadStats (stream) - - def genAggregatePerThreadStats (self, stream, variables): - for inst in self.statistics: - if inst.type.type.perThread: - inst.genAggregatePerThreadStats (stream) - - def genInstCount (self, stream, variables): - count = 0 - for inst in self.statistics: - count = count + 1 - if inst.type.type.style == "wm": - count = count + 2 - if inst.type.type.style == "mma": - count = count + 3 - stream.write ("%d" % count) - - def genInstDeclarations (self, stream, variables): - for element in self.statistics: - if not element.type.type.perThread: - element.genDeclaration (stream) - - def genPerThreadDeclarations (self, stream, variables): - for element in self.statistics: - if element.type.type.perThread: - element.genDeclaration (stream, " ") - - def genNamespace (self, stream, variables): - stream.write("::".join(self.packageName.split("."))) - - def genMethodArgIncludes (self, stream, variables): - for method in self.methods: - if method.getArgCount () > 0: - stream.write ("#include \"Args" + method.getFullName () + ".h\"\n") - - def genMethodCount (self, stream, variables): - stream.write ("%d" % len (self.methods)) - - def genMethodHandlers (self, stream, variables): - for method in self.methods: - stream.write ("\n if (methodName == \"" + method.getName () + "\") {\n") - if method.getArgCount () == 0: - stream.write (" ::qpid::management::ArgsNone ioArgs;\n") - else: - stream.write (" Args" + method.getFullName () + " ioArgs;\n") - for arg in method.args: - if arg.getDir () == "I" or arg.getDir () == "IO": - stream.write (" " +\ - arg.type.type.getReadCode ("ioArgs." +\ - arg.dir.lower () + "_" +\ - arg.name, "inBuf") + ";\n") - - stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ - method.getName().upper() + ", ioArgs, text);\n") - stream.write (" outBuf.putLong (status);\n") - stream.write (" outBuf.putMediumString(::qpid::management::Manageable::StatusText (status, text));\n") - for arg in method.args: - if arg.getDir () == "O" or arg.getDir () == "IO": - stream.write (" " +\ - arg.type.type.getWriteCode ("ioArgs." +\ - arg.dir.lower () + "_" +\ - arg.name, "outBuf") + ";\n") - stream.write (" return;\n }\n") - - def genOpenNamespaces (self, stream, variables): - for item in self.packageName.split("."): - stream.write ("namespace %s {\n" % item) - - def genPresenceMaskBytes (self, stream, variables): - count = 0 - for prop in self.properties: - if prop.isOptional == 1: - count += 1 - if count == 0: - stream.write("0") - else: - stream.write (str(((count - 1) / 8) + 1)) - - def genPresenceMaskConstants (self, stream, variables): - count = 0 - for prop in self.properties: - if prop.isOptional == 1: - stream.write(" static const uint8_t presenceByte_%s = %d;\n" % (prop.name, count / 8)) - stream.write(" static const uint8_t presenceMask_%s = %d;\n" % (prop.name, 1 << (count % 8))) - count += 1 - - def genPropertySchema (self, stream, variables): - for prop in self.properties: - prop.genSchema (stream) - - def genSetGeneralReferenceDeclaration (self, stream, variables): - for prop in self.properties: - if prop.isGeneralRef: - stream.write ("void setReference(::qpid::management::ObjectId objectId) { " + prop.name + " = objectId; }\n") - - def genStatisticSchema (self, stream, variables): - for stat in self.statistics: - stat.genSchema (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, variables): - for method in self.methods: - method.genSchema (stream, variables) - - def genNameCap (self, stream, variables): - stream.write (capitalize(self.name)) - - def genNameLower (self, stream, variables): - stream.write (self.name.lower ()) - - def genNamePackageCap (self, stream, variables): - stream.write (self.getPackageNameCap ()) - - def genNamePackageLower (self, stream, variables): - stream.write (self.packageName.lower ()) - - def genNameUpper (self, stream, variables): - stream.write (self.name.upper ()) - - def genParentArg (self, stream, variables): - for config in self.properties: - if config.isParentRef == 1: - stream.write (", ::qpid::management::Manageable* _parent") - return - - def genParentRefAssignment (self, stream, variables): - for config in self.properties: - if config.isParentRef == 1: - stream.write (config.getName () + \ - " = _parent->GetManagementObject ()->getObjectId ();") - return - - def genSchemaMD5 (self, stream, variables): - sum = self.hash.getDigest() - for idx in range (len (sum)): - if idx != 0: - stream.write (",") - stream.write (hex (ord (sum[idx]))) - - def genAssign (self, stream, variables): - for inst in self.statistics: - if not inst.type.type.perThread: - inst.genAssign (stream) - - def genPerThreadAssign (self, stream, variables): - for inst in self.statistics: - if inst.type.type.perThread: - inst.genAssign (stream) - - def genWriteProperties (self, stream, variables): - for prop in self.properties: - prop.genWrite (stream) - - def genWriteStatistics (self, stream, variables): - for stat in self.statistics: - stat.genWrite (stream) - - -class SchemaEventArgs: - def __init__(self, package, node, typespec, fragments, options): - self.packageName = package - self.options = options - self.args = {} - - children = node.childNodes - for child in children: - if child.nodeType == Node.ELEMENT_NODE: - if child.nodeName == 'arg': - arg = SchemaArg(child, typespec) - self.args[arg.name] = arg - else: - raise Exception("Unknown tag '%s' in " % child.nodeName) - -class SchemaPackage: - def __init__ (self, typefile, schemafile, options): - - self.classes = [] - self.fragments = [] - self.typespec = TypeSpec (typefile) - self.eventArgSet = None - self.events = [] - - dom = parse (schemafile) - document = dom.documentElement - if document.tagName != 'schema': - raise ValueError ("Expected 'schema' node") - attrs = document.attributes - pname = attrs['package'].nodeValue - namelist = pname.split('.') - self.packageName = ".".join(namelist) - - children = document.childNodes - for child in children: - if child.nodeType == Node.ELEMENT_NODE: - if child.nodeName == 'class': - cls = SchemaClass (self.packageName, child, self.typespec, - self.fragments, options) - self.classes.append (cls) - - elif child.nodeName == 'group': - cls = SchemaClass (self.packageName, child, self.typespec, - self.fragments, options) - self.fragments.append (cls) - - elif child.nodeName == 'eventArguments': - if self.eventArgSet: - raise Exception("Only one may appear in a package") - self.eventArgSet = SchemaEventArgs(self.packageName, child, self.typespec, self.fragments, options) - - elif child.nodeName == 'event': - event = SchemaEvent(self.packageName, child, self.typespec, self.eventArgSet) - self.events.append(event) - - else: - raise ValueError ("Unknown schema tag '%s'" % child.nodeName) - - def getPackageName (self): - return self.packageName - - def getPackageNameCap (self): - return capitalize(self.packageName) - - def getPackageNameLower (self): - return self.packageName.lower() - - def getClasses (self): - return self.classes - - def getEvents(self): - return self.events - - def genCloseNamespaces (self, stream, variables): - for item in self.packageName.split("."): - stream.write ("}") - - def genNamespace (self, stream, variables): - stream.write("::".join(self.packageName.split("."))) - - def genOpenNamespaces (self, stream, variables): - for item in self.packageName.split("."): - stream.write ("namespace %s {\n" % item) - - def genPackageNameUpper (self, stream, variables): - up = "_".join(self.packageName.split(".")) - stream.write (up.upper()) - - def genNamePackageLower (self, stream, variables): - stream.write (self.packageName.lower ()) - - def genClassIncludes (self, stream, variables): - for _class in self.classes: - stream.write ("#include \"") - _class.genNameCap (stream, variables) - stream.write (".h\"\n") - for _event in self.events: - stream.write ("#include \"Event") - _event.genNameCap(stream, variables) - stream.write (".h\"\n") - - def genClassRegisters(self, stream, variables): - for _class in self.classes: - stream.write(" ") - _class.genNameCap(stream, variables) - stream.write("::registerSelf(agent);\n") - for _event in self.events: - stream.write(" Event") - _event.genNameCap(stream, variables) - stream.write("::registerSelf(agent);\n") - - -#===================================================================================== -# Utility Functions -#===================================================================================== - -# Create a valid C++ symbol from the input string so that it can be -# used in generated C++ source. For instance, change "qpid.mgmt" to -# "qpidMgmt". -# -# Input: Raw string (str) to process -# Output: String (str) suitable for use as a C++ symbol -# -# Limitations: Currently, only strips periods ('.') from strings, -# eventually should strip :'s and ,'s and ''s, oh my! -def makeValidCppSymbol(input): - output = str() - capitalize = False - - for char in input: - skip = False - - if char == ".": - capitalize = True - skip = True - - if not skip: - output += capitalize and char.upper() or char - - capitalize = False - - return output - -# Capitalize a string by /only/ forcing the first character to be -# uppercase. The rest of the string is left alone. This is different -# from str.capitalize(), which forces the first character to uppercase -# and the rest to lowercase. -# -# Input: A string (str) to capitalize -# Output: A string (str) with the first character as uppercase -def capitalize(input): - return input[0].upper() + input[1:] diff --git a/qpid/cpp/managementgen/qmf/templates/Args.h b/qpid/cpp/managementgen/qmf/templates/Args.h deleted file mode 100644 index 074ccf9940..0000000000 --- a/qpid/cpp/managementgen/qmf/templates/Args.h +++ /dev/null @@ -1,42 +0,0 @@ -/*MGEN:commentPrefix=//*/ -#ifndef _ARGS_/*MGEN:Method.NameUpper*/_ -#define _ARGS_/*MGEN:Method.NameUpper*/_ - -// -// 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. -// - -/*MGEN:Root.Disclaimer*/ - -#include "qpid/management/Args.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/framing/Uuid.h" -#include - -namespace qmf { -/*MGEN:Method.OpenNamespaces*/ - - class Args/*MGEN:Method.NameCamel*/ : public ::qpid::management::Args -{ - public: -/*MGEN:Method.Arguments*/ -}; - -}/*MGEN:Method.CloseNamespaces*/ - -#endif /*!_ARGS_/*MGEN:Method.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmf/templates/Class.cpp b/qpid/cpp/managementgen/qmf/templates/Class.cpp deleted file mode 100644 index 247e1090ff..0000000000 --- a/qpid/cpp/managementgen/qmf/templates/Class.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/*MGEN:commentPrefix=//*/ -// -// 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. -// - -/*MGEN:Root.Disclaimer*/ - -#include "qpid/log/Statement.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/management/Manageable.h" -#include "qpid/agent/ManagementAgent.h" -#include "/*MGEN:Class.NameCap*/.h" -/*MGEN:Class.MethodArgIncludes*/ - -using namespace qmf::/*MGEN:Class.Namespace*/; -using namespace qpid::framing; -using qpid::management::ManagementAgent; -using qpid::management::Manageable; -using qpid::management::ManagementObject; -using qpid::management::Args; -using std::string; - -string /*MGEN:Class.NameCap*/::packageName = string ("/*MGEN:Class.NamePackageLower*/"); -string /*MGEN:Class.NameCap*/::className = string ("/*MGEN:Class.NameLower*/"); -uint8_t /*MGEN:Class.NameCap*/::md5Sum[16] = - {/*MGEN:Class.SchemaMD5*/}; - -/*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (ManagementAgent* _agent, Manageable* _core/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/) : - ManagementObject(_agent, _core)/*MGEN:Class.ConstructorInits*/ -{ - /*MGEN:Class.ParentRefAssignment*/ -/*MGEN:Class.InitializeElements*/ -/*MGEN:IF(Class.ExistOptionals)*/ - // Optional properties start out not-present - for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) - presenceMask[idx] = 0; -/*MGEN:ENDIF*/ -/*MGEN:IF(Class.ExistPerThreadStats)*/ - maxThreads = agent->getMaxThreads(); - perThreadStatsArray = new struct PerThreadStats*[maxThreads]; - for (int idx = 0; idx < maxThreads; idx++) - perThreadStatsArray[idx] = 0; -/*MGEN:ENDIF*/ -} - -/*MGEN:Class.NameCap*/::~/*MGEN:Class.NameCap*/ () -{ -/*MGEN:IF(Class.ExistPerThreadStats)*/ - for (int idx = 0; idx < maxThreads; idx++) - if (perThreadStatsArray[idx] != 0) - delete perThreadStatsArray[idx]; - delete[] perThreadStatsArray; -/*MGEN:ENDIF*/ -} - -namespace { - const string NAME("name"); - const string TYPE("type"); - const string ACCESS("access"); - const string IS_INDEX("index"); - const string IS_OPTIONAL("optional"); - const string UNIT("unit"); - const string MIN("min"); - const string MAX("max"); - const string MAXLEN("maxlen"); - const string DESC("desc"); - const string ARGCOUNT("argCount"); - const string ARGS("args"); - const string DIR("dir"); - const string DEFAULT("default"); -} - -void /*MGEN:Class.NameCap*/::registerSelf(ManagementAgent* agent) -{ - agent->registerClass(packageName, className, md5Sum, writeSchema); -} - -void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) -{ - FieldTable ft; - - // Schema class header: - buf.putOctet (CLASS_KIND_TABLE); - buf.putShortString (packageName); // Package Name - buf.putShortString (className); // Class Name - buf.putBin128 (md5Sum); // Schema Hash - buf.putShort (/*MGEN:Class.ConfigCount*/); // Config Element Count - buf.putShort (/*MGEN:Class.InstCount*/); // Inst Element Count - buf.putShort (/*MGEN:Class.MethodCount*/); // Method Count - - // Properties -/*MGEN:Class.PropertySchema*/ - // Statistics -/*MGEN:Class.StatisticSchema*/ - // Methods -/*MGEN:Class.MethodSchema*/ -} - -/*MGEN:IF(Class.ExistPerThreadStats)*/ -void /*MGEN:Class.NameCap*/::aggregatePerThreadStats(struct PerThreadStats* totals) -{ -/*MGEN:Class.InitializeTotalPerThreadStats*/ - for (int idx = 0; idx < maxThreads; idx++) { - struct PerThreadStats* threadStats = perThreadStatsArray[idx]; - if (threadStats != 0) { -/*MGEN:Class.AggregatePerThreadStats*/ - } - } -} -/*MGEN:ENDIF*/ - -void /*MGEN:Class.NameCap*/::writeProperties (Buffer& buf) -{ - ::qpid::sys::Mutex::ScopedLock mutex(accessLock); - configChanged = false; - - writeTimestamps (buf); -/*MGEN:IF(Class.ExistOptionals)*/ - for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) - buf.putOctet(presenceMask[idx]); -/*MGEN:ENDIF*/ -/*MGEN:Class.WriteProperties*/ -} - -void /*MGEN:Class.NameCap*/::writeStatistics (Buffer& buf, bool skipHeaders) -{ - ::qpid::sys::Mutex::ScopedLock mutex(accessLock); - instChanged = false; -/*MGEN:IF(Class.ExistPerThreadAssign)*/ - for (int idx = 0; idx < maxThreads; idx++) { - struct PerThreadStats* threadStats = perThreadStatsArray[idx]; - if (threadStats != 0) { -/*MGEN:Class.PerThreadAssign*/ - } - } -/*MGEN:ENDIF*/ -/*MGEN:IF(Class.ExistPerThreadStats)*/ - struct PerThreadStats totals; - aggregatePerThreadStats(&totals); -/*MGEN:ENDIF*/ -/*MGEN:Class.Assign*/ - if (!skipHeaders) - writeTimestamps (buf); -/*MGEN:Class.WriteStatistics*/ - - // Maintenance of hi-lo statistics -/*MGEN:Class.HiLoStatResets*/ -/*MGEN:IF(Class.ExistPerThreadResets)*/ - for (int idx = 0; idx < maxThreads; idx++) { - struct PerThreadStats* threadStats = perThreadStatsArray[idx]; - if (threadStats != 0) { -/*MGEN:Class.PerThreadHiLoStatResets*/ - } - } -/*MGEN:ENDIF*/ -} - -void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) -{ - Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; - std::string text; - -/*MGEN:Class.MethodHandlers*/ - outBuf.putLong(status); - outBuf.putShortString(Manageable::StatusText(status, text)); -} diff --git a/qpid/cpp/managementgen/qmf/templates/Class.h b/qpid/cpp/managementgen/qmf/templates/Class.h deleted file mode 100644 index 7796914d51..0000000000 --- a/qpid/cpp/managementgen/qmf/templates/Class.h +++ /dev/null @@ -1,104 +0,0 @@ -/*MGEN:commentPrefix=//*/ -#ifndef _MANAGEMENT_/*MGEN:Class.NameUpper*/_ -#define _MANAGEMENT_/*MGEN:Class.NameUpper*/_ - -// -// 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. -// - -/*MGEN:Root.Disclaimer*/ - -#include "qpid/management/ManagementObject.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/framing/Uuid.h" - -namespace qmf { -/*MGEN:Class.OpenNamespaces*/ - -class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject -{ - private: - - static std::string packageName; - static std::string className; - static uint8_t md5Sum[16]; -/*MGEN:IF(Class.ExistOptionals)*/ - uint8_t presenceMask[/*MGEN:Class.PresenceMaskBytes*/]; -/*MGEN:Class.PresenceMaskConstants*/ -/*MGEN:ENDIF*/ - - // Properties -/*MGEN:Class.ConfigDeclarations*/ - // Statistics -/*MGEN:Class.InstDeclarations*/ -/*MGEN:IF(Class.ExistPerThreadStats)*/ - // Per-Thread Statistics - struct PerThreadStats { -/*MGEN:Class.PerThreadDeclarations*/ - }; - - struct PerThreadStats** perThreadStatsArray; - - inline struct PerThreadStats* getThreadStats() { - int idx = getThreadIndex(); - struct PerThreadStats* threadStats = perThreadStatsArray[idx]; - if (threadStats == 0) { - threadStats = new(PerThreadStats); - perThreadStatsArray[idx] = threadStats; -/*MGEN:Class.InitializePerThreadElements*/ - } - return threadStats; - } - - void aggregatePerThreadStats(struct PerThreadStats*); -/*MGEN:ENDIF*/ - // Private Methods - static void writeSchema (::qpid::framing::Buffer& buf); - void writeProperties (::qpid::framing::Buffer& buf); - void writeStatistics (::qpid::framing::Buffer& buf, - bool skipHeaders = false); - void doMethod (std::string& methodName, - ::qpid::framing::Buffer& inBuf, - ::qpid::framing::Buffer& outBuf); - writeSchemaCall_t getWriteSchemaCall(void) { return writeSchema; } -/*MGEN:IF(Class.NoStatistics)*/ - // Stub for getInstChanged. There are no statistics in this class. - bool getInstChanged (void) { return false; } -/*MGEN:ENDIF*/ - public: - - /*MGEN:Class.NameCap*/ (::qpid::management::ManagementAgent* agent, - ::qpid::management::Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); - ~/*MGEN:Class.NameCap*/ (void); - - /*MGEN:Class.SetGeneralReferenceDeclaration*/ - - static void registerSelf (::qpid::management::ManagementAgent* agent); - std::string& getPackageName (void) const { return packageName; } - std::string& getClassName (void) const { return className; } - uint8_t* getMd5Sum (void) const { return md5Sum; } - - // Method IDs -/*MGEN:Class.MethodIdDeclarations*/ - // Accessor Methods -/*MGEN:Class.AccessorMethods*/ -}; - -}/*MGEN:Class.CloseNamespaces*/ - -#endif /*!_MANAGEMENT_/*MGEN:Class.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmf/templates/Event.cpp b/qpid/cpp/managementgen/qmf/templates/Event.cpp deleted file mode 100644 index cdb40c6d79..0000000000 --- a/qpid/cpp/managementgen/qmf/templates/Event.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/*MGEN:commentPrefix=//*/ -// -// 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. -// - -/*MGEN:Root.Disclaimer*/ - -#include "qpid/log/Statement.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/management/Manageable.h" -#include "qpid/agent/ManagementAgent.h" -#include "Event/*MGEN:Event.NameCap*/.h" - -using namespace qmf::/*MGEN:Event.Namespace*/; -using namespace qpid::framing; -using qpid::management::ManagementAgent; -using qpid::management::Manageable; -using qpid::management::ManagementObject; -using qpid::management::Args; -using std::string; - -string Event/*MGEN:Event.NameCap*/::packageName = string ("/*MGEN:Event.NamePackageLower*/"); -string Event/*MGEN:Event.NameCap*/::eventName = string ("/*MGEN:Event.Name*/"); -uint8_t Event/*MGEN:Event.NameCap*/::md5Sum[16] = - {/*MGEN:Event.SchemaMD5*/}; - -Event/*MGEN:Event.NameCap*/::Event/*MGEN:Event.NameCap*/ (/*MGEN:Event.ConstructorArgs*/) : - /*MGEN:Event.ConstructorInits*/ -{} - -namespace { - const string NAME("name"); - const string TYPE("type"); - const string DESC("desc"); - const string ARGCOUNT("argCount"); - const string ARGS("args"); -} - -void Event/*MGEN:Event.NameCap*/::registerSelf(ManagementAgent* agent) -{ - agent->registerEvent(packageName, eventName, md5Sum, writeSchema); -} - -void Event/*MGEN:Event.NameCap*/::writeSchema (Buffer& buf) -{ - FieldTable ft; - - // Schema class header: - buf.putOctet (CLASS_KIND_EVENT); - buf.putShortString (packageName); // Package Name - buf.putShortString (eventName); // Event Name - buf.putBin128 (md5Sum); // Schema Hash - buf.putShort (/*MGEN:Event.ArgCount*/); // Argument Count - - // Arguments -/*MGEN:Event.ArgSchema*/ -} - -void Event/*MGEN:Event.NameCap*/::encode(::qpid::framing::Buffer& buf) const -{ -/*MGEN:Event.ArgEncodes*/ -} diff --git a/qpid/cpp/managementgen/qmf/templates/Event.h b/qpid/cpp/managementgen/qmf/templates/Event.h deleted file mode 100644 index b5c2a211d1..0000000000 --- a/qpid/cpp/managementgen/qmf/templates/Event.h +++ /dev/null @@ -1,59 +0,0 @@ -/*MGEN:commentPrefix=//*/ -#ifndef _MANAGEMENT_/*MGEN:Event.NameUpper*/_ -#define _MANAGEMENT_/*MGEN:Event.NameUpper*/_ - -// -// 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. -// - -/*MGEN:Root.Disclaimer*/ - -#include "qpid/management/ManagementEvent.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/framing/Uuid.h" - -namespace qmf { -/*MGEN:Event.OpenNamespaces*/ - -class Event/*MGEN:Event.NameCap*/ : public ::qpid::management::ManagementEvent -{ - private: - static void writeSchema (::qpid::framing::Buffer& buf); - static std::string packageName; - static std::string eventName; - static uint8_t md5Sum[16]; - -/*MGEN:Event.ArgDeclarations*/ - - public: - writeSchemaCall_t getWriteSchemaCall(void) { return writeSchema; } - - Event/*MGEN:Event.NameCap*/(/*MGEN:Event.ConstructorArgs*/); - ~Event/*MGEN:Event.NameCap*/() {}; - - static void registerSelf(::qpid::management::ManagementAgent* agent); - std::string& getPackageName() const { return packageName; } - std::string& getEventName() const { return eventName; } - uint8_t* getMd5Sum() const { return md5Sum; } - uint8_t getSeverity() const { return /*MGEN:Event.Severity*/; } - void encode(::qpid::framing::Buffer& buffer) const; -}; - -}/*MGEN:Event.CloseNamespaces*/ - -#endif /*!_MANAGEMENT_/*MGEN:Event.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmf/templates/Makefile.mk b/qpid/cpp/managementgen/qmf/templates/Makefile.mk deleted file mode 100644 index 2b32c7c0f2..0000000000 --- a/qpid/cpp/managementgen/qmf/templates/Makefile.mk +++ /dev/null @@ -1,40 +0,0 @@ -# -# 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. -# -/*MGEN:commentPrefix=#*/ -/*MGEN:Root.Disclaimer*/ -/*MGEN:IF(Makefile.QpidBroker)*/ -/*MGEN:mgenDir=$(mgen_dir)*/ -/*MGEN:specDir=$(top_srcdir)/../specs*/ - -mgen_generator=/*MGEN:Makefile.GenSources*/ - -mgen_broker_cpp=/*MGEN:Makefile.GenCppFiles*/ - -# Header file install rules. -/*MGEN:Makefile.HeaderInstalls*/ -if GENERATE -$(srcdir)/managementgen.mk: $(mgen_generator) - $(mgen_cmd) - -$(mgen_generator): -endif -/*MGEN:ENDIF*/ - -qmfgen_sources=/*MGEN:Makefile.GeneratedFiles*/ - diff --git a/qpid/cpp/managementgen/qmf/templates/Package.cpp b/qpid/cpp/managementgen/qmf/templates/Package.cpp deleted file mode 100644 index f6bd7f4654..0000000000 --- a/qpid/cpp/managementgen/qmf/templates/Package.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/*MGEN:commentPrefix=//*/ -// -// 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. -// - -/*MGEN:Root.Disclaimer*/ - -#include "Package.h" -/*MGEN:Schema.ClassIncludes*/ - -using namespace qmf::/*MGEN:Schema.Namespace*/; - -Package::Package (::qpid::management::ManagementAgent* agent) -{ -/*MGEN:Schema.ClassRegisters*/ -} - diff --git a/qpid/cpp/managementgen/qmf/templates/Package.h b/qpid/cpp/managementgen/qmf/templates/Package.h deleted file mode 100644 index 0ad7060b9e..0000000000 --- a/qpid/cpp/managementgen/qmf/templates/Package.h +++ /dev/null @@ -1,41 +0,0 @@ -/*MGEN:commentPrefix=//*/ -#ifndef _MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ -#define _MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ - -// -// 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. -// - -/*MGEN:Root.Disclaimer*/ - -#include "qpid/agent/ManagementAgent.h" - -namespace qmf { -/*MGEN:Class.OpenNamespaces*/ - -class Package -{ - public: - Package (::qpid::management::ManagementAgent* agent); - ~Package () {} -}; - -}/*MGEN:Class.CloseNamespaces*/ - - -#endif /*!_MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmfgen/__init__.py b/qpid/cpp/managementgen/qmfgen/__init__.py new file mode 100644 index 0000000000..caef6cc58b --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/__init__.py @@ -0,0 +1,19 @@ +# +# 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. +# + diff --git a/qpid/cpp/managementgen/qmfgen/generate.py b/qpid/cpp/managementgen/qmfgen/generate.py new file mode 100755 index 0000000000..762af972e7 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/generate.py @@ -0,0 +1,369 @@ +# +# 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: + """ + 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), + checking conditions (testCondition), and expanding tags (substHandler). + """ + def __init__ (self, filename, handler): + self.filename = filename + self.handler = handler + self.handler.initExpansion () + self.writing = True + + def expandLine (self, line, stream, object): + cursor = 0 + while 1: + sub = line.find ("/*MGEN:", cursor) + if sub == -1: + if self.writing: + stream.write (line[cursor:len (line)]) + return + + subend = line.find("*/", sub) + if self.writing: + stream.write (line[cursor:sub]) + cursor = subend + 2 + + tag = line[sub:subend] + + if tag[7:10] == "IF(": + close = tag.find(")") + if close == -1: + raise ValueError ("Missing ')' on condition") + cond = tag[10:close] + dotPos = cond.find (".") + if dotPos == -1: + raise ValueError ("Invalid condition tag: %s" % cond) + tagObject = cond[0:dotPos] + tagName = cond[dotPos + 1 : len(cond)] + if not self.handler.testCondition(object, tagObject, tagName): + self.writing = False + + elif tag[7:12] == "ENDIF": + self.writing = True + + else: + 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)] + if self.writing: + self.handler.substHandler (object, stream, tagObject, tagName) + else: + tagKey = tag[7:equalPos] + tagVal = tag[equalPos + 1:len (tag)] + if self.writing: + 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, packagelist): + self.filelists = filelists + self.templateFiles = templateFiles + self.packagelist = packagelist + + def genGenSources (self, stream, variables): + mdir = variables["mgenDir"] + sdir = variables["specDir"] + stream.write (mdir + "/qmf-gen \\\n") + stream.write (" " + mdir + "/qmfgen/generate.py \\\n") + stream.write (" " + mdir + "/qmfgen/schema.py \\\n") + stream.write (" " + mdir + "/qmfgen/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 + "/qmfgen/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) + + def genGeneratedFiles(self, stream, variables): + first = True + extensions = ("h", "cpp") + for ext in extensions: + for file in self.filelists[ext]: + if first: + first = False + else: + stream.write(" \\\n ") + if "genprefix" in variables: + prefix = variables["genprefix"] + if prefix != "": + stream.write(prefix + "/") + stream.write(file) + + def genHeaderInstalls (self, stream, variables): + for package in self.packagelist: + name = "_".join(package.split("/")) + stream.write(name + "dir = $(includedir)/qmf/" + package + "\n") + stream.write("dist_" + name + "_HEADERS = ") + first = True + for file in self.filelists["h"]: + if file.find("gen/qmf/" + package) == 0: + if first: + first = False + else: + stream.write (" \\\n ") + stream.write(file) + stream.write("\n\n") + + def testQpidBroker(self, variables): + if "qpidbroker" in variables: + return variables["qpidbroker"] + return False + + +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: + mode = os.stat (path)[ST_MODE] + except OSError, (err,text): + if err == ENOENT or err == ESRCH: + 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) + if pair[0] != '': + 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.packagePath = self.dest + self.filelists = {} + self.filelists["h"] = [] + self.filelists["cpp"] = [] + self.filelists["mk"] = [] + self.packagelist = [] + self.templateFiles = [] + self.variables = {} + + def setPackage (self, packageName): + path = "/".join(packageName.split(".")) + self.packagelist.append(path) + self.packagePath = self.normalize(self.dest + path) + + 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 (".") + 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.packagePath + "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 targetPackageFile (self, schema, templateFile): + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + extension = templateFile[dot:len (templateFile)] + path = self.packagePath + "Package" + extension + return path + + 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.packagePath + _class.getNameCap () + extension + return path + + def targetEventFile (self, event, templateFile): + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + extension = templateFile[dot:len (templateFile)] + path = self.packagePath + "Event" + event.getNameCap () + 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.packagePath + "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, self.variables)" + eval (call) + + def testCondition (self, object, tagObject, tag): + if tagObject == "Root": + obj = "self" + else: + obj = "object" # MUST be the same as the 2nd formal parameter + + call = obj + ".test" + tag + "(self.variables)" + return eval (call) + + 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) + self.templateFiles.append (templateFile) + for _class in classes: + target = self.targetClassFile (_class, templateFile) + stream = template.expand (_class) + self.writeIfChanged (stream, target, force) + + def makeEventFiles (self, templateFile, schema, force=False): + """ Generate an expanded template per schema event """ + events = schema.getEvents() + template = Template (self.input + templateFile, self) + self.templateFiles.append (templateFile) + for event in events: + target = self.targetEventFile(event, templateFile) + stream = template.expand(event) + self.writeIfChanged(stream, target, force) + + def makeMethodFiles (self, templateFile, schema, force=False): + """ Generate an expanded template per method-with-arguments """ + classes = schema.getClasses () + template = Template (self.input + templateFile, self) + 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, force) + + def makePackageFile (self, templateFile, schema, force=False): + """ Generate a package-specific file """ + template = Template (self.input + templateFile, self) + self.templateFiles.append (templateFile) + target = self.targetPackageFile (schema, templateFile) + stream = template.expand (schema) + self.writeIfChanged (stream, target, force) + + def makeSingleFile (self, templateFile, target, force=False, vars=None): + """ Generate a single expanded template """ + makefile = Makefile (self.filelists, self.templateFiles, self.packagelist) + template = Template (self.input + templateFile, self) + if vars: + for arg in vars: + self.setVariable(arg, vars[arg]) + self.templateFiles.append (templateFile) + stream = template.expand (makefile) + self.writeIfChanged (stream, target, force) + + def getModulePath(): + return __file__ + + getModulePath = staticmethod(getModulePath) diff --git a/qpid/cpp/managementgen/qmfgen/management-types.xml b/qpid/cpp/managementgen/qmfgen/management-types.xml new file mode 100644 index 0000000000..626880afb3 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/management-types.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py new file mode 100755 index 0000000000..692a474992 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -0,0 +1,1339 @@ +# +# 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 +import md5 + +class Hash: + """ Manage the hash of an XML sub-tree """ + def __init__(self, node): + self.md5Sum = md5.new() + self._compute(node) + + def addSubHash(self, hash): + """ Use this method to add the hash of a dependend-on XML fragment that is not in the sub-tree """ + self.md5Sum.update(hash.getDigest()) + + def getDigest(self): + return self.md5Sum.digest() + + def _compute(self, node): + attrs = node.attributes + self.md5Sum.update(node.nodeName) + + for idx in range(attrs.length): + self.md5Sum.update(attrs.item(idx).nodeName) + self.md5Sum.update(attrs.item(idx).nodeValue) + + for child in node.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + self._compute(child) + + +#===================================================================================== +# +#===================================================================================== +class SchemaType: + def __init__ (self, node): + self.name = None + self.base = None + self.cpp = None + self.encode = None + self.decode = None + self.style = "normal" + self.accessor = None + self.init = "0" + self.perThread = False + self.byRef = False + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'base': + self.base = val + + elif key == 'cpp': + self.cpp = val + + elif key == 'encode': + self.encode = val + + elif key == 'decode': + self.decode = val + + elif key == 'style': + self.style = val + + elif key == 'accessor': + self.accessor = val + + elif key == 'init': + self.init = val + + elif key == 'perThread': + if val != 'y': + raise ValueError ("Expected 'y' in perThread attribute") + self.perThread = True + + elif key == 'byRef': + if val != 'y': + raise ValueError ("Expected 'y' in byRef attribute") + self.byRef = True + + else: + raise ValueError ("Unknown attribute in type '%s'" % key) + + if self.name == None or self.base == None or self.cpp == None or \ + self.encode == None or self.decode == None: + raise ValueError ("Missing required attribute(s) in type") + + if self.byRef: + self.asArg = "const " + self.cpp + "&" + else: + self.asArg = self.cpp + + def getName (self): + return self.name + + def genAccessor (self, stream, varName, changeFlag = None, optional = False): + if self.perThread: + prefix = "getThreadStats()->" + if self.style == "wm": + raise ValueError ("'wm' style types can't be per-thread") + else: + prefix = "" + if self.accessor == "direct": + stream.write (" inline void set_" + varName + " (" + self.asArg + " val) {\n"); + if not self.perThread: + stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") + if self.style != "mma": + stream.write (" " + prefix + varName + " = val;\n") + if optional: + stream.write (" presenceMask[presenceByte_%s] |= presenceMask_%s;\n" % (varName, varName)) + if self.style == "wm": + stream.write (" if (" + varName + "Low > val)\n") + stream.write (" " + varName + "Low = val;\n") + stream.write (" if (" + varName + "High < val)\n") + stream.write (" " + varName + "High = val;\n") + if self.style == "mma": + stream.write (" " + prefix + varName + "Count++;\n") + stream.write (" " + prefix + varName + "Total += val;\n") + stream.write (" if (" + prefix + varName + "Min > val)\n") + stream.write (" " + prefix + varName + "Min = val;\n") + stream.write (" if (" + prefix + varName + "Max < val)\n") + stream.write (" " + prefix + varName + "Max = val;\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n") + if self.style != "mma": + stream.write (" inline " + self.asArg + " get_" + varName + "() {\n"); + if not self.perThread: + stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" return " + prefix + varName + ";\n") + stream.write (" }\n") + if optional: + stream.write (" inline void clr_" + varName + "() {\n") + stream.write (" presenceMask[presenceByte_%s] &= ~presenceMask_%s;\n" % (varName, varName)) + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n") + stream.write (" inline bool isSet_" + varName + "() {\n") + stream.write (" return (presenceMask[presenceByte_%s] & presenceMask_%s) != 0;\n" % (varName, varName)) + stream.write (" }\n") + elif self.accessor == "counter": + stream.write (" inline void inc_" + varName + " (" + self.asArg + " by = 1) {\n"); + if not self.perThread: + stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" " + prefix + varName + " += by;\n") + if self.style == "wm": + stream.write (" if (" + varName + "High < " + varName + ")\n") + stream.write (" " + varName + "High = " + varName + ";\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); + stream.write (" inline void dec_" + varName + " (" + self.asArg + " by = 1) {\n"); + if not self.perThread: + stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" " + prefix + varName + " -= by;\n") + if self.style == "wm": + stream.write (" if (" + varName + "Low > " + varName + ")\n") + stream.write (" " + varName + "Low = " + varName + ";\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); + + def genHiLoStatResets (self, stream, varName): + if self.style == "wm": + stream.write (" " + varName + "High = " + varName + ";\n") + stream.write (" " + varName + "Low = " + varName + ";\n") + if self.style == "mma": + stream.write (" " + varName + "Count = 0;\n") + stream.write (" " + varName + "Total = 0;\n") + stream.write (" " + varName + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") + stream.write (" " + varName + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") + + def genPerThreadHiLoStatResets (self, stream, varName, cpptype): + if self.style == "mma": + stream.write (" threadStats->" + varName + "Count = 0;\n") + stream.write (" threadStats->" + varName + "Total = 0;\n") + stream.write (" threadStats->" + varName + "Min = std::numeric_limits<" + cpptype + ">::max();\n") + stream.write (" threadStats->" + varName + "Max = std::numeric_limits<" + cpptype + ">::min();\n") + + def genWrite (self, stream, varName, indent=" "): + if self.style != "mma": + stream.write (indent + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") + if self.style == "wm": + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "High") + ";\n") + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Low") + ";\n") + if self.style == "mma": + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Count") + ";\n") + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Count ? " + varName + "Min : 0") + ";\n") + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Max") + ";\n") + stream.write (indent + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Count ? " + varName + "Total / " + + varName + "Count : 0") + ";\n") + + + def getReadCode (self, varName, bufName): + result = self.decode.replace ("@", bufName).replace ("#", varName) + return result + + def getWriteCode (self, varName, bufName): + result = self.encode.replace ("@", bufName).replace ("#", varName) + return result + +#===================================================================================== +# +#===================================================================================== +class TypeSpec: + def __init__ (self, file): + self.types = {} + dom = parse (file) + document = dom.documentElement + if document.tagName != 'schema-types': + raise ValueError ("Expected 'schema-types' in type file") + + for child in document.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'type': + stype = SchemaType (child) + self.types[stype.getName ()] = stype + else: + raise ValueError ("Unknown type tag '%s'" % child.nodeName) + + def getType (self, name): + return self.types[name] + + +#===================================================================================== +# +#===================================================================================== +class Type: + def __init__ (self, name, typespec): + self.type = typespec.getType (name) + +#===================================================================================== +# +#===================================================================================== +class SchemaProperty: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.ref = None + self.access = "RO" + self.isIndex = 0 + self.isParentRef = 0 + self.isGeneralRef = 0 + self.isOptional = 0 + self.unit = None + self.min = None + self.max = None + self.maxLen = None + self.desc = None + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = makeValidCppSymbol(val) + + elif key == 'type': + self.type = Type (val, typespec) + if self.type.type.accessor != 'direct': + raise ValueError ("Class properties must have a type with a direct accessor") + + elif key == 'references': + self.ref = val + + elif key == 'access': + self.access = val + + elif key == 'index': + if val != 'y': + raise ValueError ("Expected 'y' in index attribute") + self.isIndex = 1 + + elif key == 'parentRef': + if val != 'y': + raise ValueError ("Expected 'y' in parentRef attribute") + self.isParentRef = 1 + + elif key == 'isGeneralReference': + if val != 'y': + raise ValueError ("Expected 'y' in isGeneralReference attribute") + self.isGeneralRef = 1 + + elif key == 'optional': + if val != 'y': + raise ValueError ("Expected 'y' in optional attribute") + self.isOptional = 1 + + elif key == 'unit': + self.unit = val + + elif key == 'min': + self.min = val + + elif key == 'max': + self.max = val + + elif key == 'maxlen': + self.maxLen = val + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in property '%s'" % key) + + if self.access == "RC" and self.isOptional == 1: + raise ValueError ("Properties with ReadCreate access must not be optional (%s)" % self.name) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in property") + if self.type == None: + raise ValueError ("Missing 'type' attribute in property") + + def getName (self): + return self.name + + def isConstructorArg (self): + if self.access == "RC" and self.isParentRef == 0: + return 1 + return 0 + + def genDeclaration (self, stream, prefix=" "): + stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") + + def genFormalParam (self, stream, variables): + stream.write (self.type.type.asArg + " _" + self.name) + + def genAccessor (self, stream): + self.type.type.genAccessor (stream, self.name, "configChanged", self.isOptional == 1) + + def genInitialize (self, stream, prefix="", indent=" "): + val = self.type.type.init + stream.write (indent + prefix + self.name + " = " + val + ";\n") + + def genSchema (self, stream): + stream.write (" ft = FieldTable ();\n") + stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") + stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + stream.write (" ft.setInt (ACCESS, ACCESS_" + self.access + ");\n") + stream.write (" ft.setInt (IS_INDEX, " + str (self.isIndex) + ");\n") + stream.write (" ft.setInt (IS_OPTIONAL, " + str (self.isOptional) + ");\n") + if self.unit != None: + stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + if self.min != None: + stream.write (" ft.setInt (MIN, " + self.min + ");\n") + if self.max != None: + stream.write (" ft.setInt (MAX, " + self.max + ");\n") + if self.maxLen != None: + stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") + if self.desc != None: + stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + + def genWrite (self, stream): + indent = " " + if self.isOptional: + stream.write(" if (presenceMask[presenceByte_%s] & presenceMask_%s) {\n" % (self.name, self.name)) + indent = " " + self.type.type.genWrite (stream, self.name, indent) + if self.isOptional: + stream.write(" }\n") + + +#===================================================================================== +# +#===================================================================================== +class SchemaStatistic: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.unit = None + self.desc = None + self.assign = None + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = makeValidCppSymbol(val) + + elif key == 'type': + self.type = Type (val, typespec) + + elif key == 'unit': + self.unit = val + + elif key == 'desc': + self.desc = val + + elif key == 'assign': + self.assign = val + + else: + raise ValueError ("Unknown attribute in statistic '%s'" % key) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in statistic") + if self.type == None: + raise ValueError ("Missing 'type' attribute in statistic") + + def getName (self): + return self.name + + def genDeclaration (self, stream, prefix=" "): + if self.type.type.style != "mma": + stream.write (prefix + self.type.type.cpp + " " + self.name + ";\n") + if self.type.type.style == 'wm': + stream.write (prefix + self.type.type.cpp + " " + self.name + "High;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "Low;\n") + if self.type.type.style == "mma": + stream.write (prefix + self.type.type.cpp + " " + self.name + "Count;\n") + stream.write (prefix + "uint64_t " + self.name + "Total;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "Min;\n") + stream.write (prefix + self.type.type.cpp + " " + self.name + "Max;\n") + + def genAccessor (self, stream): + self.type.type.genAccessor (stream, self.name, "instChanged") + + def genHiLoStatResets (self, stream): + self.type.type.genHiLoStatResets (stream, self.name) + + def genPerThreadHiLoStatResets (self, stream): + self.type.type.genPerThreadHiLoStatResets (stream, self.name, self.type.type.cpp) + + def genSchemaText (self, stream, name, desc): + stream.write (" ft = FieldTable ();\n") + stream.write (" ft.setString (NAME, \"" + name + "\");\n") + stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + if self.unit != None: + stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + if desc != None: + stream.write (" ft.setString (DESC, \"" + desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + + def genSchema (self, stream): + if self.type.type.style != "mma": + self.genSchemaText (stream, self.name, self.desc) + if self.type.type.style == "wm": + descHigh = self.desc + descLow = self.desc + if self.desc != None: + descHigh = descHigh + " (High)" + descLow = descLow + " (Low)" + self.genSchemaText (stream, self.name + "High", descHigh) + self.genSchemaText (stream, self.name + "Low", descLow) + if self.type.type.style == "mma": + descCount = self.desc + descMin = self.desc + descMax = self.desc + descAverage = self.desc + if self.desc != None: + descCount = descCount + " (Samples)" + descMin = descMin + " (Min)" + descMax = descMax + " (Max)" + descAverage = descAverage + " (Average)" + self.genSchemaText (stream, self.name + "Samples", descCount) + self.genSchemaText (stream, self.name + "Min", descMin) + self.genSchemaText (stream, self.name + "Max", descMax) + self.genSchemaText (stream, self.name + "Average", descAverage) + + def genAssign (self, stream): + if self.assign != None: + if self.type.type.perThread: + prefix = " threadStats->" + else: + prefix = "" + stream.write (" " + prefix + self.name + " = (" + self.type.type.cpp + + ") (" + self.assign + ");\n") + + def genWrite (self, stream): + if self.type.type.perThread: + self.type.type.genWrite (stream, "totals." + self.name) + else: + self.type.type.genWrite (stream, self.name) + + def genInitialize (self, stream, prefix="", indent=" "): + val = self.type.type.init + if self.type.type.style != "mma": + stream.write (indent + prefix + self.name + " = " + val + ";\n") + if self.type.type.style == "wm": + stream.write (indent + prefix + self.name + "High = " + val + ";\n") + stream.write (indent + prefix + self.name + "Low = " + val + ";\n") + if self.type.type.style == "mma": + stream.write (indent + prefix + self.name + "Count = 0;\n") + stream.write (indent + prefix + self.name + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") + stream.write (indent + prefix + self.name + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") + stream.write (indent + prefix + self.name + "Total = 0;\n") + + def genInitializeTotalPerThreadStats (self, stream): + if self.type.type.style == "mma": + stream.write (" totals->" + self.name + "Count = 0;\n") + stream.write (" totals->" + self.name + "Min = std::numeric_limits<" + self.type.type.cpp + ">::max();\n") + stream.write (" totals->" + self.name + "Max = std::numeric_limits<" + self.type.type.cpp + ">::min();\n") + stream.write (" totals->" + self.name + "Total = 0;\n") + else: + stream.write (" totals->" + self.name + " = 0;\n") + + def genAggregatePerThreadStats (self, stream): + if self.type.type.style == "mma": + stream.write (" totals->%sCount += threadStats->%sCount;\n" % (self.name, self.name)) + stream.write (" if (totals->%sMin > threadStats->%sMin)\n" % (self.name, self.name)) + stream.write (" totals->%sMin = threadStats->%sMin;\n" % (self.name, self.name)) + stream.write (" if (totals->%sMax < threadStats->%sMax)\n" % (self.name, self.name)) + stream.write (" totals->%sMax = threadStats->%sMax;\n" % (self.name, self.name)) + stream.write (" totals->%sTotal += threadStats->%sTotal;\n" % (self.name, self.name)) + else: + stream.write (" totals->%s += threadStats->%s;\n" % (self.name, self.name)) + +#===================================================================================== +# +#===================================================================================== +class SchemaArg: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.unit = None + self.dir = "I" + self.min = None + self.max = None + self.maxLen = None + self.desc = None + self.default = None + self.hash = Hash(node) + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = makeValidCppSymbol(val) + + elif key == 'type': + self.type = Type (val, typespec) + + elif key == 'unit': + self.unit = val + + elif key == 'dir': + self.dir = val.upper () + + elif key == 'min': + self.min = val + + elif key == 'max': + self.max = val + + elif key == 'maxlen': + self.maxLen = val + + elif key == 'desc': + self.desc = val + + elif key == 'default': + self.default = val + + else: + raise ValueError ("Unknown attribute in arg '%s'" % key) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in arg") + if self.type == None: + raise ValueError ("Missing 'type' attribute in arg") + + def getName (self): + return self.name + + def getDir (self): + return self.dir + + def genSchema (self, stream, event=False): + stream.write (" ft = FieldTable ();\n") + stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") + stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + if (not event): + stream.write (" ft.setString (DIR, \"" + self.dir + "\");\n") + if self.unit != None: + stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + if not event: + if self.min != None: + stream.write (" ft.setInt (MIN, " + self.min + ");\n") + if self.max != None: + stream.write (" ft.setInt (MAX, " + self.max + ");\n") + if self.maxLen != None: + stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") + if self.default != None: + stream.write (" ft.setString (DEFAULT, \"" + self.default + "\");\n") + if self.desc != None: + stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + + def genFormalParam (self, stream, variables): + stream.write ("%s _%s" % (self.type.type.asArg, self.name)) + +#===================================================================================== +# +#===================================================================================== +class SchemaMethod: + def __init__ (self, parent, node, typespec): + self.parent = parent + self.name = None + self.desc = None + self.args = [] + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = makeValidCppSymbol(val) + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in method '%s'" % key) + + for child in node.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'arg': + arg = SchemaArg (child, typespec) + self.args.append (arg) + else: + raise ValueError ("Unknown method tag '%s'" % child.nodeName) + + def getName (self): + return self.name + + def getFullName (self): + return capitalize(self.parent.getName()) + self.name[0:1].upper() +\ + self.name[1:] + + def getArgCount (self): + return len (self.args) + + #=================================================================================== + # Code Generation Functions. The names of these functions (minus the leading "gen") + # match the substitution keywords in the template files. + #=================================================================================== + def genNameUpper (self, stream, variables): + stream.write (self.getFullName ().upper ()) + + def genNameCamel (self, stream, variables): + stream.write (self.getFullName ()) + + def genOpenNamespaces (self, stream, variables): + self.parent.genOpenNamespaces(stream, variables) + + def genCloseNamespaces (self, stream, variables): + self.parent.genCloseNamespaces(stream, variables) + + 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 genNamePackageLower (self, stream, variables): + self.parent.genNamePackageLower(stream, variables) + + 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") + if self.desc != None: + stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + for arg in self.args: + arg.genSchema (stream) + +#===================================================================================== +# +#===================================================================================== +class SchemaEvent: + def __init__ (self, package, node, typespec, argset): + self.packageName = package + self.name = None + self.desc = None + self.sevText = "inform" + self.args = [] + self.hash = Hash(node) + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'desc': + self.desc = val + + elif key == 'sev': + self.sevText = val + + elif key == 'args': + list = val.replace(" ", "").split(",") + for item in list: + if item not in argset.args: + raise Exception("undefined argument '%s' in event" % item) + self.args.append(argset.args[item]) + self.hash.addSubHash(argset.args[item].hash) + + else: + raise ValueError ("Unknown attribute in event '%s'" % key) + + if self.sevText == "emerg" : self.sev = 0 + elif self.sevText == "alert" : self.sev = 1 + elif self.sevText == "crit" : self.sev = 2 + elif self.sevText == "error" : self.sev = 3 + elif self.sevText == "warn" : self.sev = 4 + elif self.sevText == "notice" : self.sev = 5 + elif self.sevText == "inform" : self.sev = 6 + elif self.sevText == "debug" : self.sev = 7 + else: + raise ValueError("Unknown severity '%s' in event '%s'" % (self.sevText, self.name)) + + def getName (self): + return self.name + + def getNameCap(self): + return capitalize(self.name) + + def getFullName (self): + return capitalize(self.package + capitalize(self.name)) + + def getArgCount (self): + return len (self.args) + + def genArgCount (self, stream, variables): + stream.write("%d" % len(self.args)) + + def genArgDeclarations(self, stream, variables): + for arg in self.args: + if arg.type.type.byRef: + ref = "&" + else: + ref = "" + stream.write(" const %s%s %s;\n" % (arg.type.type.cpp, ref, arg.name)) + + def genCloseNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("}") + + def genConstructorArgs(self, stream, variables): + pre = "" + for arg in self.args: + if arg.type.type.byRef: + ref = "&" + else: + ref = "" + stream.write("%sconst %s%s _%s" % (pre, arg.type.type.cpp, ref, arg.name)) + pre = ",\n " + + def genConstructorInits(self, stream, variables): + pre = "" + for arg in self.args: + stream.write("%s%s(_%s)" % (pre, arg.name, arg.name)) + pre = ",\n " + + def genName(self, stream, variables): + stream.write(self.name) + + def genNameCap(self, stream, variables): + stream.write(capitalize(self.name)) + + def genNamespace (self, stream, variables): + stream.write("::".join(self.packageName.split("."))) + + def genNameLower(self, stream, variables): + stream.write(self.name.lower()) + + def genNameUpper(self, stream, variables): + stream.write(self.name.upper()) + + def genNamePackageLower(self, stream, variables): + stream.write(self.packageName.lower()) + + def genOpenNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("namespace %s {\n" % item) + + def genSeverity(self, stream, variables): + stream.write("%d" % self.sev) + + def genArgEncodes(self, stream, variables): + for arg in self.args: + stream.write(" " + arg.type.type.encode.replace("@", "buf").replace("#", arg.name) + ";\n") + + def genArgSchema(self, stream, variables): + for arg in self.args: + arg.genSchema(stream, True) + + def genSchemaMD5(self, stream, variables): + sum = self.hash.getDigest() + for idx in range (len (sum)): + if idx != 0: + stream.write (",") + stream.write (hex (ord (sum[idx]))) + + +class SchemaClass: + def __init__ (self, package, node, typespec, fragments, options): + self.packageName = package + self.properties = [] + self.statistics = [] + self.methods = [] + self.events = [] + self.options = options + self.hash = Hash(node) + + attrs = node.attributes + self.name = makeValidCppSymbol(attrs['name'].nodeValue) + + children = node.childNodes + for child in children: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'property': + sub = SchemaProperty (child, typespec) + self.properties.append (sub) + + elif child.nodeName == 'statistic': + sub = SchemaStatistic (child, typespec) + self.statistics.append (sub) + + elif child.nodeName == 'method': + sub = SchemaMethod (self, child, typespec) + self.methods.append (sub) + + elif child.nodeName == 'group': + self.expandFragment (child, fragments) + + else: + raise ValueError ("Unknown class tag '%s'" % child.nodeName) + + # Adjust the 'assign' attributes for each statistic + for stat in self.statistics: + if stat.assign != None and stat.type.type.perThread: + stat.assign = self.adjust (stat.assign, self.statistics) + + def adjust (self, text, statistics): + result = text + start = 0 + while True: + next = None + for stat in statistics: + pos = result.find (stat.name, start) + if pos != -1 and (next == None or pos < next[0]): + next = (pos, stat.name) + if next == None: + return result + pos = next[0] + result = result[0:pos] + "threadStats->" + result[pos:] + start = pos + 9 + len(next[1]) + + def expandFragment (self, node, fragments): + attrs = node.attributes + name = attrs['name'].nodeValue + for fragment in fragments: + if fragment.name == name: + self.hash.addSubHash(fragment.hash) + for config in fragment.properties: + self.properties.append (config) + for inst in fragment.statistics: + self.statistics.append (inst) + for method in fragment.methods: + self.methods.append (method) + for event in fragment.events: + self.events.append (event) + return + raise ValueError ("Undefined group '%s'" % name) + + def getName (self): + return self.name + + def getNameCap (self): + return capitalize(self.name) + + def getMethods (self): + return self.methods + + def getEvents (self): + return self.events + + def getPackageNameCap (self): + return capitalize(self.packageName) + + #=================================================================================== + # Code Generation Functions. The names of these functions (minus the leading "gen") + # match the substitution keywords in the template files. + #=================================================================================== + def testExistOptionals (self, variables): + for prop in self.properties: + if prop.isOptional == 1: + return True + return False + + def testExistPerThreadStats (self, variables): + for inst in self.statistics: + if inst.type.type.perThread: + return True + return False + + def testExistPerThreadAssign (self, variables): + for inst in self.statistics: + if inst.type.type.perThread and inst.assign != None: + return True + return False + + def testExistPerThreadResets (self, variables): + for inst in self.statistics: + if inst.type.type.perThread and inst.type.type.style == "mma": + return True + return False + + def testNoStatistics (self, variables): + return len (self.statistics) == 0 + + def genAccessorMethods (self, stream, variables): + for config in self.properties: + if config.access != "RC": + config.genAccessor (stream) + for inst in self.statistics: + if inst.assign == None: + inst.genAccessor (stream) + + def genCloseNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("}") + + def genConfigCount (self, stream, variables): + stream.write ("%d" % len (self.properties)) + + def genConfigDeclarations (self, stream, variables): + for element in self.properties: + element.genDeclaration (stream) + + def genConstructorArgs (self, stream, variables): + # Constructor args are config elements with read-create access + result = "" + for element in self.properties: + if element.isConstructorArg (): + stream.write (", ") + element.genFormalParam (stream, variables) + + def genConstructorInits (self, stream, variables): + for element in self.properties: + if element.isConstructorArg (): + stream.write ("," + element.getName () + "(_" + element.getName () + ")") + + def genDoMethodArgs (self, stream, variables): + methodCount = 0 + inArgCount = 0 + for method in self.methods: + methodCount = methodCount + 1 + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + inArgCount = inArgCount + 1 + + if methodCount == 0: + stream.write ("string&, Buffer&, Buffer& outBuf") + else: + if inArgCount == 0: + stream.write ("string& methodName, Buffer&, Buffer& outBuf") + else: + stream.write ("string& methodName, Buffer& inBuf, Buffer& outBuf") + + def genHiLoStatResets (self, stream, variables): + for inst in self.statistics: + if not inst.type.type.perThread: + inst.genHiLoStatResets (stream) + + def genPerThreadHiLoStatResets (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genPerThreadHiLoStatResets (stream) + + def genInitializeElements (self, stream, variables): + for prop in self.properties: + if not prop.isConstructorArg() and not prop.isParentRef: + prop.genInitialize(stream) + for inst in self.statistics: + if not inst.type.type.perThread: + inst.genInitialize (stream) + + def genInitializePerThreadElements (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genInitialize (stream, "threadStats->", " ") + + def genInitializeTotalPerThreadStats (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genInitializeTotalPerThreadStats (stream) + + def genAggregatePerThreadStats (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genAggregatePerThreadStats (stream) + + def genInstCount (self, stream, variables): + count = 0 + for inst in self.statistics: + count = count + 1 + if inst.type.type.style == "wm": + count = count + 2 + if inst.type.type.style == "mma": + count = count + 3 + stream.write ("%d" % count) + + def genInstDeclarations (self, stream, variables): + for element in self.statistics: + if not element.type.type.perThread: + element.genDeclaration (stream) + + def genPerThreadDeclarations (self, stream, variables): + for element in self.statistics: + if element.type.type.perThread: + element.genDeclaration (stream, " ") + + def genNamespace (self, stream, variables): + stream.write("::".join(self.packageName.split("."))) + + def genMethodArgIncludes (self, stream, variables): + for method in self.methods: + if method.getArgCount () > 0: + stream.write ("#include \"Args" + method.getFullName () + ".h\"\n") + + def genMethodCount (self, stream, variables): + stream.write ("%d" % len (self.methods)) + + def genMethodHandlers (self, stream, variables): + for method in self.methods: + stream.write ("\n if (methodName == \"" + method.getName () + "\") {\n") + if method.getArgCount () == 0: + stream.write (" ::qpid::management::ArgsNone ioArgs;\n") + else: + stream.write (" Args" + method.getFullName () + " ioArgs;\n") + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + stream.write (" " +\ + arg.type.type.getReadCode ("ioArgs." +\ + arg.dir.lower () + "_" +\ + arg.name, "inBuf") + ";\n") + + stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ + method.getName().upper() + ", ioArgs, text);\n") + stream.write (" outBuf.putLong (status);\n") + stream.write (" outBuf.putMediumString(::qpid::management::Manageable::StatusText (status, text));\n") + for arg in method.args: + if arg.getDir () == "O" or arg.getDir () == "IO": + stream.write (" " +\ + arg.type.type.getWriteCode ("ioArgs." +\ + arg.dir.lower () + "_" +\ + arg.name, "outBuf") + ";\n") + stream.write (" return;\n }\n") + + def genOpenNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("namespace %s {\n" % item) + + def genPresenceMaskBytes (self, stream, variables): + count = 0 + for prop in self.properties: + if prop.isOptional == 1: + count += 1 + if count == 0: + stream.write("0") + else: + stream.write (str(((count - 1) / 8) + 1)) + + def genPresenceMaskConstants (self, stream, variables): + count = 0 + for prop in self.properties: + if prop.isOptional == 1: + stream.write(" static const uint8_t presenceByte_%s = %d;\n" % (prop.name, count / 8)) + stream.write(" static const uint8_t presenceMask_%s = %d;\n" % (prop.name, 1 << (count % 8))) + count += 1 + + def genPropertySchema (self, stream, variables): + for prop in self.properties: + prop.genSchema (stream) + + def genSetGeneralReferenceDeclaration (self, stream, variables): + for prop in self.properties: + if prop.isGeneralRef: + stream.write ("void setReference(::qpid::management::ObjectId objectId) { " + prop.name + " = objectId; }\n") + + def genStatisticSchema (self, stream, variables): + for stat in self.statistics: + stat.genSchema (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, variables): + for method in self.methods: + method.genSchema (stream, variables) + + def genNameCap (self, stream, variables): + stream.write (capitalize(self.name)) + + def genNameLower (self, stream, variables): + stream.write (self.name.lower ()) + + def genNamePackageCap (self, stream, variables): + stream.write (self.getPackageNameCap ()) + + def genNamePackageLower (self, stream, variables): + stream.write (self.packageName.lower ()) + + def genNameUpper (self, stream, variables): + stream.write (self.name.upper ()) + + def genParentArg (self, stream, variables): + for config in self.properties: + if config.isParentRef == 1: + stream.write (", ::qpid::management::Manageable* _parent") + return + + def genParentRefAssignment (self, stream, variables): + for config in self.properties: + if config.isParentRef == 1: + stream.write (config.getName () + \ + " = _parent->GetManagementObject ()->getObjectId ();") + return + + def genSchemaMD5 (self, stream, variables): + sum = self.hash.getDigest() + for idx in range (len (sum)): + if idx != 0: + stream.write (",") + stream.write (hex (ord (sum[idx]))) + + def genAssign (self, stream, variables): + for inst in self.statistics: + if not inst.type.type.perThread: + inst.genAssign (stream) + + def genPerThreadAssign (self, stream, variables): + for inst in self.statistics: + if inst.type.type.perThread: + inst.genAssign (stream) + + def genWriteProperties (self, stream, variables): + for prop in self.properties: + prop.genWrite (stream) + + def genWriteStatistics (self, stream, variables): + for stat in self.statistics: + stat.genWrite (stream) + + +class SchemaEventArgs: + def __init__(self, package, node, typespec, fragments, options): + self.packageName = package + self.options = options + self.args = {} + + children = node.childNodes + for child in children: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'arg': + arg = SchemaArg(child, typespec) + self.args[arg.name] = arg + else: + raise Exception("Unknown tag '%s' in " % child.nodeName) + +class SchemaPackage: + def __init__ (self, typefile, schemafile, options): + + self.classes = [] + self.fragments = [] + self.typespec = TypeSpec (typefile) + self.eventArgSet = None + self.events = [] + + dom = parse (schemafile) + document = dom.documentElement + if document.tagName != 'schema': + raise ValueError ("Expected 'schema' node") + attrs = document.attributes + pname = attrs['package'].nodeValue + namelist = pname.split('.') + self.packageName = ".".join(namelist) + + children = document.childNodes + for child in children: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'class': + cls = SchemaClass (self.packageName, child, self.typespec, + self.fragments, options) + self.classes.append (cls) + + elif child.nodeName == 'group': + cls = SchemaClass (self.packageName, child, self.typespec, + self.fragments, options) + self.fragments.append (cls) + + elif child.nodeName == 'eventArguments': + if self.eventArgSet: + raise Exception("Only one may appear in a package") + self.eventArgSet = SchemaEventArgs(self.packageName, child, self.typespec, self.fragments, options) + + elif child.nodeName == 'event': + event = SchemaEvent(self.packageName, child, self.typespec, self.eventArgSet) + self.events.append(event) + + else: + raise ValueError ("Unknown schema tag '%s'" % child.nodeName) + + def getPackageName (self): + return self.packageName + + def getPackageNameCap (self): + return capitalize(self.packageName) + + def getPackageNameLower (self): + return self.packageName.lower() + + def getClasses (self): + return self.classes + + def getEvents(self): + return self.events + + def genCloseNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("}") + + def genNamespace (self, stream, variables): + stream.write("::".join(self.packageName.split("."))) + + def genOpenNamespaces (self, stream, variables): + for item in self.packageName.split("."): + stream.write ("namespace %s {\n" % item) + + def genPackageNameUpper (self, stream, variables): + up = "_".join(self.packageName.split(".")) + stream.write (up.upper()) + + def genNamePackageLower (self, stream, variables): + stream.write (self.packageName.lower ()) + + def genClassIncludes (self, stream, variables): + for _class in self.classes: + stream.write ("#include \"") + _class.genNameCap (stream, variables) + stream.write (".h\"\n") + for _event in self.events: + stream.write ("#include \"Event") + _event.genNameCap(stream, variables) + stream.write (".h\"\n") + + def genClassRegisters(self, stream, variables): + for _class in self.classes: + stream.write(" ") + _class.genNameCap(stream, variables) + stream.write("::registerSelf(agent);\n") + for _event in self.events: + stream.write(" Event") + _event.genNameCap(stream, variables) + stream.write("::registerSelf(agent);\n") + + +#===================================================================================== +# Utility Functions +#===================================================================================== + +# Create a valid C++ symbol from the input string so that it can be +# used in generated C++ source. For instance, change "qpid.mgmt" to +# "qpidMgmt". +# +# Input: Raw string (str) to process +# Output: String (str) suitable for use as a C++ symbol +# +# Limitations: Currently, only strips periods ('.') from strings, +# eventually should strip :'s and ,'s and ''s, oh my! +def makeValidCppSymbol(input): + output = str() + capitalize = False + + for char in input: + skip = False + + if char == ".": + capitalize = True + skip = True + + if not skip: + output += capitalize and char.upper() or char + + capitalize = False + + return output + +# Capitalize a string by /only/ forcing the first character to be +# uppercase. The rest of the string is left alone. This is different +# from str.capitalize(), which forces the first character to uppercase +# and the rest to lowercase. +# +# Input: A string (str) to capitalize +# Output: A string (str) with the first character as uppercase +def capitalize(input): + return input[0].upper() + input[1:] diff --git a/qpid/cpp/managementgen/qmfgen/templates/Args.h b/qpid/cpp/managementgen/qmfgen/templates/Args.h new file mode 100644 index 0000000000..074ccf9940 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Args.h @@ -0,0 +1,42 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _ARGS_/*MGEN:Method.NameUpper*/_ +#define _ARGS_/*MGEN:Method.NameUpper*/_ + +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/Args.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/framing/Uuid.h" +#include + +namespace qmf { +/*MGEN:Method.OpenNamespaces*/ + + class Args/*MGEN:Method.NameCamel*/ : public ::qpid::management::Args +{ + public: +/*MGEN:Method.Arguments*/ +}; + +}/*MGEN:Method.CloseNamespaces*/ + +#endif /*!_ARGS_/*MGEN:Method.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp new file mode 100644 index 0000000000..247e1090ff --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp @@ -0,0 +1,181 @@ +/*MGEN:commentPrefix=//*/ +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/log/Statement.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/management/Manageable.h" +#include "qpid/agent/ManagementAgent.h" +#include "/*MGEN:Class.NameCap*/.h" +/*MGEN:Class.MethodArgIncludes*/ + +using namespace qmf::/*MGEN:Class.Namespace*/; +using namespace qpid::framing; +using qpid::management::ManagementAgent; +using qpid::management::Manageable; +using qpid::management::ManagementObject; +using qpid::management::Args; +using std::string; + +string /*MGEN:Class.NameCap*/::packageName = string ("/*MGEN:Class.NamePackageLower*/"); +string /*MGEN:Class.NameCap*/::className = string ("/*MGEN:Class.NameLower*/"); +uint8_t /*MGEN:Class.NameCap*/::md5Sum[16] = + {/*MGEN:Class.SchemaMD5*/}; + +/*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (ManagementAgent* _agent, Manageable* _core/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/) : + ManagementObject(_agent, _core)/*MGEN:Class.ConstructorInits*/ +{ + /*MGEN:Class.ParentRefAssignment*/ +/*MGEN:Class.InitializeElements*/ +/*MGEN:IF(Class.ExistOptionals)*/ + // Optional properties start out not-present + for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) + presenceMask[idx] = 0; +/*MGEN:ENDIF*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + maxThreads = agent->getMaxThreads(); + perThreadStatsArray = new struct PerThreadStats*[maxThreads]; + for (int idx = 0; idx < maxThreads; idx++) + perThreadStatsArray[idx] = 0; +/*MGEN:ENDIF*/ +} + +/*MGEN:Class.NameCap*/::~/*MGEN:Class.NameCap*/ () +{ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + for (int idx = 0; idx < maxThreads; idx++) + if (perThreadStatsArray[idx] != 0) + delete perThreadStatsArray[idx]; + delete[] perThreadStatsArray; +/*MGEN:ENDIF*/ +} + +namespace { + const string NAME("name"); + const string TYPE("type"); + const string ACCESS("access"); + const string IS_INDEX("index"); + const string IS_OPTIONAL("optional"); + const string UNIT("unit"); + const string MIN("min"); + const string MAX("max"); + const string MAXLEN("maxlen"); + const string DESC("desc"); + const string ARGCOUNT("argCount"); + const string ARGS("args"); + const string DIR("dir"); + const string DEFAULT("default"); +} + +void /*MGEN:Class.NameCap*/::registerSelf(ManagementAgent* agent) +{ + agent->registerClass(packageName, className, md5Sum, writeSchema); +} + +void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) +{ + FieldTable ft; + + // Schema class header: + buf.putOctet (CLASS_KIND_TABLE); + buf.putShortString (packageName); // Package Name + buf.putShortString (className); // Class Name + buf.putBin128 (md5Sum); // Schema Hash + buf.putShort (/*MGEN:Class.ConfigCount*/); // Config Element Count + buf.putShort (/*MGEN:Class.InstCount*/); // Inst Element Count + buf.putShort (/*MGEN:Class.MethodCount*/); // Method Count + + // Properties +/*MGEN:Class.PropertySchema*/ + // Statistics +/*MGEN:Class.StatisticSchema*/ + // Methods +/*MGEN:Class.MethodSchema*/ +} + +/*MGEN:IF(Class.ExistPerThreadStats)*/ +void /*MGEN:Class.NameCap*/::aggregatePerThreadStats(struct PerThreadStats* totals) +{ +/*MGEN:Class.InitializeTotalPerThreadStats*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.AggregatePerThreadStats*/ + } + } +} +/*MGEN:ENDIF*/ + +void /*MGEN:Class.NameCap*/::writeProperties (Buffer& buf) +{ + ::qpid::sys::Mutex::ScopedLock mutex(accessLock); + configChanged = false; + + writeTimestamps (buf); +/*MGEN:IF(Class.ExistOptionals)*/ + for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) + buf.putOctet(presenceMask[idx]); +/*MGEN:ENDIF*/ +/*MGEN:Class.WriteProperties*/ +} + +void /*MGEN:Class.NameCap*/::writeStatistics (Buffer& buf, bool skipHeaders) +{ + ::qpid::sys::Mutex::ScopedLock mutex(accessLock); + instChanged = false; +/*MGEN:IF(Class.ExistPerThreadAssign)*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.PerThreadAssign*/ + } + } +/*MGEN:ENDIF*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + struct PerThreadStats totals; + aggregatePerThreadStats(&totals); +/*MGEN:ENDIF*/ +/*MGEN:Class.Assign*/ + if (!skipHeaders) + writeTimestamps (buf); +/*MGEN:Class.WriteStatistics*/ + + // Maintenance of hi-lo statistics +/*MGEN:Class.HiLoStatResets*/ +/*MGEN:IF(Class.ExistPerThreadResets)*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.PerThreadHiLoStatResets*/ + } + } +/*MGEN:ENDIF*/ +} + +void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) +{ + Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; + std::string text; + +/*MGEN:Class.MethodHandlers*/ + outBuf.putLong(status); + outBuf.putShortString(Manageable::StatusText(status, text)); +} diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.h b/qpid/cpp/managementgen/qmfgen/templates/Class.h new file mode 100644 index 0000000000..7796914d51 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.h @@ -0,0 +1,104 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _MANAGEMENT_/*MGEN:Class.NameUpper*/_ +#define _MANAGEMENT_/*MGEN:Class.NameUpper*/_ + +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/ManagementObject.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/framing/Uuid.h" + +namespace qmf { +/*MGEN:Class.OpenNamespaces*/ + +class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject +{ + private: + + static std::string packageName; + static std::string className; + static uint8_t md5Sum[16]; +/*MGEN:IF(Class.ExistOptionals)*/ + uint8_t presenceMask[/*MGEN:Class.PresenceMaskBytes*/]; +/*MGEN:Class.PresenceMaskConstants*/ +/*MGEN:ENDIF*/ + + // Properties +/*MGEN:Class.ConfigDeclarations*/ + // Statistics +/*MGEN:Class.InstDeclarations*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + // Per-Thread Statistics + struct PerThreadStats { +/*MGEN:Class.PerThreadDeclarations*/ + }; + + struct PerThreadStats** perThreadStatsArray; + + inline struct PerThreadStats* getThreadStats() { + int idx = getThreadIndex(); + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats == 0) { + threadStats = new(PerThreadStats); + perThreadStatsArray[idx] = threadStats; +/*MGEN:Class.InitializePerThreadElements*/ + } + return threadStats; + } + + void aggregatePerThreadStats(struct PerThreadStats*); +/*MGEN:ENDIF*/ + // Private Methods + static void writeSchema (::qpid::framing::Buffer& buf); + void writeProperties (::qpid::framing::Buffer& buf); + void writeStatistics (::qpid::framing::Buffer& buf, + bool skipHeaders = false); + void doMethod (std::string& methodName, + ::qpid::framing::Buffer& inBuf, + ::qpid::framing::Buffer& outBuf); + writeSchemaCall_t getWriteSchemaCall(void) { return writeSchema; } +/*MGEN:IF(Class.NoStatistics)*/ + // Stub for getInstChanged. There are no statistics in this class. + bool getInstChanged (void) { return false; } +/*MGEN:ENDIF*/ + public: + + /*MGEN:Class.NameCap*/ (::qpid::management::ManagementAgent* agent, + ::qpid::management::Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); + ~/*MGEN:Class.NameCap*/ (void); + + /*MGEN:Class.SetGeneralReferenceDeclaration*/ + + static void registerSelf (::qpid::management::ManagementAgent* agent); + std::string& getPackageName (void) const { return packageName; } + std::string& getClassName (void) const { return className; } + uint8_t* getMd5Sum (void) const { return md5Sum; } + + // Method IDs +/*MGEN:Class.MethodIdDeclarations*/ + // Accessor Methods +/*MGEN:Class.AccessorMethods*/ +}; + +}/*MGEN:Class.CloseNamespaces*/ + +#endif /*!_MANAGEMENT_/*MGEN:Class.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmfgen/templates/Event.cpp b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp new file mode 100644 index 0000000000..cdb40c6d79 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp @@ -0,0 +1,77 @@ +/*MGEN:commentPrefix=//*/ +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/log/Statement.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/management/Manageable.h" +#include "qpid/agent/ManagementAgent.h" +#include "Event/*MGEN:Event.NameCap*/.h" + +using namespace qmf::/*MGEN:Event.Namespace*/; +using namespace qpid::framing; +using qpid::management::ManagementAgent; +using qpid::management::Manageable; +using qpid::management::ManagementObject; +using qpid::management::Args; +using std::string; + +string Event/*MGEN:Event.NameCap*/::packageName = string ("/*MGEN:Event.NamePackageLower*/"); +string Event/*MGEN:Event.NameCap*/::eventName = string ("/*MGEN:Event.Name*/"); +uint8_t Event/*MGEN:Event.NameCap*/::md5Sum[16] = + {/*MGEN:Event.SchemaMD5*/}; + +Event/*MGEN:Event.NameCap*/::Event/*MGEN:Event.NameCap*/ (/*MGEN:Event.ConstructorArgs*/) : + /*MGEN:Event.ConstructorInits*/ +{} + +namespace { + const string NAME("name"); + const string TYPE("type"); + const string DESC("desc"); + const string ARGCOUNT("argCount"); + const string ARGS("args"); +} + +void Event/*MGEN:Event.NameCap*/::registerSelf(ManagementAgent* agent) +{ + agent->registerEvent(packageName, eventName, md5Sum, writeSchema); +} + +void Event/*MGEN:Event.NameCap*/::writeSchema (Buffer& buf) +{ + FieldTable ft; + + // Schema class header: + buf.putOctet (CLASS_KIND_EVENT); + buf.putShortString (packageName); // Package Name + buf.putShortString (eventName); // Event Name + buf.putBin128 (md5Sum); // Schema Hash + buf.putShort (/*MGEN:Event.ArgCount*/); // Argument Count + + // Arguments +/*MGEN:Event.ArgSchema*/ +} + +void Event/*MGEN:Event.NameCap*/::encode(::qpid::framing::Buffer& buf) const +{ +/*MGEN:Event.ArgEncodes*/ +} diff --git a/qpid/cpp/managementgen/qmfgen/templates/Event.h b/qpid/cpp/managementgen/qmfgen/templates/Event.h new file mode 100644 index 0000000000..b5c2a211d1 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Event.h @@ -0,0 +1,59 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _MANAGEMENT_/*MGEN:Event.NameUpper*/_ +#define _MANAGEMENT_/*MGEN:Event.NameUpper*/_ + +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/ManagementEvent.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/framing/Uuid.h" + +namespace qmf { +/*MGEN:Event.OpenNamespaces*/ + +class Event/*MGEN:Event.NameCap*/ : public ::qpid::management::ManagementEvent +{ + private: + static void writeSchema (::qpid::framing::Buffer& buf); + static std::string packageName; + static std::string eventName; + static uint8_t md5Sum[16]; + +/*MGEN:Event.ArgDeclarations*/ + + public: + writeSchemaCall_t getWriteSchemaCall(void) { return writeSchema; } + + Event/*MGEN:Event.NameCap*/(/*MGEN:Event.ConstructorArgs*/); + ~Event/*MGEN:Event.NameCap*/() {}; + + static void registerSelf(::qpid::management::ManagementAgent* agent); + std::string& getPackageName() const { return packageName; } + std::string& getEventName() const { return eventName; } + uint8_t* getMd5Sum() const { return md5Sum; } + uint8_t getSeverity() const { return /*MGEN:Event.Severity*/; } + void encode(::qpid::framing::Buffer& buffer) const; +}; + +}/*MGEN:Event.CloseNamespaces*/ + +#endif /*!_MANAGEMENT_/*MGEN:Event.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/qmfgen/templates/Makefile.mk b/qpid/cpp/managementgen/qmfgen/templates/Makefile.mk new file mode 100644 index 0000000000..2b32c7c0f2 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Makefile.mk @@ -0,0 +1,40 @@ +# +# 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. +# +/*MGEN:commentPrefix=#*/ +/*MGEN:Root.Disclaimer*/ +/*MGEN:IF(Makefile.QpidBroker)*/ +/*MGEN:mgenDir=$(mgen_dir)*/ +/*MGEN:specDir=$(top_srcdir)/../specs*/ + +mgen_generator=/*MGEN:Makefile.GenSources*/ + +mgen_broker_cpp=/*MGEN:Makefile.GenCppFiles*/ + +# Header file install rules. +/*MGEN:Makefile.HeaderInstalls*/ +if GENERATE +$(srcdir)/managementgen.mk: $(mgen_generator) + $(mgen_cmd) + +$(mgen_generator): +endif +/*MGEN:ENDIF*/ + +qmfgen_sources=/*MGEN:Makefile.GeneratedFiles*/ + diff --git a/qpid/cpp/managementgen/qmfgen/templates/Package.cpp b/qpid/cpp/managementgen/qmfgen/templates/Package.cpp new file mode 100644 index 0000000000..f6bd7f4654 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Package.cpp @@ -0,0 +1,32 @@ +/*MGEN:commentPrefix=//*/ +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "Package.h" +/*MGEN:Schema.ClassIncludes*/ + +using namespace qmf::/*MGEN:Schema.Namespace*/; + +Package::Package (::qpid::management::ManagementAgent* agent) +{ +/*MGEN:Schema.ClassRegisters*/ +} + diff --git a/qpid/cpp/managementgen/qmfgen/templates/Package.h b/qpid/cpp/managementgen/qmfgen/templates/Package.h new file mode 100644 index 0000000000..0ad7060b9e --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/Package.h @@ -0,0 +1,41 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ +#define _MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ + +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/agent/ManagementAgent.h" + +namespace qmf { +/*MGEN:Class.OpenNamespaces*/ + +class Package +{ + public: + Package (::qpid::management::ManagementAgent* agent); + ~Package () {} +}; + +}/*MGEN:Class.CloseNamespaces*/ + + +#endif /*!_MANAGEMENT_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_*/ -- cgit v1.2.1 From a00e575e242f6c5c9673948efc905226f5a0bfd2 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Fri, 21 Nov 2008 20:17:22 +0000 Subject: Fixed several problems related to qmf update timestamps: - Timestamps were set at update send time regardless of whether the object's contents were actually changed. Now timestamps are set at the time of the change. - Agent heartbeat messages are now being sent after periodic updates, not before. Cleaned up the Agent object in qmf.console. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@719699 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/schema.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index 692a474992..350a271dd4 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -145,6 +145,7 @@ class SchemaType: stream.write (" " + prefix + varName + "Max = val;\n") if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") + stream.write (" setUpdateTime();\n") stream.write (" }\n") if self.style != "mma": stream.write (" inline " + self.asArg + " get_" + varName + "() {\n"); @@ -157,6 +158,7 @@ class SchemaType: stream.write (" presenceMask[presenceByte_%s] &= ~presenceMask_%s;\n" % (varName, varName)) if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") + stream.write (" setUpdateTime();\n") stream.write (" }\n") stream.write (" inline bool isSet_" + varName + "() {\n") stream.write (" return (presenceMask[presenceByte_%s] & presenceMask_%s) != 0;\n" % (varName, varName)) @@ -171,6 +173,7 @@ class SchemaType: stream.write (" " + varName + "High = " + varName + ";\n") if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") + stream.write (" setUpdateTime();\n") stream.write (" }\n"); stream.write (" inline void dec_" + varName + " (" + self.asArg + " by = 1) {\n"); if not self.perThread: @@ -181,6 +184,7 @@ class SchemaType: stream.write (" " + varName + "Low = " + varName + ";\n") if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") + stream.write (" setUpdateTime();\n") stream.write (" }\n"); def genHiLoStatResets (self, stream, varName): -- cgit v1.2.1 From 48d0bab6b2bc033c649bd39ce9949b1a7925ae5e Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 26 Nov 2008 20:48:44 +0000 Subject: Bug fixes for QMF: ManagementAgentImpl - don't send messages if broker is not connected. ManagementBroker - agents could be assigned the same agentBank - don't send console-attached for attached agents - handle multiple qmf messages in an AMQP body schema.py - Don't use the FieldTable copy-constructor, use .clear() git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@720973 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/schema.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index 350a271dd4..16ec40a8c6 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -367,7 +367,7 @@ class SchemaProperty: stream.write (indent + prefix + self.name + " = " + val + ";\n") def genSchema (self, stream): - stream.write (" ft = FieldTable ();\n") + stream.write (" ft.clear();\n") stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") stream.write (" ft.setInt (ACCESS, ACCESS_" + self.access + ");\n") @@ -458,7 +458,7 @@ class SchemaStatistic: self.type.type.genPerThreadHiLoStatResets (stream, self.name, self.type.type.cpp) def genSchemaText (self, stream, name, desc): - stream.write (" ft = FieldTable ();\n") + stream.write (" ft.clear();\n") stream.write (" ft.setString (NAME, \"" + name + "\");\n") stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") if self.unit != None: @@ -603,7 +603,7 @@ class SchemaArg: return self.dir def genSchema (self, stream, event=False): - stream.write (" ft = FieldTable ();\n") + stream.write (" ft.clear();\n") stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") if (not event): @@ -693,7 +693,7 @@ class SchemaMethod: self.parent.genNamePackageLower(stream, variables) def genSchema (self, stream, variables): - stream.write (" ft = FieldTable ();\n") + stream.write (" ft.clear();\n") stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") stream.write (" ft.setInt (ARGCOUNT, " + str (len (self.args)) + ");\n") if self.desc != None: -- cgit v1.2.1 From de7f1a46af35818b5c96e6c87386606b94ad02f6 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Mon, 1 Dec 2008 16:38:54 +0000 Subject: Fixed a performance regression caused by the management code. The current/last-change timestamp is now set on management objects when they are published, not when they actually change. Also, the timestamp is updated only if modifications were made to the object in the last publish interval. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@722120 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/schema.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index 16ec40a8c6..ee5efc0bb0 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -145,7 +145,6 @@ class SchemaType: stream.write (" " + prefix + varName + "Max = val;\n") if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") - stream.write (" setUpdateTime();\n") stream.write (" }\n") if self.style != "mma": stream.write (" inline " + self.asArg + " get_" + varName + "() {\n"); @@ -158,7 +157,6 @@ class SchemaType: stream.write (" presenceMask[presenceByte_%s] &= ~presenceMask_%s;\n" % (varName, varName)) if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") - stream.write (" setUpdateTime();\n") stream.write (" }\n") stream.write (" inline bool isSet_" + varName + "() {\n") stream.write (" return (presenceMask[presenceByte_%s] & presenceMask_%s) != 0;\n" % (varName, varName)) @@ -173,7 +171,6 @@ class SchemaType: stream.write (" " + varName + "High = " + varName + ";\n") if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") - stream.write (" setUpdateTime();\n") stream.write (" }\n"); stream.write (" inline void dec_" + varName + " (" + self.asArg + " by = 1) {\n"); if not self.perThread: @@ -184,7 +181,6 @@ class SchemaType: stream.write (" " + varName + "Low = " + varName + ";\n") if changeFlag != None: stream.write (" " + changeFlag + " = true;\n") - stream.write (" setUpdateTime();\n") stream.write (" }\n"); def genHiLoStatResets (self, stream, varName): -- cgit v1.2.1 From bc487c6e895226e4b35f46077082ee7a7fcef220 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Mon, 8 Dec 2008 14:26:55 +0000 Subject: Management optimization: don't send (empty) statistic updates for object classes that don't have statistics. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@724356 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/templates/Class.h | 31 +++++++++++++------------ 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.h b/qpid/cpp/managementgen/qmfgen/templates/Class.h index 7796914d51..0bf9911895 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.h +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.h @@ -68,30 +68,31 @@ class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject void aggregatePerThreadStats(struct PerThreadStats*); /*MGEN:ENDIF*/ // Private Methods - static void writeSchema (::qpid::framing::Buffer& buf); - void writeProperties (::qpid::framing::Buffer& buf); - void writeStatistics (::qpid::framing::Buffer& buf, - bool skipHeaders = false); - void doMethod (std::string& methodName, - ::qpid::framing::Buffer& inBuf, - ::qpid::framing::Buffer& outBuf); - writeSchemaCall_t getWriteSchemaCall(void) { return writeSchema; } + static void writeSchema(::qpid::framing::Buffer& buf); + void writeProperties(::qpid::framing::Buffer& buf); + void writeStatistics(::qpid::framing::Buffer& buf, + bool skipHeaders = false); + void doMethod(std::string& methodName, + ::qpid::framing::Buffer& inBuf, + ::qpid::framing::Buffer& outBuf); + writeSchemaCall_t getWriteSchemaCall() { return writeSchema; } /*MGEN:IF(Class.NoStatistics)*/ // Stub for getInstChanged. There are no statistics in this class. - bool getInstChanged (void) { return false; } + bool getInstChanged() { return false; } + bool hasInst() { return false; } /*MGEN:ENDIF*/ public: - /*MGEN:Class.NameCap*/ (::qpid::management::ManagementAgent* agent, + /*MGEN:Class.NameCap*/(::qpid::management::ManagementAgent* agent, ::qpid::management::Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); - ~/*MGEN:Class.NameCap*/ (void); + ~/*MGEN:Class.NameCap*/(); /*MGEN:Class.SetGeneralReferenceDeclaration*/ - static void registerSelf (::qpid::management::ManagementAgent* agent); - std::string& getPackageName (void) const { return packageName; } - std::string& getClassName (void) const { return className; } - uint8_t* getMd5Sum (void) const { return md5Sum; } + static void registerSelf(::qpid::management::ManagementAgent* agent); + std::string& getPackageName() const { return packageName; } + std::string& getClassName() const { return className; } + uint8_t* getMd5Sum() const { return md5Sum; } // Method IDs /*MGEN:Class.MethodIdDeclarations*/ -- cgit v1.2.1 From 64b313b500c260072858519d7ad74880b27cd40f Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Mon, 15 Dec 2008 11:48:25 +0000 Subject: Minor correction to included ASF license git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@726685 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/__init__.py | 2 +- qpid/cpp/managementgen/qmfgen/generate.py | 2 +- qpid/cpp/managementgen/qmfgen/schema.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/__init__.py b/qpid/cpp/managementgen/qmfgen/__init__.py index caef6cc58b..63a3f41f28 100644 --- a/qpid/cpp/managementgen/qmfgen/__init__.py +++ b/qpid/cpp/managementgen/qmfgen/__init__.py @@ -7,7 +7,7 @@ # "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 +# 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 diff --git a/qpid/cpp/managementgen/qmfgen/generate.py b/qpid/cpp/managementgen/qmfgen/generate.py index 762af972e7..35e222ebad 100755 --- a/qpid/cpp/managementgen/qmfgen/generate.py +++ b/qpid/cpp/managementgen/qmfgen/generate.py @@ -7,7 +7,7 @@ # "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 +# 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 diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index ee5efc0bb0..69823d6de0 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -7,7 +7,7 @@ # "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 +# 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 -- cgit v1.2.1 From 62910b3fa3691d3d159f22fba349541b5cd83cac Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Mon, 15 Dec 2008 15:17:40 +0000 Subject: Added ASF license to makefiles git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@726710 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/Makefile.am | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am index f4f4b35e40..da7277b255 100644 --- a/qpid/cpp/managementgen/Makefile.am +++ b/qpid/cpp/managementgen/Makefile.am @@ -1,3 +1,21 @@ +# +# 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. +# qmfpythondir = $(pythondir) dist_bin_SCRIPTS = \ qmf-gen -- cgit v1.2.1 From de54a16ea46a41ec95cb888dddb7b9e91744ef40 Mon Sep 17 00:00:00 2001 From: Rajith Muditha Attapattu Date: Fri, 19 Dec 2008 18:22:03 +0000 Subject: Added ASF licensing headers to the following files git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@728091 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf-gen | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index 21c42dc107..15fbdadfb4 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -1,4 +1,25 @@ #!/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. +# +# + # # Licensed to the Apache Software Foundation (ASF) under one -- cgit v1.2.1 From 99e47dcfda0cfa81a6fe0e73de76942e19b8e944 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Thu, 15 Jan 2009 12:32:27 +0000 Subject: Removed duplicate license text git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@734686 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf-gen | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index 15fbdadfb4..f2efa109f3 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -1,5 +1,4 @@ #!/usr/bin/env python -# # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file @@ -18,27 +17,7 @@ # specific language governing permissions and limitations # under the License. # -# - -# -# 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. -# import sys import os from qmfgen.schema import SchemaPackage, SchemaClass -- cgit v1.2.1 From 6579fef308adbd67eba30811abb4da7478031575 Mon Sep 17 00:00:00 2001 From: "Stephen D. Huston" Date: Thu, 23 Apr 2009 22:59:12 +0000 Subject: Merge in initial changes to allow building with CMake; rubygen and managementgen can now generate either .mk files or .cmake files as needed; CONF_FILE and MODULE_DIR macros now have broker/client counterparts QPIDD_CONF_FILE, QPIDD_MODULE_DIR, QPIDC_CONF_FILE, QPIDC_MODULE_DIR configurable by cmake git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@768085 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/CMakeLists.txt | 37 +++++++++ qpid/cpp/managementgen/qmf-gen | 8 ++ qpid/cpp/managementgen/qmfgen/generate.py | 95 +++++++++++++++++++++- .../qmfgen/templates/CMakeLists.cmake | 39 +++++++++ 4 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 qpid/cpp/managementgen/CMakeLists.txt create mode 100644 qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/CMakeLists.txt b/qpid/cpp/managementgen/CMakeLists.txt new file mode 100644 index 0000000000..fa0c3f2909 --- /dev/null +++ b/qpid/cpp/managementgen/CMakeLists.txt @@ -0,0 +1,37 @@ +# +# 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. +# +project(qpidc-qmfgen) +cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR) + +install(PROGRAMS qmf-gen DESTINATION managementgen + COMPONENT all-source) +install(FILES qmfgen/__init__.py + qmfgen/generate.py + qmfgen/schema.py + qmfgen/templates/Args.h + qmfgen/templates/Class.cpp + qmfgen/templates/Class.h + qmfgen/templates/Event.cpp + qmfgen/templates/Event.h + qmfgen/templates/Makefile.mk + qmfgen/templates/Package.cpp + qmfgen/templates/Package.h + qmfgen/management-types.xml + DESTINATION managementgen + COMPONENT all-source) diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index f2efa109f3..c6cfca5f83 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -33,6 +33,8 @@ usage = "usage: %prog [options] schema-document..." parser = OptionParser(usage=usage) parser.add_option("-o", "--outputdir", dest="outputdir", metavar="DIR", default="./", help="Output directory") +parser.add_option("-c", "--cmakelists", dest="cmakelists", metavar="FILE", + help="CMakeLists fragment") parser.add_option("-m", "--makefile", dest="makefile", metavar="FILE", help="Makefile fragment") parser.add_option("-t", "--typefile", dest="typefile", metavar="FILE", default=defaultTypeFile, @@ -72,3 +74,9 @@ if opts.makefile != None: args["qpidbroker"] = opts.qpidbroker args["genprefix"] = opts.genprefix gen.makeSingleFile("Makefile.mk", opts.makefile, force=True, vars=args) + +if opts.cmakelists != None: + args = {} + args["qpidbroker"] = opts.qpidbroker + args["genprefix"] = opts.genprefix + gen.makeSingleFile("CMakeLists.cmake", opts.cmakelists, force=True, vars=args) diff --git a/qpid/cpp/managementgen/qmfgen/generate.py b/qpid/cpp/managementgen/qmfgen/generate.py index 35e222ebad..255d41ea0e 100755 --- a/qpid/cpp/managementgen/qmfgen/generate.py +++ b/qpid/cpp/managementgen/qmfgen/generate.py @@ -24,6 +24,7 @@ from errno import * import os import os.path import filecmp +import re class Template: """ @@ -175,6 +176,81 @@ class Makefile: return variables["qpidbroker"] return False +class CMakeLists(Makefile): + """ Object representing a makefile fragment """ + + # Regardless of what normalize() did, switch all the dir separators back + # to '/' - cmake expects that regardless of platform. + def unNormCase (self, path): + return re.sub("\\\\", "/", path) + + def genGenSources (self, stream, variables): + mdir = self.unNormCase(variables["mgenDir"]) + sdir = self.unNormCase(variables["specDir"]) + stream.write (mdir + "/qmf-gen \n") + stream.write (" " + mdir + "/qmfgen/generate.py\n") + stream.write (" " + mdir + "/qmfgen/schema.py\n") + stream.write (" " + mdir + "/qmfgen/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 + "/qmfgen/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 (self.unNormCase(file)) + + def genGenHFiles (self, stream, variables): + first = True + for file in self.filelists["h"]: + if first: + first = False + else: + stream.write (" \n ") + stream.write (self.unNormCase(file)) + + def genGeneratedFiles(self, stream, variables): + first = True + extensions = ("h", "cpp") + for ext in extensions: + for file in self.filelists[ext]: + if first: + first = False + else: + stream.write(" \n ") + if "genprefix" in variables: + prefix = variables["genprefix"] + if prefix != "": + stream.write(prefix + "/") + stream.write(self.unNormCase(file)) + + def genHeaderInstalls (self, stream, variables): + for package in self.packagelist: + stream.write("#Come back to this later...\n") + name = "_".join(package.split("/")) + stream.write("#" + name + "dir = $(includedir)/qmf/" + package + "\n") + stream.write("#dist_" + name + "_HEADERS = ") + first = True + for file in self.filelists["h"]: + file = self.unNormCase(file) + if file.find("gen/qmf/" + package) == 0: + if first: + first = False + else: + stream.write ("\n ") + stream.write("#" + file) + stream.write("\n\n") + class Generator: """ @@ -208,9 +284,10 @@ class Generator: self.input = self.normalize (templateDir) self.packagePath = self.dest self.filelists = {} - self.filelists["h"] = [] - self.filelists["cpp"] = [] - self.filelists["mk"] = [] + self.filelists["h"] = [] + self.filelists["cpp"] = [] + self.filelists["mk"] = [] + self.filelists["cmake"] = [] self.packagelist = [] self.templateFiles = [] self.variables = {} @@ -354,7 +431,17 @@ class Generator: def makeSingleFile (self, templateFile, target, force=False, vars=None): """ Generate a single expanded template """ - makefile = Makefile (self.filelists, self.templateFiles, self.packagelist) + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + className = templateFile[0:dot] + if className == "Makefile": + classType = Makefile + elif className == "CMakeLists": + classType = CMakeLists + else: + raise ValueError ("Invalid class name %s" % className) + makefile = classType (self.filelists, self.templateFiles, self.packagelist) template = Template (self.input + templateFile, self) if vars: for arg in vars: diff --git a/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake b/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake new file mode 100644 index 0000000000..a7268ad206 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake @@ -0,0 +1,39 @@ +# +# 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. +# +/*MGEN:commentPrefix=#*/ +/*MGEN:Root.Disclaimer*/ +/*MGEN:IF(CMakeLists.QpidBroker)*/ +/*MGEN:mgenDir=${mgen_dir}*/ +/*MGEN:specDir=${qpidc_SOURCE_DIR}/../specs*/ + +set(mgen_generator /*MGEN:CMakeLists.GenSources*/) + +set(mgen_broker_cpp /*MGEN:CMakeLists.GenCppFiles*/) + +# Header file install rules. +#/*MGEN:CMakeLists.HeaderInstalls*/ +#if GENERATE +#$(srcdir)/managementgen.mk: $(mgen_generator) +# $(mgen_cmd) +# +#$(mgen_generator): +#endif +#/*MGEN:ENDIF*/ + +set(qmfgen_sources /*MGEN:CMakeLists.GeneratedFiles*/) -- cgit v1.2.1 From d003b6fde86d23727f1b77a4856f786354ea3288 Mon Sep 17 00:00:00 2001 From: Andrew Stitcher Date: Tue, 28 Apr 2009 21:51:54 +0000 Subject: Fixed to allow use of cmake 2.4 Fixes to allow cmake to build all the plugin modules as before git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@769559 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/CMakeLists.txt b/qpid/cpp/managementgen/CMakeLists.txt index fa0c3f2909..8d053e3e08 100644 --- a/qpid/cpp/managementgen/CMakeLists.txt +++ b/qpid/cpp/managementgen/CMakeLists.txt @@ -17,7 +17,7 @@ # under the License. # project(qpidc-qmfgen) -cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR) +cmake_minimum_required(VERSION 2.4.0 FATAL_ERROR) install(PROGRAMS qmf-gen DESTINATION managementgen COMPONENT all-source) -- cgit v1.2.1 From 690e5d617c9aad8550905cf30a8380778c0f9e7a Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Mon, 11 May 2009 14:16:52 +0000 Subject: QPID-1843 - Cleaned up the interface to the broker's internal management agent. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@773570 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf-gen | 22 +++++++++++++++------- qpid/cpp/managementgen/qmfgen/generate.py | 20 ++++++++++++++++---- qpid/cpp/managementgen/qmfgen/schema.py | 9 +++++++++ qpid/cpp/managementgen/qmfgen/templates/Class.cpp | 7 +++---- qpid/cpp/managementgen/qmfgen/templates/Class.h | 6 ++++++ qpid/cpp/managementgen/qmfgen/templates/Event.cpp | 2 +- qpid/cpp/managementgen/qmfgen/templates/Package.h | 2 +- 7 files changed, 51 insertions(+), 17 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index c6cfca5f83..ebc07137ae 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -45,6 +45,8 @@ parser.add_option("-p", "--gen-prefix", dest="genprefix", default="", help="Prefix for generated files in make dependencies") parser.add_option("-q", "--qpid-broker", dest="qpidbroker", default=False, action="store_true", help="Generate makefile for Qpid broker") +parser.add_option("-b", "--broker-plugin", dest="brokerplugin", default=False, action="store_true", + help="Generate code for use in a qpid broker plugin") (opts, args) = parser.parse_args() @@ -57,17 +59,23 @@ if len(args) == 0: print "no input files" parser.exit() +vargs = {} +if opts.brokerplugin: + vargs["agentHeaderDir"] = "management" +else: + vargs["agentHeaderDir"] = "agent" + for schemafile in args: package = SchemaPackage(typefile, schemafile, opts) gen.setPackage (package.packageName) - gen.makeClassFiles ("Class.h", package) - gen.makeClassFiles ("Class.cpp", package) - gen.makeMethodFiles ("Args.h", package) - gen.makeEventFiles ("Event.h", package) - gen.makeEventFiles ("Event.cpp", package) - gen.makePackageFile ("Package.h", package) - gen.makePackageFile ("Package.cpp", package) + gen.makeClassFiles ("Class.h", package, vars=vargs) + gen.makeClassFiles ("Class.cpp", package, vars=vargs) + gen.makeMethodFiles ("Args.h", package, vars=vargs) + gen.makeEventFiles ("Event.h", package, vars=vargs) + gen.makeEventFiles ("Event.cpp", package, vars=vargs) + gen.makePackageFile ("Package.h", package, vars=vargs) + gen.makePackageFile ("Package.cpp", package, vars=vargs) if opts.makefile != None: args = {} diff --git a/qpid/cpp/managementgen/qmfgen/generate.py b/qpid/cpp/managementgen/qmfgen/generate.py index 255d41ea0e..7173c2faa1 100755 --- a/qpid/cpp/managementgen/qmfgen/generate.py +++ b/qpid/cpp/managementgen/qmfgen/generate.py @@ -388,30 +388,39 @@ class Generator: def setVariable (self, key, value): self.variables[key] = value - def makeClassFiles (self, templateFile, schema, force=False): + def makeClassFiles (self, templateFile, schema, force=False, vars=None): """ Generate an expanded template per schema class """ classes = schema.getClasses () template = Template (self.input + templateFile, self) + if vars: + for arg in vars: + self.setVariable(arg, vars[arg]) self.templateFiles.append (templateFile) for _class in classes: target = self.targetClassFile (_class, templateFile) stream = template.expand (_class) self.writeIfChanged (stream, target, force) - def makeEventFiles (self, templateFile, schema, force=False): + def makeEventFiles (self, templateFile, schema, force=False, vars=None): """ Generate an expanded template per schema event """ events = schema.getEvents() template = Template (self.input + templateFile, self) + if vars: + for arg in vars: + self.setVariable(arg, vars[arg]) self.templateFiles.append (templateFile) for event in events: target = self.targetEventFile(event, templateFile) stream = template.expand(event) self.writeIfChanged(stream, target, force) - def makeMethodFiles (self, templateFile, schema, force=False): + def makeMethodFiles (self, templateFile, schema, force=False, vars=None): """ Generate an expanded template per method-with-arguments """ classes = schema.getClasses () template = Template (self.input + templateFile, self) + if vars: + for arg in vars: + self.setVariable(arg, vars[arg]) self.templateFiles.append (templateFile) for _class in classes: methods = _class.getMethods () @@ -421,9 +430,12 @@ class Generator: stream = template.expand (method) self.writeIfChanged (stream, target, force) - def makePackageFile (self, templateFile, schema, force=False): + def makePackageFile (self, templateFile, schema, force=False, vars=None): """ Generate a package-specific file """ template = Template (self.input + templateFile, self) + if vars: + for arg in vars: + self.setVariable(arg, vars[arg]) self.templateFiles.append (templateFile) target = self.targetPackageFile (schema, templateFile) stream = template.expand (schema) diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index 69823d6de0..3b53830c69 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -754,6 +754,9 @@ class SchemaEvent: def getFullName (self): return capitalize(self.package + capitalize(self.name)) + def genAgentHeaderLocation (self, stream, variables): + stream.write(variables["agentHeaderDir"]) + def getArgCount (self): return len (self.args) @@ -954,6 +957,9 @@ class SchemaClass: if inst.assign == None: inst.genAccessor (stream) + def genAgentHeaderLocation (self, stream, variables): + stream.write(variables["agentHeaderDir"]) + def genCloseNamespaces (self, stream, variables): for item in self.packageName.split("."): stream.write ("}") @@ -1258,6 +1264,9 @@ class SchemaPackage: def getEvents(self): return self.events + def genAgentHeaderLocation (self, stream, variables): + stream.write(variables["agentHeaderDir"]) + def genCloseNamespaces (self, stream, variables): for item in self.packageName.split("."): stream.write ("}") diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp index 247e1090ff..973d92586a 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp @@ -23,7 +23,7 @@ #include "qpid/log/Statement.h" #include "qpid/framing/FieldTable.h" #include "qpid/management/Manageable.h" -#include "qpid/agent/ManagementAgent.h" +#include "qpid//*MGEN:Class.AgentHeaderLocation*//ManagementAgent.h" #include "/*MGEN:Class.NameCap*/.h" /*MGEN:Class.MethodArgIncludes*/ @@ -40,8 +40,8 @@ string /*MGEN:Class.NameCap*/::className = string ("/*MGEN:Class.NameLower*/ uint8_t /*MGEN:Class.NameCap*/::md5Sum[16] = {/*MGEN:Class.SchemaMD5*/}; -/*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (ManagementAgent* _agent, Manageable* _core/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/) : - ManagementObject(_agent, _core)/*MGEN:Class.ConstructorInits*/ +/*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (ManagementAgent*, Manageable* _core/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/) : + ManagementObject(_core)/*MGEN:Class.ConstructorInits*/ { /*MGEN:Class.ParentRefAssignment*/ /*MGEN:Class.InitializeElements*/ @@ -51,7 +51,6 @@ uint8_t /*MGEN:Class.NameCap*/::md5Sum[16] = presenceMask[idx] = 0; /*MGEN:ENDIF*/ /*MGEN:IF(Class.ExistPerThreadStats)*/ - maxThreads = agent->getMaxThreads(); perThreadStatsArray = new struct PerThreadStats*[maxThreads]; for (int idx = 0; idx < maxThreads; idx++) perThreadStatsArray[idx] = 0; diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.h b/qpid/cpp/managementgen/qmfgen/templates/Class.h index 0bf9911895..225090f0a9 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.h +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.h @@ -27,6 +27,12 @@ #include "qpid/framing/FieldTable.h" #include "qpid/framing/Uuid.h" +namespace qpid { + namespace management { + class ManagementAgent; + } +} + namespace qmf { /*MGEN:Class.OpenNamespaces*/ diff --git a/qpid/cpp/managementgen/qmfgen/templates/Event.cpp b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp index cdb40c6d79..2ffec8bcdf 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Event.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp @@ -23,7 +23,7 @@ #include "qpid/log/Statement.h" #include "qpid/framing/FieldTable.h" #include "qpid/management/Manageable.h" -#include "qpid/agent/ManagementAgent.h" +#include "qpid//*MGEN:Event.AgentHeaderLocation*//ManagementAgent.h" #include "Event/*MGEN:Event.NameCap*/.h" using namespace qmf::/*MGEN:Event.Namespace*/; diff --git a/qpid/cpp/managementgen/qmfgen/templates/Package.h b/qpid/cpp/managementgen/qmfgen/templates/Package.h index 0ad7060b9e..569c7cfb33 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Package.h +++ b/qpid/cpp/managementgen/qmfgen/templates/Package.h @@ -23,7 +23,7 @@ /*MGEN:Root.Disclaimer*/ -#include "qpid/agent/ManagementAgent.h" +#include "qpid//*MGEN:Class.AgentHeaderLocation*//ManagementAgent.h" namespace qmf { /*MGEN:Class.OpenNamespaces*/ -- cgit v1.2.1 From 330c054373a42fd0c80411817bef880ab163499a Mon Sep 17 00:00:00 2001 From: Andrew Stitcher Date: Thu, 21 May 2009 15:04:56 +0000 Subject: Fix managementgen so to avoid trying to move files cross fs git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@777146 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/generate.py b/qpid/cpp/managementgen/qmfgen/generate.py index 7173c2faa1..44c434216e 100755 --- a/qpid/cpp/managementgen/qmfgen/generate.py +++ b/qpid/cpp/managementgen/qmfgen/generate.py @@ -311,7 +311,7 @@ class Generator: def writeIfChanged (self, stream, target, force=False): ext = self.fileExt (target) self.filelists[ext].append (target) - tempFile = self.packagePath + "gen.tmp" + tempFile = target + ".gen.tmp" fd = open (tempFile, "w") fd.write (stream.getvalue ()) fd.close () -- cgit v1.2.1 From 641f048cb8b86be0304441a6227759d7ad420ff3 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Thu, 11 Jun 2009 15:54:37 +0000 Subject: QPID-1786 - Committed qmf patches from Bryan Kearney Additionally updated existing qmf and Qman to be compatible. The magic number for qmf messages has been incremented. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@783818 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/management-types.xml | 2 +- qpid/cpp/managementgen/qmfgen/templates/Class.cpp | 1 + qpid/cpp/managementgen/qmfgen/templates/Event.cpp | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/management-types.xml b/qpid/cpp/managementgen/qmfgen/management-types.xml index 626880afb3..e235920447 100644 --- a/qpid/cpp/managementgen/qmfgen/management-types.xml +++ b/qpid/cpp/managementgen/qmfgen/management-types.xml @@ -36,7 +36,7 @@ - + diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp index 973d92586a..52ffce0eb4 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp @@ -98,6 +98,7 @@ void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) buf.putShortString (packageName); // Package Name buf.putShortString (className); // Class Name buf.putBin128 (md5Sum); // Schema Hash + buf.putOctet (0); // No Superclass buf.putShort (/*MGEN:Class.ConfigCount*/); // Config Element Count buf.putShort (/*MGEN:Class.InstCount*/); // Inst Element Count buf.putShort (/*MGEN:Class.MethodCount*/); // Method Count diff --git a/qpid/cpp/managementgen/qmfgen/templates/Event.cpp b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp index 2ffec8bcdf..a4fc28990d 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Event.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp @@ -65,6 +65,7 @@ void Event/*MGEN:Event.NameCap*/::writeSchema (Buffer& buf) buf.putShortString (packageName); // Package Name buf.putShortString (eventName); // Event Name buf.putBin128 (md5Sum); // Schema Hash + buf.putOctet (0); // No Superclass buf.putShort (/*MGEN:Event.ArgCount*/); // Argument Count // Arguments -- cgit v1.2.1 From e38976389b8577c731c655cd64a9fe3c167f9b65 Mon Sep 17 00:00:00 2001 From: Andrew Stitcher Date: Thu, 2 Jul 2009 05:46:51 +0000 Subject: Fix make build to generate code into the build tree git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@790465 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake b/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake index a7268ad206..54f446a437 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake +++ b/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake @@ -20,7 +20,7 @@ /*MGEN:Root.Disclaimer*/ /*MGEN:IF(CMakeLists.QpidBroker)*/ /*MGEN:mgenDir=${mgen_dir}*/ -/*MGEN:specDir=${qpidc_SOURCE_DIR}/../specs*/ +/*MGEN:specDir=${qpid-cpp_SOURCE_DIR}/../specs*/ set(mgen_generator /*MGEN:CMakeLists.GenSources*/) -- cgit v1.2.1 From 401607f0a25273441a04b1a058cf6f9c9143ea34 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Mon, 27 Jul 2009 21:32:16 +0000 Subject: Separate generated public header files from non-public headers, generated code re-organization. The gen/ directory has been removed, code is now generated into: $(builddir)/src - all .cpp files and non-public .h files. $(builddir)/include - all public .h files. The gen/ directory was originally intended to separate generated code from hand-written code. However both automake and cmake allow you to direct all build output, including generated code, into a separate build directory. In fact both recommend you build this way. Keeping the gen/ directory meant there would have been a total of 8 places to look for header files, all the combinations of builddir/srcdir, src/include and gen/no-gen. This was a mess, 4 is bad enough. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@798291 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/generate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/generate.py b/qpid/cpp/managementgen/qmfgen/generate.py index 44c434216e..4052b8c853 100755 --- a/qpid/cpp/managementgen/qmfgen/generate.py +++ b/qpid/cpp/managementgen/qmfgen/generate.py @@ -163,7 +163,7 @@ class Makefile: stream.write("dist_" + name + "_HEADERS = ") first = True for file in self.filelists["h"]: - if file.find("gen/qmf/" + package) == 0: + if file.find("qmf/" + package) == 0: if first: first = False else: @@ -243,7 +243,7 @@ class CMakeLists(Makefile): first = True for file in self.filelists["h"]: file = self.unNormCase(file) - if file.find("gen/qmf/" + package) == 0: + if file.find("qmf/" + package) == 0: if first: first = False else: -- cgit v1.2.1 From b4a8deeb520451eb429fe5360752a9918c49ff1a Mon Sep 17 00:00:00 2001 From: "Stephen D. Huston" Date: Wed, 7 Oct 2009 23:43:27 +0000 Subject: Added more install-related content to the CMake structure. Adds changes requested in QPID-2123, modified somewhat. Also adds Windows-specific installer content in cpp/packaging. Other specific packaging things can be added there as well. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@822965 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/CMakeLists.txt | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/CMakeLists.txt b/qpid/cpp/managementgen/CMakeLists.txt index 8d053e3e08..2511b745a3 100644 --- a/qpid/cpp/managementgen/CMakeLists.txt +++ b/qpid/cpp/managementgen/CMakeLists.txt @@ -20,18 +20,7 @@ project(qpidc-qmfgen) cmake_minimum_required(VERSION 2.4.0 FATAL_ERROR) install(PROGRAMS qmf-gen DESTINATION managementgen - COMPONENT all-source) -install(FILES qmfgen/__init__.py - qmfgen/generate.py - qmfgen/schema.py - qmfgen/templates/Args.h - qmfgen/templates/Class.cpp - qmfgen/templates/Class.h - qmfgen/templates/Event.cpp - qmfgen/templates/Event.h - qmfgen/templates/Makefile.mk - qmfgen/templates/Package.cpp - qmfgen/templates/Package.h - qmfgen/management-types.xml - DESTINATION managementgen - COMPONENT all-source) + COMPONENT ${QPID_COMPONENT_QMF}) +install(DIRECTORY qmfgen DESTINATION managementgen + COMPONENT ${QPID_COMPONENT_QMF} + PATTERN ".svn" EXCLUDE PATTERN "*.pyc" EXCLUDE) -- cgit v1.2.1 From 950f4b40bfc05db37d91d960cda163f557dd5e50 Mon Sep 17 00:00:00 2001 From: "Stephen D. Huston" Date: Fri, 20 Nov 2009 01:04:03 +0000 Subject: Removed the Visual Studio solution/project files, as these are now generated by CMake. Added CMakeLists.txt files to Makefile.am, and all other needed support files so that the 'make dist' supplies all needed items for building a release kit on Windows. Fixes QPID-2134 git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@882373 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am index da7277b255..7f85834093 100644 --- a/qpid/cpp/managementgen/Makefile.am +++ b/qpid/cpp/managementgen/Makefile.am @@ -33,4 +33,4 @@ nobase_qmfpython_DATA = \ qmfgen/templates/Package.h \ qmfgen/management-types.xml -EXTRA_DIST = $(nobase_qmfpython_DATA) +EXTRA_DIST = $(nobase_qmfpython_DATA) CMakeLists.txt -- cgit v1.2.1 From 3bc7e889caef716d8fdd8006f2d53b821ecef6c1 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Fri, 11 Dec 2009 13:52:48 +0000 Subject: QPID-2245 QMF protocol changes will make 0.6 incompatible with 0.5 git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@889619 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/management-types.xml | 2 +- qpid/cpp/managementgen/qmfgen/templates/Class.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/management-types.xml b/qpid/cpp/managementgen/qmfgen/management-types.xml index e235920447..626880afb3 100644 --- a/qpid/cpp/managementgen/qmfgen/management-types.xml +++ b/qpid/cpp/managementgen/qmfgen/management-types.xml @@ -36,7 +36,7 @@ - + diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp index 52ffce0eb4..973d92586a 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp @@ -98,7 +98,6 @@ void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) buf.putShortString (packageName); // Package Name buf.putShortString (className); // Class Name buf.putBin128 (md5Sum); // Schema Hash - buf.putOctet (0); // No Superclass buf.putShort (/*MGEN:Class.ConfigCount*/); // Config Element Count buf.putShort (/*MGEN:Class.InstCount*/); // Inst Element Count buf.putShort (/*MGEN:Class.MethodCount*/); // Method Count -- cgit v1.2.1 From b5d8b71528b9fcb391bbc4c53c77807830d25581 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 3 Feb 2010 13:35:58 +0000 Subject: Changes to management code generation: 1) Added readProperties(Buffer) method to ManagementObject to help in the serialization and unserialization of data for cluster replication. 2) Added hooks to ManagementObject and ObjectId to prepare for QMFv2 object naming. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@906038 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/management-types.xml | 58 +++++++++++----------- qpid/cpp/managementgen/qmfgen/schema.py | 33 ++++++++++++ qpid/cpp/managementgen/qmfgen/templates/Class.cpp | 21 ++++++++ qpid/cpp/managementgen/qmfgen/templates/Class.h | 2 + 4 files changed, 85 insertions(+), 29 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/management-types.xml b/qpid/cpp/managementgen/qmfgen/management-types.xml index 626880afb3..f3894cc962 100644 --- a/qpid/cpp/managementgen/qmfgen/management-types.xml +++ b/qpid/cpp/managementgen/qmfgen/management-types.xml @@ -19,38 +19,38 @@ under the License. --> - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - + + + + - - - + + + diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index 3b53830c69..51466c7860 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -58,6 +58,7 @@ class SchemaType: self.encode = None self.decode = None self.style = "normal" + self.stream = "#" self.accessor = None self.init = "0" self.perThread = False @@ -85,6 +86,9 @@ class SchemaType: elif key == 'style': self.style = val + elif key == 'stream': + self.stream = val + elif key == 'accessor': self.accessor = val @@ -200,6 +204,9 @@ class SchemaType: stream.write (" threadStats->" + varName + "Min = std::numeric_limits<" + cpptype + ">::max();\n") stream.write (" threadStats->" + varName + "Max = std::numeric_limits<" + cpptype + ">::min();\n") + def genRead (self, stream, varName, indent=" "): + stream.write(indent + self.decode.replace("@", "buf").replace("#", varName) + ";\n") + def genWrite (self, stream, varName, indent=" "): if self.style != "mma": stream.write (indent + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") @@ -381,6 +388,15 @@ class SchemaProperty: stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") stream.write (" buf.put (ft);\n\n") + def genRead (self, stream): + indent = " " + if self.isOptional: + stream.write(" if (presenceMask[presenceByte_%s] & presenceMask_%s) {\n" % (self.name, self.name)) + indent = " " + self.type.type.genRead (stream, self.name, indent) + if self.isOptional: + stream.write(" }\n") + def genWrite (self, stream): indent = " " if self.isOptional: @@ -1054,6 +1070,19 @@ class SchemaClass: if element.type.type.perThread: element.genDeclaration (stream, " ") + def genPrimaryKey (self, stream, variables): + first = 1 + for prop in self.properties: + if prop.isIndex == 1: + if first: + first = None + else: + stream.write(" << \",\";\n") + var = prop.type.type.stream.replace("#", prop.getName()) + stream.write(" key << %s" % var) + if not first: + stream.write(";") + def genNamespace (self, stream, variables): stream.write("::".join(self.packageName.split("."))) @@ -1182,6 +1211,10 @@ class SchemaClass: if inst.type.type.perThread: inst.genAssign (stream) + def genReadProperties (self, stream, variables): + for prop in self.properties: + prop.genRead (stream) + def genWriteProperties (self, stream, variables): for prop in self.properties: prop.genWrite (stream) diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp index 973d92586a..8312f35c64 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp @@ -26,6 +26,7 @@ #include "qpid//*MGEN:Class.AgentHeaderLocation*//ManagementAgent.h" #include "/*MGEN:Class.NameCap*/.h" /*MGEN:Class.MethodArgIncludes*/ +#include using namespace qmf::/*MGEN:Class.Namespace*/; using namespace qpid::framing; @@ -123,6 +124,17 @@ void /*MGEN:Class.NameCap*/::aggregatePerThreadStats(struct PerThreadStats* tota } /*MGEN:ENDIF*/ +void /*MGEN:Class.NameCap*/::readProperties (Buffer& buf) +{ + ::qpid::sys::Mutex::ScopedLock mutex(accessLock); + readTimestamps(buf); +/*MGEN:IF(Class.ExistOptionals)*/ + for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) + presenceMask[idx] = buf.getOctet(); +/*MGEN:ENDIF*/ +/*MGEN:Class.ReadProperties*/ +} + void /*MGEN:Class.NameCap*/::writeProperties (Buffer& buf) { ::qpid::sys::Mutex::ScopedLock mutex(accessLock); @@ -178,3 +190,12 @@ void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) outBuf.putLong(status); outBuf.putShortString(Manageable::StatusText(status, text)); } + +std::string /*MGEN:Class.NameCap*/::getKey() const +{ + std::stringstream key; + +/*MGEN:Class.PrimaryKey*/ + return key.str(); +} + diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.h b/qpid/cpp/managementgen/qmfgen/templates/Class.h index 225090f0a9..298f339381 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.h +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.h @@ -75,12 +75,14 @@ class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject /*MGEN:ENDIF*/ // Private Methods static void writeSchema(::qpid::framing::Buffer& buf); + void readProperties(::qpid::framing::Buffer& buf); void writeProperties(::qpid::framing::Buffer& buf); void writeStatistics(::qpid::framing::Buffer& buf, bool skipHeaders = false); void doMethod(std::string& methodName, ::qpid::framing::Buffer& inBuf, ::qpid::framing::Buffer& outBuf); + std::string getKey() const; writeSchemaCall_t getWriteSchemaCall() { return writeSchema; } /*MGEN:IF(Class.NoStatistics)*/ // Stub for getInstChanged. There are no statistics in this class. -- cgit v1.2.1 From 3a7f44a61ce4cada2bfce431e405652744368ab3 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Thu, 4 Feb 2010 17:25:19 +0000 Subject: Added encode/decode/encodedSize methods for management objects. Made methods on generated code public. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@906573 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/management-types.xml | 58 +++++++++++----------- qpid/cpp/managementgen/qmfgen/schema.py | 17 +++++++ qpid/cpp/managementgen/qmfgen/templates/Class.cpp | 12 ++++- qpid/cpp/managementgen/qmfgen/templates/Class.h | 9 ++-- 4 files changed, 61 insertions(+), 35 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/management-types.xml b/qpid/cpp/managementgen/qmfgen/management-types.xml index f3894cc962..6dbabc90ff 100644 --- a/qpid/cpp/managementgen/qmfgen/management-types.xml +++ b/qpid/cpp/managementgen/qmfgen/management-types.xml @@ -19,38 +19,38 @@ under the License. --> - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - + + + + - - - + + + diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index 51466c7860..b3d0f751d2 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -59,6 +59,7 @@ class SchemaType: self.decode = None self.style = "normal" self.stream = "#" + self.size = "1" self.accessor = None self.init = "0" self.perThread = False @@ -89,6 +90,9 @@ class SchemaType: elif key == 'stream': self.stream = val + elif key == 'size': + self.size = val + elif key == 'accessor': self.accessor = val @@ -388,6 +392,15 @@ class SchemaProperty: stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") stream.write (" buf.put (ft);\n\n") + def genSize (self, stream): + indent = " " + if self.isOptional: + stream.write(" if (presenceMask[presenceByte_%s] & presenceMask_%s) {\n" % (self.name, self.name)) + indent = " " + stream.write("%ssize += %s; // %s\n" % (indent, self.type.type.size.replace("#", self.name), self.name)) + if self.isOptional: + stream.write(" }\n") + def genRead (self, stream): indent = " " if self.isOptional: @@ -1211,6 +1224,10 @@ class SchemaClass: if inst.type.type.perThread: inst.genAssign (stream) + def genSizeProperties (self, stream, variables): + for prop in self.properties: + prop.genSize (stream) + def genReadProperties (self, stream, variables): for prop in self.properties: prop.genRead (stream) diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp index 8312f35c64..e6362758ba 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp @@ -124,6 +124,16 @@ void /*MGEN:Class.NameCap*/::aggregatePerThreadStats(struct PerThreadStats* tota } /*MGEN:ENDIF*/ +uint32_t /*MGEN:Class.NameCap*/::writePropertiesSize() const +{ + uint32_t size = writeTimestampsSize(); +/*MGEN:IF(Class.ExistOptionals)*/ + size += /*MGEN:Class.PresenceMaskBytes*/; +/*MGEN:ENDIF*/ +/*MGEN:Class.SizeProperties*/ + return size; +} + void /*MGEN:Class.NameCap*/::readProperties (Buffer& buf) { ::qpid::sys::Mutex::ScopedLock mutex(accessLock); @@ -135,7 +145,7 @@ void /*MGEN:Class.NameCap*/::readProperties (Buffer& buf) /*MGEN:Class.ReadProperties*/ } -void /*MGEN:Class.NameCap*/::writeProperties (Buffer& buf) +void /*MGEN:Class.NameCap*/::writeProperties (Buffer& buf) const { ::qpid::sys::Mutex::ScopedLock mutex(accessLock); configChanged = false; diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.h b/qpid/cpp/managementgen/qmfgen/templates/Class.h index 298f339381..8efacd650f 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.h +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.h @@ -73,12 +73,12 @@ class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject void aggregatePerThreadStats(struct PerThreadStats*); /*MGEN:ENDIF*/ - // Private Methods + public: static void writeSchema(::qpid::framing::Buffer& buf); + uint32_t writePropertiesSize() const; void readProperties(::qpid::framing::Buffer& buf); - void writeProperties(::qpid::framing::Buffer& buf); - void writeStatistics(::qpid::framing::Buffer& buf, - bool skipHeaders = false); + void writeProperties(::qpid::framing::Buffer& buf) const; + void writeStatistics(::qpid::framing::Buffer& buf, bool skipHeaders = false); void doMethod(std::string& methodName, ::qpid::framing::Buffer& inBuf, ::qpid::framing::Buffer& outBuf); @@ -89,7 +89,6 @@ class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject bool getInstChanged() { return false; } bool hasInst() { return false; } /*MGEN:ENDIF*/ - public: /*MGEN:Class.NameCap*/(::qpid::management::ManagementAgent* agent, ::qpid::management::Manageable* coreObject/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/); -- cgit v1.2.1 From 9e11e1cd1a0516df8c63de07870e299e9a103a4b Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Mon, 8 Mar 2010 17:33:54 +0000 Subject: QPID-2436: Drop the vhost prefix in QMF V2keys. - The prefix makes the keys extremely long and unreadable. - In a standalone broker it adds nothing since its the same for every object. - In a cluster you need a consistent ID for shadow connections on all brokers. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@920413 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/schema.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index b3d0f751d2..d80567687e 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -1086,13 +1086,14 @@ class SchemaClass: def genPrimaryKey (self, stream, variables): first = 1 for prop in self.properties: - if prop.isIndex == 1: - if first: - first = None - else: - stream.write(" << \",\";\n") - var = prop.type.type.stream.replace("#", prop.getName()) - stream.write(" key << %s" % var) + if prop.getName() != "vhostRef": # Limit how deep the v2Key strings get + if prop.isIndex == 1: + if first: + first = None + else: + stream.write(" << \",\";\n") + var = prop.type.type.stream.replace("#", prop.getName()) + stream.write(" key << %s" % var) if not first: stream.write(";") -- cgit v1.2.1 From c53c4cc94e121c0fc3df6010cffa1bbb49a779db Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 31 Mar 2010 21:13:12 +0000 Subject: Merged the changes from the qmf-devel0.7a branch back to the trunk. This is a checkpoint along the QMFv2 development path. This update introduces portions of QMFv2 into the code: - The C++ agent (qpid/agent) uses QMFv2 for data and method transfer o The APIs no longer use qpid::framing::* o Consequently, boost is no longer referenced from the API headers. o Agents and Objects are now referenced by strings, not numbers. o Schema transfer still uses the QMFv1 format. - The broker-resident agent can use QMFv1 or QMFv2 based on the command line options. It defaults to QMFv1 for compatibility. - The pure-python QMF console (qmf.console) can concurrently interact with both QMFv1 and QMFv2 agents. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@929716 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmf-gen | 2 + qpid/cpp/managementgen/qmfgen/generate.py | 41 +-- qpid/cpp/managementgen/qmfgen/management-types.xml | 28 +- qpid/cpp/managementgen/qmfgen/schema.py | 314 ++++++++++++++++++++- qpid/cpp/managementgen/qmfgen/templates/Args.h | 4 +- qpid/cpp/managementgen/qmfgen/templates/Class.cpp | 158 +++++++++-- qpid/cpp/managementgen/qmfgen/templates/Class.h | 30 +- qpid/cpp/managementgen/qmfgen/templates/Event.cpp | 34 ++- qpid/cpp/managementgen/qmfgen/templates/Event.h | 9 +- 9 files changed, 552 insertions(+), 68 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index ebc07137ae..667aa1ba2d 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -62,8 +62,10 @@ if len(args) == 0: vargs = {} if opts.brokerplugin: vargs["agentHeaderDir"] = "management" + vargs["genQmfV1"] = True else: vargs["agentHeaderDir"] = "agent" + vargs["genQmfV1"] = None for schemafile in args: package = SchemaPackage(typefile, schemafile, opts) diff --git a/qpid/cpp/managementgen/qmfgen/generate.py b/qpid/cpp/managementgen/qmfgen/generate.py index 4052b8c853..8a00b69761 100755 --- a/qpid/cpp/managementgen/qmfgen/generate.py +++ b/qpid/cpp/managementgen/qmfgen/generate.py @@ -38,39 +38,43 @@ class Template: self.filename = filename self.handler = handler self.handler.initExpansion () - self.writing = True + self.writing = 0 # 0 => write output lines; >0 => recursive depth of conditional regions def expandLine (self, line, stream, object): cursor = 0 while 1: sub = line.find ("/*MGEN:", cursor) if sub == -1: - if self.writing: + if self.writing == 0: stream.write (line[cursor:len (line)]) return subend = line.find("*/", sub) - if self.writing: + if self.writing == 0: stream.write (line[cursor:sub]) cursor = subend + 2 tag = line[sub:subend] if tag[7:10] == "IF(": - close = tag.find(")") - if close == -1: - raise ValueError ("Missing ')' on condition") - cond = tag[10:close] - dotPos = cond.find (".") - if dotPos == -1: - raise ValueError ("Invalid condition tag: %s" % cond) - tagObject = cond[0:dotPos] - tagName = cond[dotPos + 1 : len(cond)] - if not self.handler.testCondition(object, tagObject, tagName): - self.writing = False + if self.writing == 0: + close = tag.find(")") + if close == -1: + raise ValueError ("Missing ')' on condition") + cond = tag[10:close] + dotPos = cond.find (".") + if dotPos == -1: + raise ValueError ("Invalid condition tag: %s" % cond) + tagObject = cond[0:dotPos] + tagName = cond[dotPos + 1 : len(cond)] + if not self.handler.testCondition(object, tagObject, tagName): + self.writing += 1 + else: + self.writing += 1 elif tag[7:12] == "ENDIF": - self.writing = True + if self.writing > 0: + self.writing -= 1 else: equalPos = tag.find ("=") @@ -80,12 +84,12 @@ class Template: raise ValueError ("Invalid tag: %s" % tag) tagObject = tag[7:dotPos] tagName = tag[dotPos + 1:len (tag)] - if self.writing: + if self.writing == 0: self.handler.substHandler (object, stream, tagObject, tagName) else: tagKey = tag[7:equalPos] tagVal = tag[equalPos + 1:len (tag)] - if self.writing: + if self.writing == 0: self.handler.setVariable (tagKey, tagVal) def expand (self, object): @@ -297,6 +301,9 @@ class Generator: self.packagelist.append(path) self.packagePath = self.normalize(self.dest + path) + def testGenQMFv1 (self, variables): + return variables["genQmfV1"] + def genDisclaimer (self, stream, variables): prefix = variables["commentPrefix"] stream.write (prefix + " This source file was created by a code generator.\n") diff --git a/qpid/cpp/managementgen/qmfgen/management-types.xml b/qpid/cpp/managementgen/qmfgen/management-types.xml index 6dbabc90ff..857f8af212 100644 --- a/qpid/cpp/managementgen/qmfgen/management-types.xml +++ b/qpid/cpp/managementgen/qmfgen/management-types.xml @@ -19,7 +19,14 @@ under the License. --> - + + + @@ -29,14 +36,25 @@ - - + + - - + + + diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index d80567687e..c1bb507d84 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -19,12 +19,18 @@ from xml.dom.minidom import parse, parseString, Node from cStringIO import StringIO -import md5 +#import md5 +try: + import hashlib + _md5Obj = hashlib.md5 +except ImportError: + import md5 + _md5Obj = md5.new class Hash: """ Manage the hash of an XML sub-tree """ def __init__(self, node): - self.md5Sum = md5.new() + self.md5Sum = _md5Obj() self._compute(node) def addSubHash(self, hash): @@ -64,6 +70,8 @@ class SchemaType: self.init = "0" self.perThread = False self.byRef = False + self.unmap = "#" + self.map = "#" attrs = node.attributes for idx in range (attrs.length): @@ -109,6 +117,12 @@ class SchemaType: raise ValueError ("Expected 'y' in byRef attribute") self.byRef = True + elif key == 'unmap': + self.unmap = val + + elif key == 'map': + self.map = val + else: raise ValueError ("Unknown attribute in type '%s'" % key) @@ -211,6 +225,17 @@ class SchemaType: def genRead (self, stream, varName, indent=" "): stream.write(indent + self.decode.replace("@", "buf").replace("#", varName) + ";\n") + def genUnmap (self, stream, varName, indent=" ", key=None, mapName="_map", + _optional=False): + if key is None: + key = varName + stream.write(indent + "if ((_i = " + mapName + ".find(\"" + key + "\")) != " + mapName + ".end()) {\n") + stream.write(indent + " " + varName + " = " + + self.unmap.replace("#", "_i->second") + ";\n") + if _optional: + stream.write(indent + " _found = true;\n") + stream.write(indent + "}\n") + def genWrite (self, stream, varName, indent=" "): if self.style != "mma": stream.write (indent + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") @@ -230,6 +255,31 @@ class SchemaType: .replace ("#", varName + "Count ? " + varName + "Total / " + varName + "Count : 0") + ";\n") + def genMap (self, stream, varName, indent=" ", key=None, mapName="_map"): + if key is None: + key = varName + if self.style != "mma": + var_cast = self.map.replace("#", varName) + stream.write(indent + mapName + "[\"" + key + "\"] = ::qpid::types::Variant(" + var_cast + ");\n") + if self.style == "wm": + var_cast_hi = self.map.replace("#", varName + "High") + var_cast_lo = self.map.replace("#", varName + "Low") + stream.write(indent + mapName + "[\"" + key + "High\"] = " + + "::qpid::types::Variant(" + var_cast_hi + ");\n") + stream.write(indent + mapName + "[\"" + key + "Low\"] = " + + "::qpid::types::Variant(" + var_cast_lo + ");\n") + if self.style == "mma": + var_cast = self.map.replace("#", varName + "Count") + stream.write(indent + mapName + "[\"" + key + "Count\"] = " + "::qpid::types::Variant(" + var_cast + ");\n") + var_cast = self.map.replace("#", varName + "Min") + stream.write(indent + mapName + "[\"" + key + "Min\"] = " + + "(" + varName + "Count ? ::qpid::types::Variant(" + var_cast + ") : ::qpid::types::Variant(0));\n") + var_cast = self.map.replace("#", varName + "Max") + stream.write(indent + mapName + "[\"" + key + "Max\"] = " + "::qpid::types::Variant(" + var_cast + ");\n") + + var_cast = self.map.replace("#", "(" + varName + "Total / " + varName + "Count)") + stream.write(indent + mapName + "[\"" + key + "Avg\"] = " + + "(" + varName + "Count ? ::qpid::types::Variant(" + var_cast + ") : ::qpid::types::Variant(0));\n") def getReadCode (self, varName, bufName): result = self.decode.replace ("@", bufName).replace ("#", varName) @@ -392,6 +442,29 @@ class SchemaProperty: stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") stream.write (" buf.put (ft);\n\n") + + def genSchemaMap(self, stream): + stream.write (" {\n") + stream.write (" ::qpid::types::Variant::Map _value;\n") + stream.write (" _value[TYPE] = TYPE_" + self.type.type.base +";\n") + stream.write (" _value[ACCESS] = ACCESS_" + self.access + ";\n") + stream.write (" _value[IS_INDEX] = " + str (self.isIndex) + ";\n") + stream.write (" _value[IS_OPTIONAL] = " + str (self.isOptional) + ";\n") + if self.unit != None: + stream.write (" _value[UNIT] = \"" + self.unit + "\";\n") + if self.min != None: + stream.write (" _value[MIN] = " + self.min + ";\n") + if self.max != None: + stream.write (" _value[MAX] = " + self.max + ";\n") + if self.maxLen != None: + stream.write (" _value[MAXLEN] = " + self.maxLen + ";\n") + if self.desc != None: + stream.write (" _value[DESC] = \"" + self.desc + "\";\n") + stream.write (" _props[\"" + self.name + "\"] = _value;\n") + stream.write (" }\n\n") + + + def genSize (self, stream): indent = " " if self.isOptional: @@ -419,6 +492,43 @@ class SchemaProperty: if self.isOptional: stream.write(" }\n") + def genUnmap (self, stream): + indent = " " + if self.isOptional: + stream.write(" _found = false;\n") + self.type.type.genUnmap (stream, self.name, indent, _optional=self.isOptional) + if self.isOptional: + stream.write(" if (_found) {\n") + stream.write(" presenceMask[presenceByte_%s] |= presenceMask_%s;\n" % + (self.name, self.name)) + stream.write(" }\n") + + def genMap (self, stream): + indent = " " + if self.isOptional: + stream.write(" if (presenceMask[presenceByte_%s] & presenceMask_%s) {\n" % (self.name, self.name)) + indent = " " + self.type.type.genMap (stream, self.name, indent) + if self.isOptional: + stream.write(" }\n") + + + def __repr__(self): + m = {} + m["name"] = self.name + m["type"] = self.type + m["ref"] = self.ref + m["access"] = self.access + m["isIndex"] = self.isIndex + m["isParentRef"] = self.isParentRef + m["isGeneralRef"] = self.isGeneralRef + m["isOptional"] = self.isOptional + m["unit"] = self.unit + m["min"] = self.min + m["max"] = self.max + m["maxLen"] = self.maxLen + m["desc"] = self.desc + return str(m) #===================================================================================== # @@ -492,6 +602,17 @@ class SchemaStatistic: stream.write (" ft.setString (DESC, \"" + desc + "\");\n") stream.write (" buf.put (ft);\n\n") + def genSchemaTextMap(self, stream, name, desc): + stream.write (" {\n") + stream.write (" ::qpid::types::Variant::Map _value;\n") + stream.write (" _value[TYPE] = TYPE_" + self.type.type.base +";\n") + if self.unit != None: + stream.write (" _value[UNIT] = \"" + self.unit + "\";\n") + if desc != None: + stream.write (" _value[DESC] = \"" + desc + "\";\n") + stream.write (" _stats[\"" + self.name + "\"] = _value;\n") + stream.write (" }\n\n") + def genSchema (self, stream): if self.type.type.style != "mma": self.genSchemaText (stream, self.name, self.desc) @@ -518,6 +639,32 @@ class SchemaStatistic: self.genSchemaText (stream, self.name + "Max", descMax) self.genSchemaText (stream, self.name + "Average", descAverage) + def genSchemaMap (self, stream): + if self.type.type.style != "mma": + self.genSchemaTextMap (stream, self.name, self.desc) + if self.type.type.style == "wm": + descHigh = self.desc + descLow = self.desc + if self.desc != None: + descHigh = descHigh + " (High)" + descLow = descLow + " (Low)" + self.genSchemaTextMap (stream, self.name + "High", descHigh) + self.genSchemaTextMap (stream, self.name + "Low", descLow) + if self.type.type.style == "mma": + descCount = self.desc + descMin = self.desc + descMax = self.desc + descAverage = self.desc + if self.desc != None: + descCount = descCount + " (Samples)" + descMin = descMin + " (Min)" + descMax = descMax + " (Max)" + descAverage = descAverage + " (Average)" + self.genSchemaTextMap (stream, self.name + "Samples", descCount) + self.genSchemaTextMap (stream, self.name + "Min", descMin) + self.genSchemaTextMap (stream, self.name + "Max", descMax) + self.genSchemaTextMap (stream, self.name + "Average", descAverage) + def genAssign (self, stream): if self.assign != None: if self.type.type.perThread: @@ -533,6 +680,12 @@ class SchemaStatistic: else: self.type.type.genWrite (stream, self.name) + def genMap (self, stream): + if self.type.type.perThread: + self.type.type.genMap(stream, "totals." + self.name, key=self.name) + else: + self.type.type.genMap(stream, self.name) + def genInitialize (self, stream, prefix="", indent=" "): val = self.type.type.init if self.type.type.style != "mma": @@ -648,6 +801,30 @@ class SchemaArg: stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") stream.write (" buf.put (ft);\n\n") + def genSchemaMap (self, stream, event=False): + stream.write (" {\n") + stream.write (" ::qpid::types::Variant::Map _avalue;\n") + stream.write (" _avalue[TYPE] = TYPE_" + self.type.type.base +";\n") + if (not event): + stream.write (" _avalue[DIR] = \"" + self.dir + "\";\n") + if self.unit != None: + stream.write (" _avalue[UNIT] = \"" + self.unit + "\";\n") + if not event: + if self.min != None: + stream.write (" _avalue[MIN] = " + self.min + ";\n") + if self.max != None: + stream.write (" _avalue[MAX] = " + self.max + ";\n") + if self.maxLen != None: + stream.write (" _avalue[MAXLEN] = " + self.maxLen + ";\n") + if self.default != None: + stream.write (" _avalue[DEFAULT] = \"" + self.default + "\";\n") + if self.desc != None: + stream.write (" _avalue[DESC] = \"" + self.desc + "\";\n") + stream.write (" _args[\"" + self.name + "\"] = _avalue;\n") + stream.write (" }\n") + + + def genFormalParam (self, stream, variables): stream.write ("%s _%s" % (self.type.type.asArg, self.name)) @@ -727,6 +904,24 @@ class SchemaMethod: for arg in self.args: arg.genSchema (stream) + def genSchemaMap (self, stream, variables): + stream.write (" {\n") + stream.write (" ::qpid::types::Variant::Map _value;\n") + stream.write (" ::qpid::types::Variant::Map _args;\n") + stream.write (" _value[ARGCOUNT] = " + str(len(self.args)) + ";\n") + if self.desc != None: + stream.write (" _value[DESC] = \"" + self.desc + "\";\n") + + for arg in self.args: + arg.genSchemaMap (stream) + + stream.write (" if (!_args.empty())\n") + stream.write (" _value[ARGS] = _args;\n") + + + stream.write (" _methods[\"" + self.name + "\"] = _value;\n") + stream.write (" }\n\n") + #===================================================================================== # #===================================================================================== @@ -849,10 +1044,20 @@ class SchemaEvent: for arg in self.args: stream.write(" " + arg.type.type.encode.replace("@", "buf").replace("#", arg.name) + ";\n") + def genArgMap(self, stream, variables): + for arg in self.args: + arg.type.type.genMap(stream, arg.name, " ", mapName="map") + #stream.write(" " + arg.type.type.encode.replace("@", "buf").replace("#", arg.name) + ";\n") + + def genArgSchema(self, stream, variables): for arg in self.args: arg.genSchema(stream, True) + def genArgSchemaMap(self, stream, variables): + for arg in self.args: + arg.genSchemaMap(stream, True) + def genSchemaMD5(self, stream, variables): sum = self.hash.getDigest() for idx in range (len (sum)): @@ -1023,12 +1228,36 @@ class SchemaClass: inArgCount = inArgCount + 1 if methodCount == 0: - stream.write ("string&, Buffer&, Buffer& outBuf") + stream.write ("string&, const string&, string& outStr") + else: + if inArgCount == 0: + stream.write ("string& methodName, const string&, string& outStr") + else: + stream.write ("string& methodName, const string& inStr, string& outStr") + + + def genDoMapMethodArgs (self, stream, variables): + methodCount = 0 + inArgCount = 0 + for method in self.methods: + methodCount = methodCount + 1 + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + inArgCount = inArgCount + 1 + + if methodCount == 0: + stream.write ("string&," + + " const ::qpid::types::Variant::Map&," + + " ::qpid::types::Variant::Map& outMap") else: if inArgCount == 0: - stream.write ("string& methodName, Buffer&, Buffer& outBuf") + stream.write ("string& methodName," + + " const ::qpid::types::Variant::Map&," + + " ::qpid::types::Variant::Map& outMap") else: - stream.write ("string& methodName, Buffer& inBuf, Buffer& outBuf") + stream.write ("string& methodName," + + " const ::qpid::types::Variant::Map& inMap," + + " ::qpid::types::Variant::Map& outMap") def genHiLoStatResets (self, stream, variables): for inst in self.statistics: @@ -1109,8 +1338,22 @@ class SchemaClass: stream.write ("%d" % len (self.methods)) def genMethodHandlers (self, stream, variables): + inArgs = False + for method in self.methods: + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + inArgs = True; + break + + if inArgs: + stream.write("\n") + stream.write(" char *_tmpBuf = new char[inStr.length()];\n") + stream.write(" memcpy(_tmpBuf, inStr.data(), inStr.length());\n") + stream.write(" ::qpid::framing::Buffer inBuf(_tmpBuf, inStr.length());\n") + for method in self.methods: stream.write ("\n if (methodName == \"" + method.getName () + "\") {\n") + stream.write (" _matched = true;\n") if method.getArgCount () == 0: stream.write (" ::qpid::management::ArgsNone ioArgs;\n") else: @@ -1131,7 +1374,43 @@ class SchemaClass: stream.write (" " +\ arg.type.type.getWriteCode ("ioArgs." +\ arg.dir.lower () + "_" +\ - arg.name, "outBuf") + ";\n") + arg.name, "outBuf") + ";\n") + stream.write(" }\n") + + if inArgs: + stream.write ("\n delete [] _tmpBuf;\n") + + + + def genMapMethodHandlers (self, stream, variables): + for method in self.methods: + stream.write ("\n if (methodName == \"" + method.getName () + "\") {\n") + if method.getArgCount () == 0: + stream.write (" ::qpid::management::ArgsNone ioArgs;\n") + else: + stream.write (" Args" + method.getFullName () + " ioArgs;\n") + stream.write (" ::qpid::types::Variant::Map::const_iterator _i;\n") + + # decode each input argument from the input map + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + arg.type.type.genUnmap(stream, + "ioArgs." + arg.dir.lower () + "_" + arg.name, + " ", + arg.name, + "inMap") + + stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ + method.getName().upper() + ", ioArgs, text);\n") + stream.write (" outMap[\"_status_code\"] = (uint32_t) status;\n") + stream.write (" outMap[\"_status_text\"] = ::qpid::management::Manageable::StatusText(status, text);\n") + for arg in method.args: + if arg.getDir () == "O" or arg.getDir () == "IO": + arg.type.type.genMap(stream, + "ioArgs." + arg.dir.lower () + "_" + arg.name, + " ", + arg.name, + "outMap") stream.write (" return;\n }\n") def genOpenNamespaces (self, stream, variables): @@ -1160,6 +1439,10 @@ class SchemaClass: for prop in self.properties: prop.genSchema (stream) + def genPropertySchemaMap (self, stream, variables): + for prop in self.properties: + prop.genSchemaMap(stream) + def genSetGeneralReferenceDeclaration (self, stream, variables): for prop in self.properties: if prop.isGeneralRef: @@ -1169,6 +1452,10 @@ class SchemaClass: for stat in self.statistics: stat.genSchema (stream) + def genStatisticSchemaMap (self, stream, variables): + for stat in self.statistics: + stat.genSchemaMap(stream) + def genMethodIdDeclarations (self, stream, variables): number = 1 for method in self.methods: @@ -1180,6 +1467,10 @@ class SchemaClass: for method in self.methods: method.genSchema (stream, variables) + def genMethodSchemaMap(self, stream, variables): + for method in self.methods: + method.genSchemaMap(stream, variables) + def genNameCap (self, stream, variables): stream.write (capitalize(self.name)) @@ -1241,6 +1532,17 @@ class SchemaClass: for stat in self.statistics: stat.genWrite (stream) + def genMapEncodeProperties(self, stream, variables): + for prop in self.properties: + prop.genMap (stream) + + def genMapEncodeStatistics (self, stream, variables): + for stat in self.statistics: + stat.genMap (stream) + + def genMapDecodeProperties (self, stream, variables): + for prop in self.properties: + prop.genUnmap (stream) class SchemaEventArgs: def __init__(self, package, node, typespec, fragments, options): diff --git a/qpid/cpp/managementgen/qmfgen/templates/Args.h b/qpid/cpp/managementgen/qmfgen/templates/Args.h index 074ccf9940..20681ab477 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Args.h +++ b/qpid/cpp/managementgen/qmfgen/templates/Args.h @@ -24,8 +24,8 @@ /*MGEN:Root.Disclaimer*/ #include "qpid/management/Args.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/framing/Uuid.h" +//#include "qpid/framing/FieldTable.h" +//#include "qpid/framing/Uuid.h" #include namespace qmf { diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp index e6362758ba..ed4e17720f 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp @@ -21,15 +21,15 @@ /*MGEN:Root.Disclaimer*/ #include "qpid/log/Statement.h" +#include "qpid/management/Manageable.h" #include "qpid/framing/FieldTable.h" -#include "qpid/management/Manageable.h" +#include "qpid/framing/Buffer.h" #include "qpid//*MGEN:Class.AgentHeaderLocation*//ManagementAgent.h" #include "/*MGEN:Class.NameCap*/.h" /*MGEN:Class.MethodArgIncludes*/ #include using namespace qmf::/*MGEN:Class.Namespace*/; -using namespace qpid::framing; using qpid::management::ManagementAgent; using qpid::management::Manageable; using qpid::management::ManagementObject; @@ -38,7 +38,7 @@ using std::string; string /*MGEN:Class.NameCap*/::packageName = string ("/*MGEN:Class.NamePackageLower*/"); string /*MGEN:Class.NameCap*/::className = string ("/*MGEN:Class.NameLower*/"); -uint8_t /*MGEN:Class.NameCap*/::md5Sum[16] = +uint8_t /*MGEN:Class.NameCap*/::md5Sum[MD5_LEN] = {/*MGEN:Class.SchemaMD5*/}; /*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (ManagementAgent*, Manageable* _core/*MGEN:Class.ParentArg*//*MGEN:Class.ConstructorArgs*/) : @@ -90,9 +90,12 @@ void /*MGEN:Class.NameCap*/::registerSelf(ManagementAgent* agent) agent->registerClass(packageName, className, md5Sum, writeSchema); } -void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) +void /*MGEN:Class.NameCap*/::writeSchema (std::string& schema) { - FieldTable ft; + const int _bufSize=65536; + char _msgChars[_bufSize]; + ::qpid::framing::Buffer buf(_msgChars, _bufSize); + ::qpid::framing::FieldTable ft; // Schema class header: buf.putOctet (CLASS_KIND_TABLE); @@ -109,10 +112,15 @@ void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) /*MGEN:Class.StatisticSchema*/ // Methods /*MGEN:Class.MethodSchema*/ + { + uint32_t _len = buf.getPosition(); + buf.reset(); + buf.getRawData(schema, _len); + } } /*MGEN:IF(Class.ExistPerThreadStats)*/ -void /*MGEN:Class.NameCap*/::aggregatePerThreadStats(struct PerThreadStats* totals) +void /*MGEN:Class.NameCap*/::aggregatePerThreadStats(struct PerThreadStats* totals) const { /*MGEN:Class.InitializeTotalPerThreadStats*/ for (int idx = 0; idx < maxThreads; idx++) { @@ -124,6 +132,7 @@ void /*MGEN:Class.NameCap*/::aggregatePerThreadStats(struct PerThreadStats* tota } /*MGEN:ENDIF*/ +/*MGEN:IF(Root.GenQMFv1)*/ uint32_t /*MGEN:Class.NameCap*/::writePropertiesSize() const { uint32_t size = writeTimestampsSize(); @@ -134,32 +143,62 @@ uint32_t /*MGEN:Class.NameCap*/::writePropertiesSize() const return size; } -void /*MGEN:Class.NameCap*/::readProperties (Buffer& buf) +void /*MGEN:Class.NameCap*/::readProperties (const std::string& _sBuf) { + char *_tmpBuf = new char[_sBuf.length()]; + memcpy(_tmpBuf, _sBuf.data(), _sBuf.length()); + ::qpid::framing::Buffer buf(_tmpBuf, _sBuf.length()); ::qpid::sys::Mutex::ScopedLock mutex(accessLock); - readTimestamps(buf); + + { + std::string _tbuf; + buf.getRawData(_tbuf, writeTimestampsSize()); + readTimestamps(_tbuf); + } + /*MGEN:IF(Class.ExistOptionals)*/ for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) presenceMask[idx] = buf.getOctet(); /*MGEN:ENDIF*/ /*MGEN:Class.ReadProperties*/ + + delete [] _tmpBuf; } -void /*MGEN:Class.NameCap*/::writeProperties (Buffer& buf) const +void /*MGEN:Class.NameCap*/::writeProperties (std::string& _sBuf) const { + const int _bufSize=65536; + char _msgChars[_bufSize]; + ::qpid::framing::Buffer buf(_msgChars, _bufSize); + ::qpid::sys::Mutex::ScopedLock mutex(accessLock); configChanged = false; - writeTimestamps (buf); + { + std::string _tbuf; + writeTimestamps(_tbuf); + buf.putRawData(_tbuf); + } + + /*MGEN:IF(Class.ExistOptionals)*/ for (uint8_t idx = 0; idx < /*MGEN:Class.PresenceMaskBytes*/; idx++) buf.putOctet(presenceMask[idx]); /*MGEN:ENDIF*/ /*MGEN:Class.WriteProperties*/ + + uint32_t _bufLen = buf.getPosition(); + buf.reset(); + + buf.getRawData(_sBuf, _bufLen); } -void /*MGEN:Class.NameCap*/::writeStatistics (Buffer& buf, bool skipHeaders) +void /*MGEN:Class.NameCap*/::writeStatistics (std::string& _sBuf, bool skipHeaders) { + const int _bufSize=65536; + char _msgChars[_bufSize]; + ::qpid::framing::Buffer buf(_msgChars, _bufSize); + ::qpid::sys::Mutex::ScopedLock mutex(accessLock); instChanged = false; /*MGEN:IF(Class.ExistPerThreadAssign)*/ @@ -175,8 +214,12 @@ void /*MGEN:Class.NameCap*/::writeStatistics (Buffer& buf, bool skipHeaders) aggregatePerThreadStats(&totals); /*MGEN:ENDIF*/ /*MGEN:Class.Assign*/ - if (!skipHeaders) - writeTimestamps (buf); + if (!skipHeaders) { + std::string _tbuf; + writeTimestamps (_tbuf); + buf.putRawData(_tbuf); + } + /*MGEN:Class.WriteStatistics*/ // Maintenance of hi-lo statistics @@ -189,6 +232,11 @@ void /*MGEN:Class.NameCap*/::writeStatistics (Buffer& buf, bool skipHeaders) } } /*MGEN:ENDIF*/ + + uint32_t _bufLen = buf.getPosition(); + buf.reset(); + + buf.getRawData(_sBuf, _bufLen); } void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) @@ -196,11 +244,25 @@ void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; std::string text; + bool _matched = false; + + const int _bufSize=65536; + char _msgChars[_bufSize]; + ::qpid::framing::Buffer outBuf(_msgChars, _bufSize); + /*MGEN:Class.MethodHandlers*/ - outBuf.putLong(status); - outBuf.putShortString(Manageable::StatusText(status, text)); -} + if (!_matched) { + outBuf.putLong(status); + outBuf.putShortString(Manageable::StatusText(status, text)); + } + + uint32_t _bufLen = outBuf.getPosition(); + outBuf.reset(); + + outBuf.getRawData(outStr, _bufLen); +} +/*MGEN:ENDIF*/ std::string /*MGEN:Class.NameCap*/::getKey() const { std::stringstream key; @@ -209,3 +271,67 @@ std::string /*MGEN:Class.NameCap*/::getKey() const return key.str(); } + + +void /*MGEN:Class.NameCap*/::mapEncodeValues (::qpid::types::Variant::Map& _map, + bool includeProperties, + bool includeStatistics) +{ + using namespace ::qpid::types; + ::qpid::sys::Mutex::ScopedLock mutex(accessLock); + + if (includeProperties) { + configChanged = false; +/*MGEN:Class.MapEncodeProperties*/ + } + + if (includeStatistics) { + instChanged = false; +/*MGEN:IF(Class.ExistPerThreadAssign)*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.PerThreadAssign*/ + } + } +/*MGEN:ENDIF*/ +/*MGEN:IF(Class.ExistPerThreadStats)*/ + struct PerThreadStats totals; + aggregatePerThreadStats(&totals); +/*MGEN:ENDIF*/ +/*MGEN:Class.Assign*/ + +/*MGEN:Class.MapEncodeStatistics*/ + + // Maintenance of hi-lo statistics +/*MGEN:Class.HiLoStatResets*/ +/*MGEN:IF(Class.ExistPerThreadResets)*/ + for (int idx = 0; idx < maxThreads; idx++) { + struct PerThreadStats* threadStats = perThreadStatsArray[idx]; + if (threadStats != 0) { +/*MGEN:Class.PerThreadHiLoStatResets*/ + } + } +/*MGEN:ENDIF*/ + } +} + +void /*MGEN:Class.NameCap*/::mapDecodeValues (const ::qpid::types::Variant::Map& _map) +{ + ::qpid::types::Variant::Map::const_iterator _i; + ::qpid::sys::Mutex::ScopedLock mutex(accessLock); +/*MGEN:IF(Class.ExistOptionals)*/ + bool _found; +/*MGEN:ENDIF*/ +/*MGEN:Class.MapDecodeProperties*/ +} + +void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMapMethodArgs*/) +{ + Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; + std::string text; + +/*MGEN:Class.MapMethodHandlers*/ + outMap["_status_code"] = (uint32_t) status; + outMap["_status_text"] = Manageable::StatusText(status, text); +} diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.h b/qpid/cpp/managementgen/qmfgen/templates/Class.h index 8efacd650f..cdb31c4c9e 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.h +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.h @@ -24,8 +24,6 @@ /*MGEN:Root.Disclaimer*/ #include "qpid/management/ManagementObject.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/framing/Uuid.h" namespace qpid { namespace management { @@ -42,7 +40,7 @@ class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject static std::string packageName; static std::string className; - static uint8_t md5Sum[16]; + static uint8_t md5Sum[MD5_LEN]; /*MGEN:IF(Class.ExistOptionals)*/ uint8_t presenceMask[/*MGEN:Class.PresenceMaskBytes*/]; /*MGEN:Class.PresenceMaskConstants*/ @@ -71,18 +69,28 @@ class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject return threadStats; } - void aggregatePerThreadStats(struct PerThreadStats*); + void aggregatePerThreadStats(struct PerThreadStats*) const; /*MGEN:ENDIF*/ public: - static void writeSchema(::qpid::framing::Buffer& buf); + static void writeSchema(std::string& schema); + void mapEncodeValues(::qpid::types::Variant::Map& map, + bool includeProperties=true, + bool includeStatistics=true); + void mapDecodeValues(const ::qpid::types::Variant::Map& map); + void doMethod(std::string& methodName, + const ::qpid::types::Variant::Map& inMap, + ::qpid::types::Variant::Map& outMap); + std::string getKey() const; +/*MGEN:IF(Root.GenQMFv1)*/ uint32_t writePropertiesSize() const; - void readProperties(::qpid::framing::Buffer& buf); - void writeProperties(::qpid::framing::Buffer& buf) const; - void writeStatistics(::qpid::framing::Buffer& buf, bool skipHeaders = false); + void readProperties(const std::string& buf); + void writeProperties(std::string& buf) const; + void writeStatistics(std::string& buf, bool skipHeaders = false); void doMethod(std::string& methodName, - ::qpid::framing::Buffer& inBuf, - ::qpid::framing::Buffer& outBuf); - std::string getKey() const; + const std::string& inBuf, + std::string& outBuf); +/*MGEN:ENDIF*/ + writeSchemaCall_t getWriteSchemaCall() { return writeSchema; } /*MGEN:IF(Class.NoStatistics)*/ // Stub for getInstChanged. There are no statistics in this class. diff --git a/qpid/cpp/managementgen/qmfgen/templates/Event.cpp b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp index a4fc28990d..d760fd9014 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Event.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp @@ -21,13 +21,13 @@ /*MGEN:Root.Disclaimer*/ #include "qpid/log/Statement.h" -#include "qpid/framing/FieldTable.h" #include "qpid/management/Manageable.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/framing/Buffer.h" #include "qpid//*MGEN:Event.AgentHeaderLocation*//ManagementAgent.h" #include "Event/*MGEN:Event.NameCap*/.h" using namespace qmf::/*MGEN:Event.Namespace*/; -using namespace qpid::framing; using qpid::management::ManagementAgent; using qpid::management::Manageable; using qpid::management::ManagementObject; @@ -56,23 +56,45 @@ void Event/*MGEN:Event.NameCap*/::registerSelf(ManagementAgent* agent) agent->registerEvent(packageName, eventName, md5Sum, writeSchema); } -void Event/*MGEN:Event.NameCap*/::writeSchema (Buffer& buf) +void Event/*MGEN:Event.NameCap*/::writeSchema (std::string& schema) { - FieldTable ft; + const int _bufSize = 65536; + char _msgChars[_bufSize]; + ::qpid::framing::Buffer buf(_msgChars, _bufSize); + ::qpid::framing::FieldTable ft; // Schema class header: buf.putOctet (CLASS_KIND_EVENT); buf.putShortString (packageName); // Package Name buf.putShortString (eventName); // Event Name buf.putBin128 (md5Sum); // Schema Hash - buf.putOctet (0); // No Superclass buf.putShort (/*MGEN:Event.ArgCount*/); // Argument Count // Arguments /*MGEN:Event.ArgSchema*/ + { + uint32_t _len = buf.getPosition(); + buf.reset(); + buf.getRawData(schema, _len); + } } -void Event/*MGEN:Event.NameCap*/::encode(::qpid::framing::Buffer& buf) const +void Event/*MGEN:Event.NameCap*/::encode(std::string& _sBuf) const { + const int _bufSize=65536; + char _msgChars[_bufSize]; + ::qpid::framing::Buffer buf(_msgChars, _bufSize); + /*MGEN:Event.ArgEncodes*/ + + uint32_t _bufLen = buf.getPosition(); + buf.reset(); + + buf.getRawData(_sBuf, _bufLen); +} + +void Event/*MGEN:Event.NameCap*/::mapEncode(::qpid::types::Variant::Map& map) const +{ + using namespace ::qpid::types; +/*MGEN:Event.ArgMap*/ } diff --git a/qpid/cpp/managementgen/qmfgen/templates/Event.h b/qpid/cpp/managementgen/qmfgen/templates/Event.h index b5c2a211d1..4f912cf220 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Event.h +++ b/qpid/cpp/managementgen/qmfgen/templates/Event.h @@ -24,8 +24,6 @@ /*MGEN:Root.Disclaimer*/ #include "qpid/management/ManagementEvent.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/framing/Uuid.h" namespace qmf { /*MGEN:Event.OpenNamespaces*/ @@ -33,10 +31,10 @@ namespace qmf { class Event/*MGEN:Event.NameCap*/ : public ::qpid::management::ManagementEvent { private: - static void writeSchema (::qpid::framing::Buffer& buf); + static void writeSchema (std::string& schema); static std::string packageName; static std::string eventName; - static uint8_t md5Sum[16]; + static uint8_t md5Sum[MD5_LEN]; /*MGEN:Event.ArgDeclarations*/ @@ -51,7 +49,8 @@ class Event/*MGEN:Event.NameCap*/ : public ::qpid::management::ManagementEvent std::string& getEventName() const { return eventName; } uint8_t* getMd5Sum() const { return md5Sum; } uint8_t getSeverity() const { return /*MGEN:Event.Severity*/; } - void encode(::qpid::framing::Buffer& buffer) const; + void encode(std::string& buffer) const; + void mapEncode(::qpid::types::Variant::Map& map) const; }; }/*MGEN:Event.CloseNamespaces*/ -- cgit v1.2.1 From 5f4ccf5da76ae6ebfdd3252ed6f865e0a72fd745 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Fri, 9 Apr 2010 03:53:30 +0000 Subject: QPID-2489 - Remove references to boost:: and qpid::framing:: from QMF-generated cpp files Added a wrapper class for framing::Buffer in the qpid::management namespace. This wrapper class has no reference to framing or boost and is now used in the generated C++ code to encode QMFv1 content. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@932236 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/management-types.xml | 29 +++++----- qpid/cpp/managementgen/qmfgen/schema.py | 62 +++++++++++----------- qpid/cpp/managementgen/qmfgen/templates/Args.h | 2 - qpid/cpp/managementgen/qmfgen/templates/Class.cpp | 17 +++--- qpid/cpp/managementgen/qmfgen/templates/Event.cpp | 11 ++-- 5 files changed, 62 insertions(+), 59 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/management-types.xml b/qpid/cpp/managementgen/qmfgen/management-types.xml index 857f8af212..61c91fed2d 100644 --- a/qpid/cpp/managementgen/qmfgen/management-types.xml +++ b/qpid/cpp/managementgen/qmfgen/management-types.xml @@ -24,9 +24,9 @@ --> + encode="{std::string _s; #.encode(_s); @.putRawData(_s);}" + decode="{std::string _s; @.getRawData(_s, #.encodedSize()); #.decode(_s);}" + stream="#.getV2Key()" size="16" accessor="direct" init="::qpid::management::ObjectId()" byRef="y"/> @@ -43,18 +43,21 @@ stream="#.getV2Key()" size="16" accessor="direct" init="::qpid::management::Obje + encode="@.putRawData(#.data(), 16)" + decode="{ unsigned char d[16]; @.getRawData(d, 16); # = ::qpid::types::Uuid(d); }" + stream="#" size="16" accessor="direct" init="::qpid::types::Uuid()" byRef="y" + unmap="(#).asUuid().data()" + map="::qpid::types::Uuid((#).data())" /> + encode="@.putMap(#)" + decode="@.getMap(#)" + size="::qpid::amqp_0_10::MapCodec::encodedSize(#)" + stream="#" accessor="direct" init="::qpid::types::Variant::Map()" byRef="y" unmap="::qpid::types::Variant::Map(); assert(false); /*TBD*/"/> + encode="@.putList(#)" + decode="@.getList(#)" + size="::qpid::amqp_0_10::ListCodec::encodedSize(#)" + stream="#" accessor="direct" init="::qpid::types::Variant::List()" byRef="y" unmap="::qpid::types::Variant::List(); assert(false); /*TBD*/"/> diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index c1bb507d84..1206b0082d 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -425,22 +425,22 @@ class SchemaProperty: def genSchema (self, stream): stream.write (" ft.clear();\n") - stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") - stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") - stream.write (" ft.setInt (ACCESS, ACCESS_" + self.access + ");\n") - stream.write (" ft.setInt (IS_INDEX, " + str (self.isIndex) + ");\n") - stream.write (" ft.setInt (IS_OPTIONAL, " + str (self.isOptional) + ");\n") + stream.write (" ft[NAME] = \"" + self.name + "\";\n") + stream.write (" ft[TYPE] = TYPE_" + self.type.type.base +";\n") + stream.write (" ft[ACCESS] = ACCESS_" + self.access + ";\n") + stream.write (" ft[IS_INDEX] = " + str (self.isIndex) + ";\n") + stream.write (" ft[IS_OPTIONAL] = " + str (self.isOptional) + ";\n") if self.unit != None: - stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + stream.write (" ft[UNIT] = \"" + self.unit + "\";\n") if self.min != None: - stream.write (" ft.setInt (MIN, " + self.min + ");\n") + stream.write (" ft[MIN] = " + self.min + ";\n") if self.max != None: - stream.write (" ft.setInt (MAX, " + self.max + ");\n") + stream.write (" ft[MAX] = " + self.max + ";\n") if self.maxLen != None: - stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") + stream.write (" ft[MAXLEN] = " + self.maxLen + ";\n") if self.desc != None: - stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") - stream.write (" buf.put (ft);\n\n") + stream.write (" ft[DESC] = \"" + self.desc + "\";\n") + stream.write (" buf.putMap(ft);\n\n") def genSchemaMap(self, stream): @@ -594,13 +594,13 @@ class SchemaStatistic: def genSchemaText (self, stream, name, desc): stream.write (" ft.clear();\n") - stream.write (" ft.setString (NAME, \"" + name + "\");\n") - stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + stream.write (" ft[NAME] = \"" + name + "\";\n") + stream.write (" ft[TYPE] = TYPE_" + self.type.type.base +";\n") if self.unit != None: - stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + stream.write (" ft[UNIT] = \"" + self.unit + "\";\n") if desc != None: - stream.write (" ft.setString (DESC, \"" + desc + "\");\n") - stream.write (" buf.put (ft);\n\n") + stream.write (" ft[DESC] = \"" + desc + "\";\n") + stream.write (" buf.putMap(ft);\n\n") def genSchemaTextMap(self, stream, name, desc): stream.write (" {\n") @@ -782,24 +782,24 @@ class SchemaArg: def genSchema (self, stream, event=False): stream.write (" ft.clear();\n") - stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") - stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + stream.write (" ft[NAME] = \"" + self.name + "\";\n") + stream.write (" ft[TYPE] = TYPE_" + self.type.type.base +";\n") if (not event): - stream.write (" ft.setString (DIR, \"" + self.dir + "\");\n") + stream.write (" ft[DIR] = \"" + self.dir + "\";\n") if self.unit != None: - stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + stream.write (" ft[UNIT] = \"" + self.unit + "\";\n") if not event: if self.min != None: - stream.write (" ft.setInt (MIN, " + self.min + ");\n") + stream.write (" ft[MIN] = " + self.min + ";\n") if self.max != None: - stream.write (" ft.setInt (MAX, " + self.max + ");\n") + stream.write (" ft[MAX] = " + self.max + ";\n") if self.maxLen != None: - stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") + stream.write (" ft[MAXLEN] = " + self.maxLen + ";\n") if self.default != None: - stream.write (" ft.setString (DEFAULT, \"" + self.default + "\");\n") + stream.write (" ft[DEFAULT] = \"" + self.default + "\";\n") if self.desc != None: - stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") - stream.write (" buf.put (ft);\n\n") + stream.write (" ft[DESC] = \"" + self.desc + "\";\n") + stream.write (" buf.putMap(ft);\n\n") def genSchemaMap (self, stream, event=False): stream.write (" {\n") @@ -896,11 +896,11 @@ class SchemaMethod: def genSchema (self, stream, variables): stream.write (" ft.clear();\n") - stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") - stream.write (" ft.setInt (ARGCOUNT, " + str (len (self.args)) + ");\n") + stream.write (" ft[NAME] = \"" + self.name + "\";\n") + stream.write (" ft[ARGCOUNT] = " + str (len (self.args)) + ";\n") if self.desc != None: - stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") - stream.write (" buf.put (ft);\n\n") + stream.write (" ft[DESC] = \"" + self.desc + "\";\n") + stream.write (" buf.putMap(ft);\n\n") for arg in self.args: arg.genSchema (stream) @@ -1349,7 +1349,7 @@ class SchemaClass: stream.write("\n") stream.write(" char *_tmpBuf = new char[inStr.length()];\n") stream.write(" memcpy(_tmpBuf, inStr.data(), inStr.length());\n") - stream.write(" ::qpid::framing::Buffer inBuf(_tmpBuf, inStr.length());\n") + stream.write(" ::qpid::management::Buffer inBuf(_tmpBuf, inStr.length());\n") for method in self.methods: stream.write ("\n if (methodName == \"" + method.getName () + "\") {\n") diff --git a/qpid/cpp/managementgen/qmfgen/templates/Args.h b/qpid/cpp/managementgen/qmfgen/templates/Args.h index 20681ab477..89a5bec9b9 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Args.h +++ b/qpid/cpp/managementgen/qmfgen/templates/Args.h @@ -24,8 +24,6 @@ /*MGEN:Root.Disclaimer*/ #include "qpid/management/Args.h" -//#include "qpid/framing/FieldTable.h" -//#include "qpid/framing/Uuid.h" #include namespace qmf { diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp index ed4e17720f..9a9af07b28 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp @@ -22,8 +22,9 @@ #include "qpid/log/Statement.h" #include "qpid/management/Manageable.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/framing/Buffer.h" +#include "qpid/management/Buffer.h" +#include "qpid/types/Variant.h" +#include "qpid/amqp_0_10/Codecs.h" #include "qpid//*MGEN:Class.AgentHeaderLocation*//ManagementAgent.h" #include "/*MGEN:Class.NameCap*/.h" /*MGEN:Class.MethodArgIncludes*/ @@ -94,8 +95,8 @@ void /*MGEN:Class.NameCap*/::writeSchema (std::string& schema) { const int _bufSize=65536; char _msgChars[_bufSize]; - ::qpid::framing::Buffer buf(_msgChars, _bufSize); - ::qpid::framing::FieldTable ft; + ::qpid::management::Buffer buf(_msgChars, _bufSize); + ::qpid::types::Variant::Map ft; // Schema class header: buf.putOctet (CLASS_KIND_TABLE); @@ -147,7 +148,7 @@ void /*MGEN:Class.NameCap*/::readProperties (const std::string& _sBuf) { char *_tmpBuf = new char[_sBuf.length()]; memcpy(_tmpBuf, _sBuf.data(), _sBuf.length()); - ::qpid::framing::Buffer buf(_tmpBuf, _sBuf.length()); + ::qpid::management::Buffer buf(_tmpBuf, _sBuf.length()); ::qpid::sys::Mutex::ScopedLock mutex(accessLock); { @@ -169,7 +170,7 @@ void /*MGEN:Class.NameCap*/::writeProperties (std::string& _sBuf) const { const int _bufSize=65536; char _msgChars[_bufSize]; - ::qpid::framing::Buffer buf(_msgChars, _bufSize); + ::qpid::management::Buffer buf(_msgChars, _bufSize); ::qpid::sys::Mutex::ScopedLock mutex(accessLock); configChanged = false; @@ -197,7 +198,7 @@ void /*MGEN:Class.NameCap*/::writeStatistics (std::string& _sBuf, bool skipHeade { const int _bufSize=65536; char _msgChars[_bufSize]; - ::qpid::framing::Buffer buf(_msgChars, _bufSize); + ::qpid::management::Buffer buf(_msgChars, _bufSize); ::qpid::sys::Mutex::ScopedLock mutex(accessLock); instChanged = false; @@ -248,7 +249,7 @@ void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) const int _bufSize=65536; char _msgChars[_bufSize]; - ::qpid::framing::Buffer outBuf(_msgChars, _bufSize); + ::qpid::management::Buffer outBuf(_msgChars, _bufSize); /*MGEN:Class.MethodHandlers*/ diff --git a/qpid/cpp/managementgen/qmfgen/templates/Event.cpp b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp index d760fd9014..94de331611 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Event.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp @@ -22,8 +22,9 @@ #include "qpid/log/Statement.h" #include "qpid/management/Manageable.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/framing/Buffer.h" +#include "qpid/management/Buffer.h" +#include "qpid/types/Variant.h" +#include "qpid/amqp_0_10/Codecs.h" #include "qpid//*MGEN:Event.AgentHeaderLocation*//ManagementAgent.h" #include "Event/*MGEN:Event.NameCap*/.h" @@ -60,8 +61,8 @@ void Event/*MGEN:Event.NameCap*/::writeSchema (std::string& schema) { const int _bufSize = 65536; char _msgChars[_bufSize]; - ::qpid::framing::Buffer buf(_msgChars, _bufSize); - ::qpid::framing::FieldTable ft; + ::qpid::management::Buffer buf(_msgChars, _bufSize); + ::qpid::types::Variant::Map ft; // Schema class header: buf.putOctet (CLASS_KIND_EVENT); @@ -83,7 +84,7 @@ void Event/*MGEN:Event.NameCap*/::encode(std::string& _sBuf) const { const int _bufSize=65536; char _msgChars[_bufSize]; - ::qpid::framing::Buffer buf(_msgChars, _bufSize); + ::qpid::management::Buffer buf(_msgChars, _bufSize); /*MGEN:Event.ArgEncodes*/ -- cgit v1.2.1 From e3c5ebca4152d1753f714c6b2d62485a2ef4d288 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Fri, 9 Apr 2010 17:19:32 +0000 Subject: QPID-2489 - Added wrapped version of Mutex to isolate QMF-generated source from boost. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@932517 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/schema.py | 8 ++++---- qpid/cpp/managementgen/qmfgen/templates/Class.cpp | 12 ++++++------ qpid/cpp/managementgen/qmfgen/templates/Event.cpp | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index 1206b0082d..ec0ccc3462 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -148,7 +148,7 @@ class SchemaType: if self.accessor == "direct": stream.write (" inline void set_" + varName + " (" + self.asArg + " val) {\n"); if not self.perThread: - stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" ::qpid::management::Mutex::ScopedLock mutex(accessLock);\n") if self.style != "mma": stream.write (" " + prefix + varName + " = val;\n") if optional: @@ -171,7 +171,7 @@ class SchemaType: if self.style != "mma": stream.write (" inline " + self.asArg + " get_" + varName + "() {\n"); if not self.perThread: - stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" ::qpid::management::Mutex::ScopedLock mutex(accessLock);\n") stream.write (" return " + prefix + varName + ";\n") stream.write (" }\n") if optional: @@ -186,7 +186,7 @@ class SchemaType: elif self.accessor == "counter": stream.write (" inline void inc_" + varName + " (" + self.asArg + " by = 1) {\n"); if not self.perThread: - stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" ::qpid::management::Mutex::ScopedLock mutex(accessLock);\n") stream.write (" " + prefix + varName + " += by;\n") if self.style == "wm": stream.write (" if (" + varName + "High < " + varName + ")\n") @@ -196,7 +196,7 @@ class SchemaType: stream.write (" }\n"); stream.write (" inline void dec_" + varName + " (" + self.asArg + " by = 1) {\n"); if not self.perThread: - stream.write (" ::qpid::sys::Mutex::ScopedLock mutex(accessLock);\n") + stream.write (" ::qpid::management::Mutex::ScopedLock mutex(accessLock);\n") stream.write (" " + prefix + varName + " -= by;\n") if self.style == "wm": stream.write (" if (" + varName + "Low > " + varName + ")\n") diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp index 9a9af07b28..cfc142e18c 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp @@ -20,7 +20,6 @@ /*MGEN:Root.Disclaimer*/ -#include "qpid/log/Statement.h" #include "qpid/management/Manageable.h" #include "qpid/management/Buffer.h" #include "qpid/types/Variant.h" @@ -35,6 +34,7 @@ using qpid::management::ManagementAgent; using qpid::management::Manageable; using qpid::management::ManagementObject; using qpid::management::Args; +using qpid::management::Mutex; using std::string; string /*MGEN:Class.NameCap*/::packageName = string ("/*MGEN:Class.NamePackageLower*/"); @@ -149,7 +149,7 @@ void /*MGEN:Class.NameCap*/::readProperties (const std::string& _sBuf) char *_tmpBuf = new char[_sBuf.length()]; memcpy(_tmpBuf, _sBuf.data(), _sBuf.length()); ::qpid::management::Buffer buf(_tmpBuf, _sBuf.length()); - ::qpid::sys::Mutex::ScopedLock mutex(accessLock); + Mutex::ScopedLock mutex(accessLock); { std::string _tbuf; @@ -172,7 +172,7 @@ void /*MGEN:Class.NameCap*/::writeProperties (std::string& _sBuf) const char _msgChars[_bufSize]; ::qpid::management::Buffer buf(_msgChars, _bufSize); - ::qpid::sys::Mutex::ScopedLock mutex(accessLock); + Mutex::ScopedLock mutex(accessLock); configChanged = false; { @@ -200,7 +200,7 @@ void /*MGEN:Class.NameCap*/::writeStatistics (std::string& _sBuf, bool skipHeade char _msgChars[_bufSize]; ::qpid::management::Buffer buf(_msgChars, _bufSize); - ::qpid::sys::Mutex::ScopedLock mutex(accessLock); + Mutex::ScopedLock mutex(accessLock); instChanged = false; /*MGEN:IF(Class.ExistPerThreadAssign)*/ for (int idx = 0; idx < maxThreads; idx++) { @@ -279,7 +279,7 @@ void /*MGEN:Class.NameCap*/::mapEncodeValues (::qpid::types::Variant::Map& _map, bool includeStatistics) { using namespace ::qpid::types; - ::qpid::sys::Mutex::ScopedLock mutex(accessLock); + Mutex::ScopedLock mutex(accessLock); if (includeProperties) { configChanged = false; @@ -320,7 +320,7 @@ void /*MGEN:Class.NameCap*/::mapEncodeValues (::qpid::types::Variant::Map& _map, void /*MGEN:Class.NameCap*/::mapDecodeValues (const ::qpid::types::Variant::Map& _map) { ::qpid::types::Variant::Map::const_iterator _i; - ::qpid::sys::Mutex::ScopedLock mutex(accessLock); + Mutex::ScopedLock mutex(accessLock); /*MGEN:IF(Class.ExistOptionals)*/ bool _found; /*MGEN:ENDIF*/ diff --git a/qpid/cpp/managementgen/qmfgen/templates/Event.cpp b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp index 94de331611..a8fdd0bd92 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Event.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Event.cpp @@ -20,7 +20,6 @@ /*MGEN:Root.Disclaimer*/ -#include "qpid/log/Statement.h" #include "qpid/management/Manageable.h" #include "qpid/management/Buffer.h" #include "qpid/types/Variant.h" @@ -33,6 +32,7 @@ using qpid::management::ManagementAgent; using qpid::management::Manageable; using qpid::management::ManagementObject; using qpid::management::Args; +using qpid::management::Mutex; using std::string; string Event/*MGEN:Event.NameCap*/::packageName = string ("/*MGEN:Event.NamePackageLower*/"); -- cgit v1.2.1 From d00cc63a79f570ad2d953bc9d8009a4c688546a9 Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Wed, 14 Apr 2010 12:23:21 +0000 Subject: Fix testagent for changes in r933842 git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@933923 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/templates/Class.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp index cfc142e18c..fc0b9c8177 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.cpp @@ -28,6 +28,7 @@ #include "/*MGEN:Class.NameCap*/.h" /*MGEN:Class.MethodArgIncludes*/ #include +#include using namespace qmf::/*MGEN:Class.Namespace*/; using qpid::management::ManagementAgent; -- cgit v1.2.1 From ae2de91821f016a0a5cecb3b4e9953de6230a7f8 Mon Sep 17 00:00:00 2001 From: Kenneth Anthony Giusti Date: Wed, 14 Apr 2010 18:57:18 +0000 Subject: QPID-2506: enable map and list method arguments. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@934117 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/management-types.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/management-types.xml b/qpid/cpp/managementgen/qmfgen/management-types.xml index 61c91fed2d..f1f1351990 100644 --- a/qpid/cpp/managementgen/qmfgen/management-types.xml +++ b/qpid/cpp/managementgen/qmfgen/management-types.xml @@ -52,12 +52,12 @@ encode="@.putMap(#)" decode="@.getMap(#)" size="::qpid::amqp_0_10::MapCodec::encodedSize(#)" - stream="#" accessor="direct" init="::qpid::types::Variant::Map()" byRef="y" unmap="::qpid::types::Variant::Map(); assert(false); /*TBD*/"/> + stream="#" accessor="direct" init="::qpid::types::Variant::Map()" byRef="y" unmap="(#).asMap()"/> + stream="#" accessor="direct" init="::qpid::types::Variant::List()" byRef="y" unmap="(#).asList()"/> -- cgit v1.2.1 From 777c27588b4bdc5bf988174f785417bb0e54611d Mon Sep 17 00:00:00 2001 From: Kenneth Anthony Giusti Date: Tue, 20 Apr 2010 15:39:54 +0000 Subject: QMF: fix object name separator, use native bool type git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@935961 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/management-types.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/management-types.xml b/qpid/cpp/managementgen/qmfgen/management-types.xml index f1f1351990..c88f0caeae 100644 --- a/qpid/cpp/managementgen/qmfgen/management-types.xml +++ b/qpid/cpp/managementgen/qmfgen/management-types.xml @@ -35,7 +35,7 @@ - + -- cgit v1.2.1 From a349ccd5a819226cf70618fb170785e001d42cff Mon Sep 17 00:00:00 2001 From: Kenneth Anthony Giusti Date: Wed, 22 Sep 2010 12:48:00 +0000 Subject: clarify a comment git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@999916 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/schema.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index ec0ccc3462..f01d5ee9b2 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -1315,7 +1315,9 @@ class SchemaClass: def genPrimaryKey (self, stream, variables): first = 1 for prop in self.properties: - if prop.getName() != "vhostRef": # Limit how deep the v2Key strings get + # deliberately leave out the "vhostRef" fields since there's only one vhost, + # this serves to shorten the keys without compromising uniqueness + if prop.getName() != "vhostRef": if prop.isIndex == 1: if first: first = None -- cgit v1.2.1 From 4978d516e39c7862934bed5eb0cdcfb528f0390e Mon Sep 17 00:00:00 2001 From: Robert Gemmell Date: Sun, 31 Oct 2010 23:39:39 +0000 Subject: add ASF licence to various files in the cpp tree git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1029521 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake | 6 +++--- qpid/cpp/managementgen/qmfgen/templates/Makefile.mk | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake b/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake index 54f446a437..d8a3b91b10 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake +++ b/qpid/cpp/managementgen/qmfgen/templates/CMakeLists.cmake @@ -6,9 +6,9 @@ # 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 -# +# +# 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 diff --git a/qpid/cpp/managementgen/qmfgen/templates/Makefile.mk b/qpid/cpp/managementgen/qmfgen/templates/Makefile.mk index 2b32c7c0f2..b9adb4a2d2 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Makefile.mk +++ b/qpid/cpp/managementgen/qmfgen/templates/Makefile.mk @@ -6,9 +6,9 @@ # 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 -# +# +# 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 -- cgit v1.2.1 From 42d18e5791c0f79588d5264f2b0c96ee0a39c122 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Tue, 9 Nov 2010 21:15:03 +0000 Subject: QPID-2934 Feature to pass the authenticated userId to QMF agent method handlers for authorization git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1033232 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/schema.py | 26 +++++++++++++++++-------- qpid/cpp/managementgen/qmfgen/templates/Class.h | 6 ++++-- 2 files changed, 22 insertions(+), 10 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index f01d5ee9b2..fdbc7c7be8 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -1228,12 +1228,12 @@ class SchemaClass: inArgCount = inArgCount + 1 if methodCount == 0: - stream.write ("string&, const string&, string& outStr") + stream.write ("string&, const string&, string& outStr, const string&") else: if inArgCount == 0: - stream.write ("string& methodName, const string&, string& outStr") + stream.write ("string& methodName, const string&, string& outStr, const string& userId") else: - stream.write ("string& methodName, const string& inStr, string& outStr") + stream.write ("string& methodName, const string& inStr, string& outStr, const string& userId") def genDoMapMethodArgs (self, stream, variables): @@ -1248,16 +1248,16 @@ class SchemaClass: if methodCount == 0: stream.write ("string&," + " const ::qpid::types::Variant::Map&," + - " ::qpid::types::Variant::Map& outMap") + " ::qpid::types::Variant::Map& outMap, const string&") else: if inArgCount == 0: stream.write ("string& methodName," + " const ::qpid::types::Variant::Map&," + - " ::qpid::types::Variant::Map& outMap") + " ::qpid::types::Variant::Map& outMap, const string& userId") else: stream.write ("string& methodName," + " const ::qpid::types::Variant::Map& inMap," + - " ::qpid::types::Variant::Map& outMap") + " ::qpid::types::Variant::Map& outMap, const string& userId") def genHiLoStatResets (self, stream, variables): for inst in self.statistics: @@ -1367,8 +1367,13 @@ class SchemaClass: arg.dir.lower () + "_" +\ arg.name, "inBuf") + ";\n") - stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ + stream.write (" bool allow = coreObject->AuthorizeMethod(METHOD_" +\ + method.getName().upper() + ", ioArgs, userId);\n") + stream.write (" if (allow)\n") + stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ method.getName().upper() + ", ioArgs, text);\n") + stream.write (" else\n") + stream.write (" status = Manageable::STATUS_FORBIDDEN;\n") stream.write (" outBuf.putLong (status);\n") stream.write (" outBuf.putMediumString(::qpid::management::Manageable::StatusText (status, text));\n") for arg in method.args: @@ -1402,8 +1407,13 @@ class SchemaClass: arg.name, "inMap") - stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ + stream.write (" bool allow = coreObject->AuthorizeMethod(METHOD_" +\ + method.getName().upper() + ", ioArgs, userId);\n") + stream.write (" if (allow)\n") + stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ method.getName().upper() + ", ioArgs, text);\n") + stream.write (" else\n") + stream.write (" status = Manageable::STATUS_FORBIDDEN;\n") stream.write (" outMap[\"_status_code\"] = (uint32_t) status;\n") stream.write (" outMap[\"_status_text\"] = ::qpid::management::Manageable::StatusText(status, text);\n") for arg in method.args: diff --git a/qpid/cpp/managementgen/qmfgen/templates/Class.h b/qpid/cpp/managementgen/qmfgen/templates/Class.h index cdb31c4c9e..4bcd423a26 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/Class.h +++ b/qpid/cpp/managementgen/qmfgen/templates/Class.h @@ -79,7 +79,8 @@ class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject void mapDecodeValues(const ::qpid::types::Variant::Map& map); void doMethod(std::string& methodName, const ::qpid::types::Variant::Map& inMap, - ::qpid::types::Variant::Map& outMap); + ::qpid::types::Variant::Map& outMap, + const std::string& userId); std::string getKey() const; /*MGEN:IF(Root.GenQMFv1)*/ uint32_t writePropertiesSize() const; @@ -88,7 +89,8 @@ class /*MGEN:Class.NameCap*/ : public ::qpid::management::ManagementObject void writeStatistics(std::string& buf, bool skipHeaders = false); void doMethod(std::string& methodName, const std::string& inBuf, - std::string& outBuf); + std::string& outBuf, + const std::string& userId); /*MGEN:ENDIF*/ writeSchemaCall_t getWriteSchemaCall() { return writeSchema; } -- cgit v1.2.1 From 8ad734ad94e5fca9c358326496515943250a5ac5 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 15 Dec 2010 04:53:10 +0000 Subject: Added an option to the qmf-gen tool to generate v2-style schema declarations. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1049425 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/Makefile.am | 2 + qpid/cpp/managementgen/qmf-gen | 24 ++-- qpid/cpp/managementgen/qmfgen/generate.py | 19 +++ qpid/cpp/managementgen/qmfgen/schema.py | 139 +++++++++++++++++++++ .../managementgen/qmfgen/templates/V2Package.cpp | 37 ++++++ .../cpp/managementgen/qmfgen/templates/V2Package.h | 44 +++++++ 6 files changed, 257 insertions(+), 8 deletions(-) create mode 100644 qpid/cpp/managementgen/qmfgen/templates/V2Package.cpp create mode 100644 qpid/cpp/managementgen/qmfgen/templates/V2Package.h (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am index 7f85834093..6c2024ccaa 100644 --- a/qpid/cpp/managementgen/Makefile.am +++ b/qpid/cpp/managementgen/Makefile.am @@ -31,6 +31,8 @@ nobase_qmfpython_DATA = \ qmfgen/templates/Makefile.mk \ qmfgen/templates/Package.cpp \ qmfgen/templates/Package.h \ + qmfgen/templates/V2Package.cpp \ + qmfgen/templates/V2Package.h \ qmfgen/management-types.xml EXTRA_DIST = $(nobase_qmfpython_DATA) CMakeLists.txt diff --git a/qpid/cpp/managementgen/qmf-gen b/qpid/cpp/managementgen/qmf-gen index 667aa1ba2d..6e8f864256 100755 --- a/qpid/cpp/managementgen/qmf-gen +++ b/qpid/cpp/managementgen/qmf-gen @@ -47,12 +47,15 @@ parser.add_option("-q", "--qpid-broker", dest="qpidbroker", default=False, actio help="Generate makefile for Qpid broker") parser.add_option("-b", "--broker-plugin", dest="brokerplugin", default=False, action="store_true", help="Generate code for use in a qpid broker plugin") +parser.add_option("-2", "--v2-style", dest="v2_style", default=False, action="store_true", + help="Generate code for use with the QMFv2 Agent API") (opts, args) = parser.parse_args() typefile = opts.typefile templatedir = opts.templatedir outdir = opts.outputdir +v2_style = opts.v2_style gen = Generator(outdir, templatedir) if len(args) == 0: @@ -70,14 +73,19 @@ else: for schemafile in args: package = SchemaPackage(typefile, schemafile, opts) - gen.setPackage (package.packageName) - gen.makeClassFiles ("Class.h", package, vars=vargs) - gen.makeClassFiles ("Class.cpp", package, vars=vargs) - gen.makeMethodFiles ("Args.h", package, vars=vargs) - gen.makeEventFiles ("Event.h", package, vars=vargs) - gen.makeEventFiles ("Event.cpp", package, vars=vargs) - gen.makePackageFile ("Package.h", package, vars=vargs) - gen.makePackageFile ("Package.cpp", package, vars=vargs) + gen.setPackage(package.packageName) + + if v2_style: + gen.makeV2PackageFile("V2Package.h", package, vars=vargs) + gen.makeV2PackageFile("V2Package.cpp", package, vars=vargs) + else: + gen.makeClassFiles ("Class.h", package, vars=vargs) + gen.makeClassFiles ("Class.cpp", package, vars=vargs) + gen.makeMethodFiles ("Args.h", package, vars=vargs) + gen.makeEventFiles ("Event.h", package, vars=vargs) + gen.makeEventFiles ("Event.cpp", package, vars=vargs) + gen.makePackageFile ("Package.h", package, vars=vargs) + gen.makePackageFile ("Package.cpp", package, vars=vargs) if opts.makefile != None: args = {} diff --git a/qpid/cpp/managementgen/qmfgen/generate.py b/qpid/cpp/managementgen/qmfgen/generate.py index 8a00b69761..4e688e3bc7 100755 --- a/qpid/cpp/managementgen/qmfgen/generate.py +++ b/qpid/cpp/managementgen/qmfgen/generate.py @@ -346,6 +346,14 @@ class Generator: path = self.packagePath + "Package" + extension return path + def targetV2PackageFile (self, schema, templateFile): + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + extension = templateFile[dot:len (templateFile)] + path = self.packagePath + "QmfPackage" + extension + return path + def targetClassFile (self, _class, templateFile): dot = templateFile.find(".") if dot == -1: @@ -448,6 +456,17 @@ class Generator: stream = template.expand (schema) self.writeIfChanged (stream, target, force) + def makeV2PackageFile (self, templateFile, schema, force=False, vars=None): + """ Generate a QMFv2 package definition file """ + template = Template (self.input + templateFile, self) + if vars: + for arg in vars: + self.setVariable(arg, vars[arg]) + self.templateFiles.append (templateFile) + target = self.targetV2PackageFile (schema, templateFile) + stream = template.expand (schema) + self.writeIfChanged (stream, target, force) + def makeSingleFile (self, templateFile, target, force=False, vars=None): """ Generate a single expanded template """ dot = templateFile.find(".") diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index fdbc7c7be8..afdfe42639 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -1483,6 +1483,9 @@ class SchemaClass: for method in self.methods: method.genSchemaMap(stream, variables) + def genName (self, stream, variables): + stream.write (self.name) + def genNameCap (self, stream, variables): stream.write (capitalize(self.name)) @@ -1647,6 +1650,9 @@ class SchemaPackage: up = "_".join(self.packageName.split(".")) stream.write (up.upper()) + def genPackageName (self, stream, variables): + stream.write(self.packageName) + def genNamePackageLower (self, stream, variables): stream.write (self.packageName.lower ()) @@ -1670,6 +1676,139 @@ class SchemaPackage: _event.genNameCap(stream, variables) stream.write("::registerSelf(agent);\n") + def genV2ClassMembers(self, stream, variables): + for _class in self.classes: + stream.write(" ::qmf::Schema data_%s;\n" % _class.name) + for _event in self.events: + stream.write(" ::qmf::Schema event_%s;\n" % _event.name) + + def genV2ClassDefines(self, stream, variables): + for _class in self.classes: + stream.write("\n //\n // Data: %s\n //\n" % _class.name) + stream.write(" data_%s = qmf::Schema(SCHEMA_TYPE_DATA, package, \"%s\");\n" % (_class.name, _class.name)) + + for prop in _class.properties: + typeName, subType = self.qmfv2Type(prop.type) + access = self.qmfv2Access(prop.access) + stream.write(" {\n") + stream.write(" qmf::SchemaProperty prop(\"%s\", %s);\n" % (prop.name, typeName)) + if subType: + stream.write(" prop.setSubtype(\"%s\");\n" % subType) + stream.write(" prop.setAccess(%s);\n" % access) + if prop.isIndex == 1: + stream.write(" prop.setIndex(true);\n") + if prop.isOptional == 1: + stream.write(" prop.setOptional(true);\n") + if prop.unit: + stream.write(" prop.setUnit(\"%s\");\n" % prop.unit) + if prop.desc: + stream.write(" prop.setDesc(\"%s\");\n" % prop.desc) + stream.write(" data_%s.addProperty(prop);\n" % _class.name) + stream.write(" }\n\n") + + for stat in _class.statistics: + typeName, subType = self.qmfv2Type(stat.type) + stream.write(" {\n") + stream.write(" qmf::SchemaProperty prop(\"%s\", %s);\n" % (stat.name, typeName)) + if subType: + stream.write(" prop.setSubtype(\"%s\");\n" % subType) + if stat.unit: + stream.write(" prop.setUnit(\"%s\");\n" % stat.unit) + if stat.desc: + stream.write(" prop.setDesc(\"%s\");\n" % stat.desc) + stream.write(" data_%s.addProperty(prop);\n" % _class.name) + stream.write(" }\n\n") + + for method in _class.methods: + stream.write(" {\n") + stream.write(" qmf::SchemaMethod method(\"%s\");\n" % method.name) + if method.desc: + stream.write(" method.setDesc(\"%s\");\n" % method.desc) + + for arg in method.args: + typeName, subType = self.qmfv2Type(arg.type) + stream.write(" {\n") + stream.write(" qmf::SchemaProperty arg(\"%s\", %s);\n" % (arg.name, typeName)) + if subType: + stream.write(" arg.setSubtype(\"%s\");\n" % subType) + if stat.unit: + stream.write(" arg.setUnit(\"%s\");\n" % arg.unit) + if stat.desc: + stream.write(" arg.setDesc(\"%s\");\n" % arg.desc) + stream.write(" arg.setDirection(%s);\n" % self.qmfv2Dir(arg.dir)) + stream.write(" method.addArgument(arg);\n") + stream.write(" }\n\n") + + stream.write(" data_%s.addMethod(method);\n" % _class.name) + stream.write(" }\n\n") + + stream.write(" session.registerSchema(data_%s);\n" % _class.name) + + for _event in self.events: + stream.write("\n //\n // Event: %s\n //\n" % _event.name) + stream.write(" event_%s = qmf::Schema(SCHEMA_TYPE_EVENT, package, \"%s\");\n" % (_event.name, _event.name)) + stream.write(" event_%s.setDefaultSeverity(%s);\n" % (_event.name, self.qmfv2Severity(_event.sev))) + for prop in _event.args: + typeName, subType = self.qmfv2Type(prop.type) + stream.write(" {\n") + stream.write(" qmf::SchemaProperty prop(\"%s\", %s);\n" % (prop.name, typeName)) + if subType: + stream.write(" prop.setSubtype(\"%s\");\n" % subType) + if prop.unit: + stream.write(" prop.setUnit(\"%s\");\n" % prop.unit) + if prop.desc: + stream.write(" prop.setDesc(\"%s\");\n" % prop.desc) + stream.write(" event_%s.addProperty(prop);\n" % _event.name) + stream.write(" }\n\n") + + stream.write(" session.registerSchema(event_%s);\n" % _event.name) + + + def qmfv2Type(self, typecode): + base = typecode.type.base + if base == "REF" : return ("qmf::SCHEMA_DATA_MAP", "reference") + if base == "U8" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "U16" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "U32" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "U64" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "S8" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "S16" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "S32" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "S64" : return ("qmf::SCHEMA_DATA_INT", None) + if base == "BOOL" : return ("qmf::SCHEMA_DATA_BOOL", None) + if base == "SSTR" : return ("qmf::SCHEMA_DATA_STRING", None) + if base == "LSTR" : return ("qmf::SCHEMA_DATA_STRING", None) + if base == "ABSTIME" : return ("qmf::SCHEMA_DATA_INT", "abstime") + if base == "DELTATIME" : return ("qmf::SCHEMA_DATA_INT", "deltatime") + if base == "FLOAT" : return ("qmf::SCHEMA_DATA_FLOAT", None) + if base == "DOUBLE" : return ("qmf::SCHEMA_DATA_FLOAT", None) + if base == "UUID" : return ("qmf::SCHEMA_DATA_UUID", None) + if base == "FTABLE" : return ("qmf::SCHEMA_DATA_MAP", None) + if base == "LIST" : return ("qmf::SCHEMA_DATA_LIST", None) + raise ValueError("Unknown base type %s" % base) + + def qmfv2Access(self, code): + if code == "RC": return "qmf::ACCESS_READ_CREATE" + if code == "RO": return "qmf::ACCESS_READ_ONLY" + if code == "RW": return "qmf::ACCESS_READ_WRITE" + raise ValueError("Unknown access type %s" % code) + + def qmfv2Dir(self, code): + if code == "I" : return "qmf::DIR_IN" + if code == "O" : return "qmf::DIR_OUT" + if code == "IO": return "qmf::DIR_IN_OUT" + raise ValueError("Unknown direction type %s" % code) + + def qmfv2Severity(self, code): + if code == 0 : return "qmf::SEV_EMERG" + if code == 1 : return "qmf::SEV_ALERT" + if code == 2 : return "qmf::SEV_CRIT" + if code == 3 : return "qmf::SEV_ERROR" + if code == 4 : return "qmf::SEV_WARN" + if code == 5 : return "qmf::SEV_NOTICE" + if code == 6 : return "qmf::SEV_INFORM" + if code == 7 : return "qmf::SEV_DEBUG" + raise ValueError("Out of Range Severity %d" % code) #===================================================================================== # Utility Functions diff --git a/qpid/cpp/managementgen/qmfgen/templates/V2Package.cpp b/qpid/cpp/managementgen/qmfgen/templates/V2Package.cpp new file mode 100644 index 0000000000..2c87805bdb --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/V2Package.cpp @@ -0,0 +1,37 @@ +/*MGEN:commentPrefix=//*/ +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "QmfPackage.h" +#include +#include +#include +#include + +using namespace std; +using namespace qmf::/*MGEN:Schema.Namespace*/; + +PackageDefinition::PackageDefinition(::qmf::AgentSession& session) +{ + string package("/*MGEN:Schema.PackageName*/"); +/*MGEN:Schema.V2ClassDefines*/ +} + diff --git a/qpid/cpp/managementgen/qmfgen/templates/V2Package.h b/qpid/cpp/managementgen/qmfgen/templates/V2Package.h new file mode 100644 index 0000000000..663a69ac86 --- /dev/null +++ b/qpid/cpp/managementgen/qmfgen/templates/V2Package.h @@ -0,0 +1,44 @@ +/*MGEN:commentPrefix=//*/ +#ifndef _QMF_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ +#define _QMF_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_ + +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include +#include + +namespace qmf { +/*MGEN:Class.OpenNamespaces*/ + +class PackageDefinition +{ + public: + PackageDefinition (::qmf::AgentSession& session); + ~PackageDefinition () {} + +/*MGEN:Schema.V2ClassMembers*/ +}; + +}/*MGEN:Class.CloseNamespaces*/ + + +#endif /*!_QMF_PACKAGE_/*MGEN:Schema.PackageNameUpper*/_*/ -- cgit v1.2.1 From adad1797bc8e7427742d76baf52b32d5b29d85b5 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Thu, 16 Dec 2010 00:22:19 +0000 Subject: Updates to the V2-style qmf-generation templates: 1) Added include directives in the .h template for convenience 2) Moved the schema-registration out of the class constructor and into a method. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1049754 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/templates/V2Package.cpp | 2 +- qpid/cpp/managementgen/qmfgen/templates/V2Package.h | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/templates/V2Package.cpp b/qpid/cpp/managementgen/qmfgen/templates/V2Package.cpp index 2c87805bdb..2b6e231fe9 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/V2Package.cpp +++ b/qpid/cpp/managementgen/qmfgen/templates/V2Package.cpp @@ -29,7 +29,7 @@ using namespace std; using namespace qmf::/*MGEN:Schema.Namespace*/; -PackageDefinition::PackageDefinition(::qmf::AgentSession& session) +void PackageDefinition::configure(::qmf::AgentSession& session) { string package("/*MGEN:Schema.PackageName*/"); /*MGEN:Schema.V2ClassDefines*/ diff --git a/qpid/cpp/managementgen/qmfgen/templates/V2Package.h b/qpid/cpp/managementgen/qmfgen/templates/V2Package.h index 663a69ac86..1d4f907ab3 100644 --- a/qpid/cpp/managementgen/qmfgen/templates/V2Package.h +++ b/qpid/cpp/managementgen/qmfgen/templates/V2Package.h @@ -25,6 +25,8 @@ #include #include +#include +#include namespace qmf { /*MGEN:Class.OpenNamespaces*/ @@ -32,8 +34,8 @@ namespace qmf { class PackageDefinition { public: - PackageDefinition (::qmf::AgentSession& session); - ~PackageDefinition () {} + ~PackageDefinition() {} + void configure(::qmf::AgentSession& session); /*MGEN:Schema.V2ClassMembers*/ }; -- cgit v1.2.1 From 01b3fdecc0f96507f48a2fc3e2b61e8f47393b86 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Tue, 22 Mar 2011 21:39:31 +0000 Subject: QPID-3159 - Applied patch from Angus Salkeld git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1084359 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/qmfgen/schema.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/qmfgen/schema.py b/qpid/cpp/managementgen/qmfgen/schema.py index afdfe42639..59e951fb6e 100755 --- a/qpid/cpp/managementgen/qmfgen/schema.py +++ b/qpid/cpp/managementgen/qmfgen/schema.py @@ -1731,9 +1731,9 @@ class SchemaPackage: stream.write(" qmf::SchemaProperty arg(\"%s\", %s);\n" % (arg.name, typeName)) if subType: stream.write(" arg.setSubtype(\"%s\");\n" % subType) - if stat.unit: + if arg.unit: stream.write(" arg.setUnit(\"%s\");\n" % arg.unit) - if stat.desc: + if arg.desc: stream.write(" arg.setDesc(\"%s\");\n" % arg.desc) stream.write(" arg.setDirection(%s);\n" % self.qmfv2Dir(arg.dir)) stream.write(" method.addArgument(arg);\n") -- cgit v1.2.1 From 9e3214850a8f8d419660cb42ee8004134f751870 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Wed, 25 May 2011 14:28:41 +0000 Subject: NO-JIRA - Makefile cleanup for wrapped bindings git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1127542 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/managementgen/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'qpid/cpp/managementgen') diff --git a/qpid/cpp/managementgen/Makefile.am b/qpid/cpp/managementgen/Makefile.am index 6c2024ccaa..8769200719 100644 --- a/qpid/cpp/managementgen/Makefile.am +++ b/qpid/cpp/managementgen/Makefile.am @@ -19,7 +19,8 @@ qmfpythondir = $(pythondir) dist_bin_SCRIPTS = \ qmf-gen -nobase_qmfpython_DATA = \ +pkgpyexec_qmfgendir = $(pyexecdir)/qmfgen +pkgpyexec_qmfgen_PYTHON = \ qmfgen/__init__.py \ qmfgen/generate.py \ qmfgen/schema.py \ -- cgit v1.2.1