#!/usr/bin/env python3
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
import tempfile
import filecmp
import shutil
class CDROIDHandler( xml.sax.ContentHandler ):
def __init__(self,namespace):
self.idlist=[]
self.strings=[]
self.namespace=namespace
def normalizeXMLString(self,xmlStr):
xmlStr.replace("\n", "
")
xmlStr.replace("\r", "d;")
return xmlStr
def isMyNS(self,idname):#parse @android:id/ @+id/ @id/
ns=""
if idname.find(":")>0:
ns = idname.split(":")
ns =ns[0]
else:
pos = idname.find("id/")
ns = idname[0:pos]
ns= ns.replace("@","")
ns= ns.replace("+","")
#print(idname+"==>"+ns)
if ns.strip():#not empty
return (ns==namespace) or (ns=="android" and namespace=="cdroid") or (ns=="cdroid" and namespace=="android")
return True
def startElement(self, tag, attributes):
for attr in attributes.getNames():
value = attributes.get(attr)
if ':id' in attr:
if self.isMyNS(value):
self.addID(value)
if 'string/' in value:
self.addString(value)
if 'type' in attributes and 'name' in attributes:
self.addID("@id/"+attributes.get('name'))
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()
if(value[0].isalpha() or (value[0]=='_')) and (value not in self.strings):
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','navigation','values']
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('')
fr.write("\n")
fr.write("\n")
i=0;
for k in self.Handler.idlist:
fr.write(' 0x%08x\n'%(k,self.idstart+i))
i+=1
fr.write("\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('\n')
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