File indexing completed on 2025-01-05 04:26:51
0001 # Copyright 2013 Anmol Ahuja <darthcodus@gmail.com> 0002 # 0003 # This program is free software; you can redistribute it and/or 0004 # modify it under the terms of the GNU General Public License as 0005 # published by the Free Software Foundation; either version 2 of 0006 # the License, or (at your option) any later version. 0007 # 0008 # This program is distributed in the hope that it will be useful, 0009 # but WITHOUT ANY WARRANTY; without even the implied warranty of 0010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0011 # GNU General Public License for more details. 0012 # 0013 # You should have received a copy of the GNU General Public License 0014 # along with this program. If not, see <http://www.gnu.org/licenses/>. 0015 0016 # TODOs: 0017 # NO enums like in AmarokInfoScript.cpp handled, global func not handled 0018 # handle enums in scriptdox 0019 # Handle multiple classes in a file 0020 # Handle docs in script dox 0021 0022 import os 0023 import sys 0024 import re 0025 0026 prototype = {} 0027 scriptMap = {} 0028 autoComplete = [] 0029 0030 def addElement( scriptMap, name, classDoc = '' ): 0031 #if not scriptMap.has_key( name ): 0032 scriptMap[name] = ["\nclass " + name + "{\n"] 0033 0034 def generatePseudoHeader( rootDir, fileName ): 0035 global prototype 0036 global scriptMap 0037 global autoComplete 0038 0039 headerPath = os.path.join(rootDir, fileName+".h") 0040 0041 className = None 0042 with open( headerPath, 'r' ) as f: 0043 contents = f.read() 0044 match = re.search( r'//[\s]*SCRIPTDOX[\s:]*(.*)', contents ) 0045 if match is None: 0046 return 0047 s = [item for item in match.group(1).split(' ') if item] 0048 if 'PROTOTYPE' in s: 0049 className = s[2].strip() 0050 prototype[ s[1] ] = className 0051 else: 0052 className = s[0].strip() 0053 autoComplete.append( className ) 0054 addElement( scriptMap, className )#, classDoc ) 0055 classBeg = contents.index(match.group(0)) 0056 if True: 0057 properties = re.findall( r"(Q_PROPERTY\(\s*[\w:<>]*\s*([\w:<>\*]*).*\))", contents, re.MULTILINE ) 0058 for qProperty in properties: 0059 if 'PROTOTYPE' not in s: 0060 autoComplete.append( className + "." + qProperty[1] ) 0061 scriptMap[className].append( qProperty[0] ) 0062 #re.findall( r"public slots:[\s\n]*(.*)[\n\s]*(protected|private|public|slots|};|signals):" #huh, works without |signals?! 0063 # , contents, re.MULTILINE|re.DOTALL ) 0064 accessMap = {} 0065 for access in ( 'private slots:', 'protected slots:', 'public slots:', 'private:', 'public:', 'protected:', 'signals:', '};' ): 0066 indexFromBeg = contents[classBeg:].find( access ) + classBeg 0067 if indexFromBeg != -1: 0068 accessMap[ indexFromBeg ] = access 0069 0070 sortedKeys = sorted( accessMap.keys() ) 0071 for access in ('public slots:', 'signals:'): 0072 if( access in contents ): 0073 accessIndex = contents[classBeg:].find( access ) + classBeg 0074 selections = contents[ accessIndex : sortedKeys[sortedKeys.index(accessIndex)] ] 0075 functions = filter( None, re.findall( r'(.*;)', selections ) ) 0076 if 'PROTOTYPE' not in s: 0077 for function in functions: 0078 reg = re.search( r'.*[\s\n](.*)[\s\n]*\(', function.strip()) 0079 if reg: 0080 funcName = reg.group(1).replace('*','').replace('&','') 0081 autoComplete.append( className+"."+ funcName + '(' ) 0082 scriptMap[className].append( selections ) 0083 0084 def traverseDir( dirPath, opDir ): 0085 for root, subFolder, files in os.walk(dirPath): 0086 for fileName in files: 0087 if fileName.endswith( ".cpp" ): 0088 generatePseudoHeader( root, fileName[:-4] ) 0089 #substitute prototypes 0090 for scriptClass in scriptMap: 0091 for line in scriptMap[scriptClass]: 0092 re.sub( r"\b("+'|'.join(prototype.keys())+r')\b', lambda word: prototype[word.group()], line ) 0093 0094 f = open( os.path.join( opDir, "PseudoHeader.h" ), 'w' ) 0095 for scriptClass in scriptMap: 0096 f.write( '\n'.join(scriptMap[scriptClass]) + '};\n' ) 0097 f.close() 0098 0099 autoComplete.sort() 0100 f = open( os.path.join( opDir, "AutoComplete.txt" ), 'w' ) 0101 f.write( '\n'.join(autoComplete) ) 0102 f.close() 0103 0104 def main(): 0105 scriptPath = sys.argv[1] 0106 if not os.path.exists(sys.argv[2]): 0107 os.makedirs(sys.argv[2]) 0108 traverseDir( sys.argv[1], sys.argv[2] ) 0109 0110 if __name__ == "__main__": 0111 main()