--- /dev/null
+#!/usr/bin/env python
+
+import sys, re
+import glob, os
+import xml.etree.ElementTree as ET
+import argparse
+import subprocess
+
+
+#-------------------------------------------------------------------------------
+# VARIABLES
+#-------------------------------------------------------------------------------
+HEADER_FILE = "/include/anna/diameter/helpers/defines.hpp"
+
+
+#-------------------------------------------------------------------------------
+# FUNCTIONS
+#-------------------------------------------------------------------------------
+def normalize(name):
+ result = name.replace("-","_")
+ result = result.replace(" ","_")
+ result = result.replace("+","_plus_")
+ result = result.replace("/","_slash_")
+ return result
+
+def writeOnFile (file, text, mode = 'w'):
+ f = open(file, mode)
+ f.write(text)
+ f.close()
+
+def launchShellScript(cmd):
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
+ retcode = p.wait()
+ output = p.stdout.read()
+ return retcode,output
+
+
+#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+# MAIN FUNCTION
+#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+def main(path):
+
+ # Git repository and target file:
+ retcode,git_root = launchShellScript("git rev-parse --show-toplevel 2>/dev/null")
+ git_root = git_root.replace("\n","")
+ target = git_root + HEADER_FILE
+
+ # Strings for content creation
+ content_header = ""
+ content_vendors = ""
+ content_avps = ""
+ content_enums = ""
+ content_commands = ""
+
+ # License and header:
+ license = git_root + "/LICENSE"
+ f = open(license)
+ content_header += str(f.read())
+ f.close()
+ content_header += "\n\n"
+ content_header += "#ifndef anna_diameter_helpers_defines_hpp\n"
+ content_header += "#define anna_diameter_helpers_defines_hpp\n"
+ content_header += "\n\n"
+ content_header += "// Local\n"
+ content_header += "#include <anna/diameter/defines.hpp>\n"
+ content_header += "#include <anna/config/defines.hpp>\n"
+ content_header += "\n\n"
+ content_header += "namespace anna {\nnamespace diameter {\nnamespace helpers {\n"
+
+
+ # Dictionary elements content creation:
+ os.chdir(path)
+ for file in glob.glob("*.xml"):
+
+ tree = ET.parse(file)
+ root = tree.getroot()
+ for child in root:
+ tag = child.tag
+ attribs = child.attrib
+ name = attribs['name']
+ name = normalize(name)
+
+ if tag == "vendor":
+ content_vendors += ("/** vendor '" + name + "' */ static const S32 VENDORID__" + name + " = " + attribs['code'] + ";\n")
+ elif tag == "avp":
+ try: vendor_name = attribs['vendor-name']
+ except: vendor_name = "IETF"
+ content_avps += ("/** avp '" + name + "' */ static const AvpId AVPID__" + name + "(" + attribs['code'] + ",VENDORID__" + vendor_name + ");\n")
+
+ single = child.find('single')
+ if single is not None:
+ label = single.find('label')
+ if label is not None:
+ content_enums += ("/** avp enumeration for '" + name + "' */\nstruct AVPVALUES__" + name + "\n")
+ content_enums += "{\n"
+ content_enums += " enum v_ {\n"
+ comma = ","
+ for lbl in single.iter('label'):
+ lbl_attrib = lbl.attrib
+ alias = lbl_attrib['alias']
+ alias = normalize(alias)
+ data = lbl_attrib['data']
+ content_enums += (" " + alias + " = " + data + comma + "\n")
+ content_enums += " };\n"
+ content_enums += "};\n"
+
+ elif tag == "command":
+ if attribs['type'] == "Request":
+ is_request = "true"
+ else:
+ is_request = "false"
+ content_commands += ("/** command '" + name + "' */ static const CommandId COMMANDID__" + name + "(" + attribs['code'] + "," + is_request + ");\n")
+
+
+ # Write target while sorting uniquely vendors, avps and commands:
+ vendors_file = target + ".vendors"
+ avps_file = target + ".avps"
+ commands_file = target + ".commands"
+
+ # 1) write header
+ writeOnFile (target, content_header)
+ # 2) append sorted vendors
+ writeOnFile (target, "\n\n/** Vendors */\n", 'a')
+ writeOnFile (vendors_file, content_vendors)
+ retcode = launchShellScript("sort -u " + vendors_file + " >> " + target)
+ # 3) append sorted avps
+ writeOnFile (target, "\n\n/** Avps */\n", 'a')
+ writeOnFile (avps_file, content_avps)
+ retcode = launchShellScript("sort -u " + avps_file + " >> " + target)
+ # 4) append enums
+ writeOnFile (target, "\n\n/** Avps Enumerations */\n", 'a')
+ writeOnFile (target, content_enums, 'a')
+ # 5) append sorted commands
+ writeOnFile (target, "\n\n/** Commands */\n", 'a')
+ writeOnFile (commands_file, content_commands)
+ retcode = launchShellScript("sort -u " + commands_file + " >> " + target)
+ # 6) End header
+ writeOnFile (target, "\n}\n}\n}\n\n#endif\n\n", 'a')
+
+ # cleanup
+ os.remove(vendors_file)
+ os.remove(avps_file)
+ os.remove(commands_file)
+
+ # End notice
+ print "Created file '" + target + "'"
+
+
+
+if __name__ == "__main__":
+
+ # Command-line arguments:
+ parser = argparse.ArgumentParser(description='Generates a C++ header file from dictionary elements found under provided directory as xml files')
+ parser.add_argument('path', help='directory containing xml files')
+ args = parser.parse_args()
+
+ try:
+ main(args.path)
+ except Exception as e:
+ print e
+ sys.exit(1)
+