First version for elements constants automatic creation
[anna.git] / source / diameter / stack / setups / createHeader.sh
1 #!/usr/bin/env python
2
3 import sys, re
4 import glob, os
5 import xml.etree.ElementTree as ET
6 import argparse
7 import subprocess
8
9
10 #-------------------------------------------------------------------------------
11 #                                                                      VARIABLES
12 #-------------------------------------------------------------------------------
13 HEADER_FILE = "/include/anna/diameter/helpers/defines.hpp"
14
15
16 #-------------------------------------------------------------------------------
17 #                                                                      FUNCTIONS
18 #-------------------------------------------------------------------------------
19 def normalize(name):
20   result = name.replace("-","_") 
21   result = result.replace(" ","_")
22   result = result.replace("+","_plus_")
23   result = result.replace("/","_slash_")
24   return result
25
26 def writeOnFile (file, text, mode = 'w'):
27   f = open(file, mode)
28   f.write(text)
29   f.close()
30
31 def launchShellScript(cmd):
32   p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
33   retcode = p.wait()
34   output = p.stdout.read()
35   return retcode,output
36
37
38 #-------------------------------------------------------------------------------
39 #-------------------------------------------------------------------------------
40 #                                                                  MAIN FUNCTION
41 #-------------------------------------------------------------------------------
42 #-------------------------------------------------------------------------------
43 def main(path):
44
45   # Git repository and target file:
46   retcode,git_root = launchShellScript("git rev-parse --show-toplevel 2>/dev/null")
47   git_root = git_root.replace("\n","")
48   target = git_root + HEADER_FILE
49
50   # Strings for content creation
51   content_header = ""
52   content_vendors = ""
53   content_avps = ""
54   content_enums = ""
55   content_commands = ""
56
57   # License and header:
58   license = git_root + "/LICENSE"
59   f = open(license)
60   content_header += str(f.read())
61   f.close()
62   content_header += "\n\n"
63   content_header += "#ifndef anna_diameter_helpers_defines_hpp\n"
64   content_header += "#define anna_diameter_helpers_defines_hpp\n"
65   content_header += "\n\n"
66   content_header += "// Local\n"
67   content_header += "#include <anna/diameter/defines.hpp>\n"
68   content_header += "#include <anna/config/defines.hpp>\n"
69   content_header += "\n\n"
70   content_header += "namespace anna {\nnamespace diameter {\nnamespace helpers {\n"
71
72
73   # Dictionary elements content creation:
74   os.chdir(path)
75   for file in glob.glob("*.xml"):
76
77     tree = ET.parse(file)
78     root = tree.getroot()
79     for child in root:
80       tag = child.tag
81       attribs = child.attrib
82       name = attribs['name']
83       name = normalize(name)
84
85       if tag == "vendor":
86         content_vendors += ("/** vendor '" + name + "' */ static const S32 VENDORID__" + name + " = " + attribs['code'] + ";\n")
87       elif tag == "avp":
88         try: vendor_name = attribs['vendor-name']
89         except: vendor_name = "IETF"
90         content_avps += ("/** avp '" + name + "' */ static const AvpId AVPID__" + name + "(" + attribs['code'] + ",VENDORID__" + vendor_name + ");\n")
91
92         single = child.find('single')
93         if single is not None:
94           label = single.find('label')
95           if label is not None:
96             content_enums += ("/** avp enumeration for '" + name + "' */\nstruct AVPVALUES__" + name + "\n")
97             content_enums += "{\n"
98             content_enums += "  enum v_ {\n"
99             comma = ","
100             for lbl in single.iter('label'):
101               lbl_attrib = lbl.attrib
102               alias = lbl_attrib['alias']
103               alias = normalize(alias)
104               data = lbl_attrib['data']
105               content_enums += ("    " + alias + " = " + data + comma + "\n")
106             content_enums += "  };\n"
107             content_enums += "};\n"
108
109       elif tag == "command":
110         if attribs['type'] == "Request":
111           is_request = "true"
112         else:
113           is_request = "false"
114         content_commands += ("/** command '" + name + "' */ static const CommandId COMMANDID__" + name + "(" + attribs['code'] + "," + is_request + ");\n")
115
116
117   # Write target while sorting uniquely vendors, avps and commands:
118   vendors_file = target + ".vendors"
119   avps_file = target + ".avps"
120   commands_file = target + ".commands"
121
122   # 1) write header
123   writeOnFile (target, content_header)
124   # 2) append sorted vendors
125   writeOnFile (target, "\n\n/** Vendors */\n", 'a')
126   writeOnFile (vendors_file, content_vendors)
127   retcode = launchShellScript("sort -u " + vendors_file + " >> " + target)
128   # 3) append sorted avps
129   writeOnFile (target, "\n\n/** Avps */\n", 'a')
130   writeOnFile (avps_file, content_avps)
131   retcode = launchShellScript("sort -u " + avps_file + " >> " + target)
132   # 4) append enums
133   writeOnFile (target, "\n\n/** Avps Enumerations */\n", 'a')
134   writeOnFile (target, content_enums, 'a')
135   # 5) append sorted commands
136   writeOnFile (target, "\n\n/** Commands */\n", 'a')
137   writeOnFile (commands_file, content_commands)
138   retcode = launchShellScript("sort -u " + commands_file + " >> " + target)
139   # 6) End header
140   writeOnFile (target, "\n}\n}\n}\n\n#endif\n\n", 'a')
141
142   # cleanup
143   os.remove(vendors_file)
144   os.remove(avps_file)
145   os.remove(commands_file)
146
147   # End notice
148   print "Created file '" + target + "'"
149
150
151
152 if __name__ == "__main__":
153
154   # Command-line arguments:
155   parser = argparse.ArgumentParser(description='Generates a C++ header file from dictionary elements found under provided directory as xml files')
156   parser.add_argument('path', help='directory containing xml files')
157   args = parser.parse_args()
158
159   try:
160     main(args.path)
161   except Exception as e:
162     print e
163     sys.exit(1)
164