Cdroid/scripts/idgen.py

202 lines
6.8 KiB
Python
Executable File

#!/usr/bin/env python
import xml.sax
from xml.dom import minidom
import xml.etree.ElementTree as xmltree
from xml.dom.minidom import parse, parseString
import os
import sys
import time
class CDROIDHandler( xml.sax.ContentHandler ):
def __init__(self,namespace):
self.idlist=[]
self.strings=[]
self.namespace=namespace
def startElement(self, tag, attributes):
for attr in attributes.getNames():
value = attributes.get(attr)
if ':id' in attr:
self.addID(value)
if 'string/' in value:
self.addString(value)
def addID(self,name):
pos=name.find('/')
if pos<0:
return
name=name[pos+1:].strip()
if (name[0].isalpha() or (name[0]=='_')) and (name not in self.idlist) :
self.idlist.append(name)
def addString(self,value):
pos=value.find('/')
if pos<0 :
return
value=value[pos+1:].strip()
self.strings.append(value)
def groupby(self):
new_ids = []
for id in self.idlist:
if id not in new_ids:
new_ids.append(id)
self.idlist=new_ids
print(new_ids)
return new_ids
class IDGenerater(object):
def __init__(self,idstart,namespace):
self.idstart=idstart
self.namespace=namespace
self.processDirs=['layout','drawable']
self.parser = xml.sax.make_parser()
self.parser.setFeature(xml.sax.handler.feature_namespaces, 0)
self.Handler = CDROIDHandler(namespace)
self.parser.setContentHandler( self.Handler )
def dict2RH(self,filepath):
fr=open(filepath,"w")
fr.write("#pragma once\n\n")
fr.write("/*Generated by machine ,Do not edit !!!*/\n\n")
fr.write("namespace %s{\n\n"%(self.namespace))
fr.write("namespace R{\n")
fr.write(" namespace id{\n")
i=0
#print(self.Handler.idlist)
#print(self.Handler.strings)
for k in self.Handler.idlist:
fr.write("%8s static constexpr int %-24s= 0x%08X ;/*%d*/\n"%('',k,self.idstart+i,self.idstart+i))
i+=1
fr.write("%4s};/*namespace id*/\n\n"%(''))
fr.write(" namespace strings{\n")
i=0
for ss in self.Handler.strings:
fr.write("%8s static constexpr int %-24s= 0x%08X ;/*%d*/\n"%('',ss,self.idstart+i,self.idstart+i))
i+=1
fr.write("%4s};/*namespace strings*/\n\n"%(''))
fr.write("};//endof namespace R\n\n")
fr.write("}//endof namespace\n\n")
fr.close()
def dict2ID(self,filepath):
fr=open(filepath,"w")
fr.write('<?xml version="1.0" encoding="utf-8"?>')
fr.write("<!--Generated by CDdroid's machine,Do not edit !!!-->\n")
fr.write("<resources xmlns:android=\"http://schemas.android.com/apk/res/android\">\n")
i=0;
for k in self.Handler.idlist:
fr.write(' <id name="%s">0x%08x</id>\n'%(k,self.idstart+i))
i+=1
fr.write("</resources>\n\n")
fr.close();
def elementExists(self,elements,tofind):
for e in elements:
if e.getAttribute('name')==tofind:
return 1
return 0
def fixed_writexml(self,writer,xmlroot): #, indent, addindent, newl,encoding):
indent=''
addindent='\t'
newl='\n'
encoding='utf-8'
writer.write(indent + "<" + xmlroot.tagName)
attrs = xmlroot._get_attributes()
a_names = attrs.keys()
for a_name in a_names:
writer.write(" %s=\"" % a_name)
minidom._write_data(writer, attrs[a_name].value)
writer.write("\"")
if xmlroot.childNodes:
if len(xmlroot.childNodes) == 1 \
and xmlroot.childNodes[0].nodeType == minidom.Node.TEXT_NODE:
writer.write(">")
xmlroot.childNodes[0].writexml(writer, "", "", "")
writer.write("</%s>%s" % (xmlroot.tagName, newl))
return
writer.write(">%s" % (newl))
for node in xmlroot.childNodes:
if node.nodeType is not minidom.Node.TEXT_NODE:
node.writexml(writer, indent + addindent, addindent, newl)
writer.write("%s</%s>%s" % (indent, xmlroot.tagName, newl))
else:
writer.write("/>%s" % (newl))
def strings2XML(self,filename):
print(self.Handler.strings)
try:
dom=parse(filename)
except:#(xml.parsers.expat.ExpatError)
print(filename+" open failed or syntax error")
dom=parseString('<?xml version="1.0" encoding="utf-8"?>\n<resources lang="zh_CN"></resources>')
root = dom.documentElement
stringsNodeInFile=root.getElementsByTagName('string')
for str in self.Handler.strings:
if self.elementExists(stringsNodeInFile,str):
continue
e=dom.createElement('string')
text = dom.createTextNode(str)
text.text=str
e.setAttribute('name',str)
e.appendChild(text)
root.appendChild(e)
fp = open(filename, mode='w')#, encoding='utf-8')
self.fixed_writexml(fp,root)# ,indent='', addindent='\t', newl='\n', encoding='utf-8')
fp.close()
def dirHasId(self,path):
for dir in self.processDirs:
if path.find(dir)>=0:
return 1
return -1;
def scanxml(self,scanPath):
lastmodifytime=0
for top, dirs, nondirs in os.walk(scanPath):
dirs.sort()
nondirs.sort()
for item in nondirs:
fname=os.path.join(top, item)
if (not item.endswith('.xml')) or (self.dirHasId(fname)<0):
continue
newestdate=os.stat(fname);
if(lastmodifytime<newestdate.st_mtime):
lastmodifytime=newestdate.st_mtime
self.parser.parse(fname)
return lastmodifytime
if ( __name__ == "__main__"):
#arg0 is myname(idgen.py)
#arg1 is namespace
#arg2 is resource directory
#arg3 is directory which R.h generate to
idstart=10000
if len(sys.argv)<3:
print(sys.argv[0])
print(sys.argv)
namespace=sys.argv[1]
if namespace=='cdroid':
idstart=1000
print("namespace="+namespace)
lastmodifytime=0
if os.path.exists(sys.argv[3]):
fstat=os.stat(sys.argv[3])
lastmodifytime=fstat.st_mtime
idgen=IDGenerater(idstart,namespace)
if not os.path.exists(sys.argv[2]+"/values"):
os.makedirs(sys.argv[2]+"/values")
if idgen.scanxml(sys.argv[2])>lastmodifytime:
idgen.dict2RH(sys.argv[3])
idgen.dict2ID(sys.argv[2]+"/values/ID.xml")
idgen.strings2XML(sys.argv[2]+"/values/strings.xml")
else:
print(sys.argv[3]+" is latest ,skipped.")