1#!/usr/bin/env python3
2# Take a .conf file and generate :
3# 1- Couple header   (.h)
4# 2- Couple template (_desc.cpp)
5# 3....
6# (c) Mean 2011
7#
8import os
9import re
10import sys
11
12structName=r'foostruct'
13allCTypes=dict()
14allATypes=dict()
15allJTypes=dict()
16
17allCTypes["uint32_t"]="uint32_t"
18allCTypes["int32_t"]="int32_t"
19allCTypes["bool"]="bool"
20allCTypes["string"]="std::string "
21allCTypes["float"]="float"
22allCTypes["double"]="double"
23allCTypes["video_encode"]="COMPRES_PARAMS"
24allCTypes["lavcodec_context"]="FFcodecContext"
25
26allJTypes["uint32_t"]="json.addUint32("
27allJTypes["int32_t"]="json.addInt32("
28allJTypes["bool"]="json.addBool("
29allJTypes["string"]="json.addString("
30allJTypes["float"]="json.addFloat("
31allJTypes["double"]="json.addDouble("
32allJTypes["video_encode"]="json.addCompressParam("
33allJTypes["lavcodec_context"]="json.lavcodec("
34
35
36allATypes["uint32_t"]="ADM_param_uint32_t"
37allATypes["int32_t"]="ADM_param_int32_t"
38allATypes["float"]="ADM_param_float"
39allATypes["double"]="ADM_param_double"
40allATypes["bool"]="ADM_param_bool"
41allATypes["string"]="ADM_param_stdstring"
42allATypes["video_encode"]="ADM_param_video_encode"
43allATypes["lavcodec_context"]="ADM_param_lavcodec_context"
44
45fullPath=""
46nested=list()
47gotName=False
48def usage():
49    print("python admSerialization xxxx.conf")
50#########################################################
51def outputHeader(st):
52    tab="\t"*len(nested)
53    headerFile.write(tab+str(st)+"\n")
54    pass
55def outputDesc(st):
56    descFile.write(str(st)+"\n")
57    pass
58def outputJson(st):
59    jsonFile.write(str(st)+"\n")
60    #print(st)
61    pass
62
63#
64def processLine(varType,varName):
65    if(not varType in allCTypes):
66        print("Unknown var type "+str(varType))
67        exit(1)
68    if(not varType in allATypes):
69        print("Unknown var type "+str(varType))
70        exit(1)
71    if(not varType in allJTypes):
72        print("json:Unknown var "+str(varType))
73        exit(1)
74    ctype=allCTypes[varType].strip()
75    atype=allATypes[varType].strip()
76    jtype=allJTypes[varType].strip()
77    outputHeader( str(ctype)+" "+str(varName)+";")
78    if(len(fullPath)==0):
79        fullName=varName
80    else:
81        fullName=fullPath+"."+varName
82    #outputDesc(" {\""+str(varName)+"\",offsetof("+str(structName)+","+str(fullName)+"),\""+str(ctype)+"\","+str(atype)+"},")
83    outputDesc(" {\""+str(fullName)+"\",offsetof("+str(structName)+","+str(fullName)+"),\""+str(ctype)+"\","+str(atype)+"},")
84    # json part...
85    outputJson(jtype+"\""+str(varName)+"\",key->"+str(fullName)+");")
86###################################################################################################################################
87def writeDescHead():
88    outputDesc("// automatically generated by admSerialization.py, do not edit!")
89    #outputDesc("#include \"string\"")
90    #outputDesc("#include \"ADM_default.h\"")
91    #outputDesc("#include \"ADM_paramList.h\"")
92    #outputDesc("#include \""+str(headerFileName)+"\"")
93    outputDesc("extern const ADM_paramList "+str(structName)+"_param[]={")
94
95def writeDescFooter():
96    outputDesc("{NULL,0,NULL}")
97    outputDesc("};")
98
99def writeJsonHead():
100    outputJson("// automatically generated by admSerialization.py, do not edit!")
101    outputJson("#include \"ADM_default.h\"")
102    outputJson("#include \"ADM_paramList.h\"")
103    #outputJson("#include \"ADM_coreVideoEncoder.h\"")
104    #outputJson("#include \"ADM_encoderConf.h\"")
105    outputJson("#include \"ADM_coreJson.h\"")
106    outputJson("#include \""+str(headerFileName)+"\"")
107    #outputJson("extern const ADM_paramList "+str(structName)+"_param[];")
108    outputJson("bool  "+str(structName)+"_jserialize(const char *file, const "+str(structName)+" *key){")
109    outputJson("admJson json;")
110
111def writeJsonFooter():
112    outputJson("return json.dumpToFile(file);")
113    outputJson("};")
114    outputJson("bool  "+str(structName)+"_jdeserialize(const char *file, const ADM_paramList *tmpl,"+str(structName)+" *key){")
115    outputJson("admJsonToCouple json;")
116    outputJson("CONFcouple *c=json.readFromFile(file);")
117    outputJson("if(!c) {ADM_error(\"Cannot read json file\");return false;}")
118    outputJson("bool r= ADM_paramLoadPartial(c,tmpl,key);")
119    outputJson("delete c;")
120    outputJson("return r;")
121    outputJson("};")
122
123
124
125def writeHeaderHead():
126    outputHeader( "// automatically generated by admSerialization.py do not edit")
127    outputHeader("#include \"string\"")
128    outputHeader("#pragma once")
129    outputHeader(  "typedef struct {")
130
131def writeHeadFooter():
132    outputHeader("}"+structName+";")
133###################################################################################################################################
134# Main...
135###################################################################################################################################
136nb=len(sys.argv)
137if(nb!=2):
138    usage()
139    exit(1)
140print("Processing "+str(sys.argv[1]))
141inputFile=sys.argv[1]
142if(not os.path.isfile(inputFile)):
143    print("no such file "+str(inputFile))
144    exit(1)
145structName=re.sub(r'.conf',r'',inputFile)
146#
147headerFileName=re.sub(r'.conf',r'.h',inputFile)
148headerFile=open(headerFileName,'w')
149#
150descFileName=re.sub(r'.conf',r'_desc.cpp',inputFile)
151descFile=open(descFileName,'w')
152#
153jsonFileName=re.sub(r'.conf',r'_json.cpp',inputFile)
154jsonFile=open(jsonFileName,'w')
155#
156f=open(inputFile,'r')
157while(1):
158    line=f.readline()
159    if(len(line)==0):
160        break # eof
161    line=re.sub(r'#.*$',r'',line)
162    line=re.sub(r'//.*$',r'',line)
163    line=line.strip()
164    if(len(line)==0):
165        continue # blank
166    # Remove #....
167    if(line.find(r'{')!=-1):
168        #
169        structs=re.sub(r'{.*$',r'',line).strip()
170        if(len(nested)==0 and gotName==False): # first one = struct Name
171            structName=structs
172            print("Our structure is :"+str(structName))
173            writeDescHead()
174            writeHeaderHead()
175            writeJsonHead()
176            gotName=True
177        else:  # else we have structure inside structure
178            #outputHeader("struct "+structs+" {")
179            outputHeader("struct  {")
180            nested.append(structs)
181            fullPath=".".join(nested)
182            outputJson("json.addNode(\""+str(structs)+"\");")
183    elif(line.find(r'}')!=-1):
184        if(len(nested)!=0):
185            last=nested.pop()
186            outputJson("json.endNode();")
187            outputHeader("}"+str(last)+";")
188            #outputHeader("};")
189        fullPath=".".join(nested)
190    elif(line.find(':')!=-1):
191        if(gotName==False):
192            print("No structure name !")
193            exit(1)
194        line=re.sub(r'#.*$',r'',line)
195        line=re.sub(r'//.*$',r'',line)
196        if(len(line)==0):
197            continue
198        # split by :
199        (varType,varName)=line.split(r':')
200        #
201        # Remote extra ,.... used by prefs
202        varName=re.sub(r',.*$',r';',varName)
203        #
204        varName=re.sub(r';.*$',r'',varName)
205        varName=varName.strip()
206        varType=varType.strip()
207        processLine(varType,varName)
208    else:
209        print("Invalid line "+str(line))
210        exit(1)
211f.close()
212writeDescFooter()
213writeHeadFooter()
214writeJsonFooter()
215headerFile.close()
216descFile.close()
217jsonFile.close()
218print("All done")
219