ACE3/tools/search_undefinedFunctions.py

136 lines
4.4 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
import fnmatch
import os
import re
import ntpath
import sys
import argparse
import ctypes
#from http://stackoverflow.com/a/3429034
#Get required functions, strcpy..
strcpy = ctypes.cdll.msvcrt.strcpy
ocb = ctypes.windll.user32.OpenClipboard #Basic Clipboard functions
ecb = ctypes.windll.user32.EmptyClipboard
gcd = ctypes.windll.user32.GetClipboardData
scd = ctypes.windll.user32.SetClipboardData
ccb = ctypes.windll.user32.CloseClipboard
ga = ctypes.windll.kernel32.GlobalAlloc # Global Memory allocation
gl = ctypes.windll.kernel32.GlobalLock # Global Memory Locking
gul = ctypes.windll.kernel32.GlobalUnlock
GMEM_DDESHARE = 0x2000
def Get( ):
ocb(None) # Open Clip, Default task
pcontents = gcd(1) # 1 means CF_TEXT.. too lazy to get the token thingy ...
data = ctypes.c_char_p(pcontents).value
#gul(pcontents) ?
ccb()
return data
def Paste( data ):
ocb(None) # Open Clip, Default task
ecb()
hCd = ga( GMEM_DDESHARE, len( bytes(data,"ascii") )+1 )
pchData = gl(hCd)
strcpy(ctypes.c_char_p(pchData),bytes(data,"ascii"))
gul(hCd)
scd(1,hCd)
ccb()
def getFunctions(filepath):
selfmodule = (re.search('addons[\W]*([_a-zA-Z0-9]*)', filepath)).group(1)
# print("Checking {0} from {1}".format(filepath,selfmodule))
with open(filepath, 'r') as file:
content = file.read()
srch = re.compile('[^E]FUNC\(([_a-zA-Z0-9]*)\)')
modfuncs = srch.findall(content)
modfuncs = sorted(set(modfuncs))
srch = re.compile('EFUNC\(([_a-zA-Z0-9]*),([_a-zA-Z0-9]*)\)')
exfuncs = srch.findall(content)
exfuncs = sorted(set(exfuncs))
fileFuncs = []
for func in modfuncs:
fileFuncs.append("ace_{0}_fnc_{1}".format(selfmodule,func))
for exModule,func in exfuncs:
fileFuncs.append("ace_{0}_fnc_{1}".format(exModule, func))
return fileFuncs
def getStrings(filepath):
selfmodule = (re.search('addons[\W]*([_a-zA-Z0-9]*)', filepath)).group(1)
# print("Checking {0} from {1}".format(filepath,selfmodule))
with open(filepath, 'r') as file:
content = file.read()
srch = re.compile('[^E][CL]STRING\(([_a-zA-Z0-9]*)\)')
2015-09-20 22:56:07 +00:00
modStrings = srch.findall(content)
modStrings = sorted(set(modStrings))
2015-09-20 22:56:07 +00:00
srch = re.compile('E[CL]STRING\(([_a-zA-Z0-9]*),([_a-zA-Z0-9]*)\)')
exStrings = srch.findall(content)
exStrings = sorted(set(exStrings))
fileStrings = []
2015-09-20 22:56:07 +00:00
for localString in modStrings:
fileStrings.append("STR_ACE_{0}_{1}".format(selfmodule, localString))
2015-09-20 22:56:07 +00:00
for (exModule, exString) in exStrings:
fileStrings.append("STR_ACE_{0}_{1}".format(exModule, exString))
return fileStrings
def main():
print("#########################")
print("# All Functions #")
print("#########################")
sqf_list = []
allFunctions = []
allStrings = []
parser = argparse.ArgumentParser()
parser.add_argument('-m','--module', help='only search specified module addon folder', required=False, default=".")
args = parser.parse_args()
for root, dirnames, filenames in os.walk('../addons' + '/' + args.module):
for filename in fnmatch.filter(filenames, '*.sqf'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.cpp'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.hpp'):
sqf_list.append(os.path.join(root, filename))
for filename in sqf_list:
allFunctions = allFunctions + getFunctions(filename)
for filename in sqf_list:
allStrings = allStrings + getStrings(filename)
codeHeader = "diag_log text '*********** Scaning for nil functions [funcs {0} / strings {1}]';".format(len(set(allFunctions)), len(set(allStrings)))
codeFuncCheck = "{ if (isNil _x) then {systemChat format ['%1 is nil', _x]; diag_log text format ['%1 is nil', _x];}} forEach allFunctions;"
codeStringCheck = "{ if (!isLocalized _x) then {systemChat format ['%1 is not in stringtable', _x]; diag_log text format ['%1 is not in stringtable', _x];}} forEach allStrings;"
outputCode = "{0} allFunctions = {1}; allStrings = {2}; {3} {4}".format(codeHeader, list(set(allFunctions)), list(set(allStrings)), codeFuncCheck, codeStringCheck)
print(outputCode)
Paste(outputCode);
print ("")
print ("Copied to clipboard, [funcs {0} / strings {1}]'".format(len(set(allFunctions)), len(set(allStrings))))
if __name__ == "__main__":
main()