#!/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" % (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" % (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