2019-10-05 20:53:16 +00:00
#!/usr/bin/env python3
2015-09-18 18:14:00 +00:00
import fnmatch
import os
import re
import ntpath
import sys
import argparse
2020-06-30 16:43:00 +00:00
# handle x64 python clipboard, ref https://forums.autodesk.com/t5/maya-programming/ctypes-bug-cannot-copy-data-to-clipboard-via-python/m-p/9197068/highlight/true#M10992
2015-09-18 18:14:00 +00:00
import ctypes
2020-06-30 16:43:00 +00:00
from ctypes import wintypes
CF_UNICODETEXT = 13
user32 = ctypes . WinDLL ( ' user32 ' )
kernel32 = ctypes . WinDLL ( ' kernel32 ' )
OpenClipboard = user32 . OpenClipboard
OpenClipboard . argtypes = wintypes . HWND ,
OpenClipboard . restype = wintypes . BOOL
CloseClipboard = user32 . CloseClipboard
CloseClipboard . restype = wintypes . BOOL
EmptyClipboard = user32 . EmptyClipboard
EmptyClipboard . restype = wintypes . BOOL
GetClipboardData = user32 . GetClipboardData
GetClipboardData . argtypes = wintypes . UINT ,
GetClipboardData . restype = wintypes . HANDLE
SetClipboardData = user32 . SetClipboardData
SetClipboardData . argtypes = ( wintypes . UINT , wintypes . HANDLE )
SetClipboardData . restype = wintypes . HANDLE
GlobalLock = kernel32 . GlobalLock
GlobalLock . argtypes = wintypes . HGLOBAL ,
GlobalLock . restype = wintypes . LPVOID
GlobalUnlock = kernel32 . GlobalUnlock
GlobalUnlock . argtypes = wintypes . HGLOBAL ,
GlobalUnlock . restype = wintypes . BOOL
GlobalAlloc = kernel32 . GlobalAlloc
GlobalAlloc . argtypes = ( wintypes . UINT , ctypes . c_size_t )
GlobalAlloc . restype = wintypes . HGLOBAL
GlobalSize = kernel32 . GlobalSize
GlobalSize . argtypes = wintypes . HGLOBAL ,
GlobalSize . restype = ctypes . c_size_t
GMEM_MOVEABLE = 0x0002
GMEM_ZEROINIT = 0x0040
2015-09-18 18:14:00 +00:00
def Paste ( data ) :
2020-06-30 16:43:00 +00:00
data = data . encode ( ' utf-16le ' )
OpenClipboard ( None )
EmptyClipboard ( )
handle = GlobalAlloc ( GMEM_MOVEABLE | GMEM_ZEROINIT , len ( data ) + 2 )
pcontents = GlobalLock ( handle )
ctypes . memmove ( pcontents , data , len ( data ) )
GlobalUnlock ( handle )
SetClipboardData ( CF_UNICODETEXT , handle )
CloseClipboard ( )
2015-09-18 18:14:00 +00:00
def getFunctions ( filepath ) :
2020-06-30 16:43:00 +00:00
selfmodule = ( re . search ( r ' addons[ \ W]*([_a-zA-Z0-9]*) ' , filepath ) ) . group ( 1 )
2015-09-18 18:14:00 +00:00
# print("Checking {0} from {1}".format(filepath,selfmodule))
2023-10-18 19:19:20 +00:00
if ( selfmodule . startswith ( " compat " ) ) : return [ ]
2015-09-20 22:46:43 +00:00
2015-09-18 18:14:00 +00:00
with open ( filepath , ' r ' ) as file :
content = file . read ( )
2020-06-30 16:43:00 +00:00
srch = re . compile ( r ' [^E]FUNC \ (([_a-zA-Z0-9]*) \ ) ' )
2015-09-18 18:14:00 +00:00
modfuncs = srch . findall ( content )
modfuncs = sorted ( set ( modfuncs ) )
2020-06-30 16:43:00 +00:00
srch = re . compile ( r ' EFUNC \ (([_a-zA-Z0-9]*),([_a-zA-Z0-9]*) \ ) ' )
2015-09-18 18:14:00 +00:00
exfuncs = srch . findall ( content )
exfuncs = sorted ( set ( exfuncs ) )
2015-09-20 22:46:43 +00:00
fileFuncs = [ ]
2015-09-18 18:14:00 +00:00
for func in modfuncs :
2015-09-20 22:46:43 +00:00
fileFuncs . append ( " ace_ {0} _fnc_ {1} " . format ( selfmodule , func ) )
2015-09-18 18:14:00 +00:00
for exModule , func in exfuncs :
2015-09-20 22:46:43 +00:00
fileFuncs . append ( " ace_ {0} _fnc_ {1} " . format ( exModule , func ) )
return fileFuncs
def getStrings ( filepath ) :
2020-06-30 16:43:00 +00:00
selfmodule = ( re . search ( r ' addons[ \ W]*([_a-zA-Z0-9]*) ' , filepath ) ) . group ( 1 )
2015-09-20 22:46:43 +00:00
# print("Checking {0} from {1}".format(filepath,selfmodule))
2023-10-18 19:19:20 +00:00
if ( selfmodule . startswith ( " compat " ) ) : return [ ]
2015-09-20 22:46:43 +00:00
with open ( filepath , ' r ' ) as file :
content = file . read ( )
2020-06-30 16:43:00 +00:00
srch = re . compile ( r ' [^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:46:43 +00:00
2020-06-30 16:43:00 +00:00
srch = re . compile ( r ' E[CL]STRING \ (([_a-zA-Z0-9]*),([_a-zA-Z0-9]*) \ ) ' )
2015-09-20 22:56:07 +00:00
exStrings = srch . findall ( content )
exStrings = sorted ( set ( exStrings ) )
2015-09-20 22:46:43 +00:00
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:46:43 +00:00
2015-09-20 22:56:07 +00:00
for ( exModule , exString ) in exStrings :
fileStrings . append ( " STR_ACE_ {0} _ {1} " . format ( exModule , exString ) )
2015-09-20 22:46:43 +00:00
return fileStrings
2015-09-18 18:14:00 +00:00
def main ( ) :
print ( " ######################### " )
print ( " # All Functions # " )
print ( " ######################### " )
sqf_list = [ ]
2015-09-20 22:46:43 +00:00
2015-09-18 18:14:00 +00:00
allFunctions = [ ]
2015-09-20 22:46:43 +00:00
allStrings = [ ]
2015-09-18 18:14:00 +00:00
parser = argparse . ArgumentParser ( )
parser . add_argument ( ' -m ' , ' --module ' , help = ' only search specified module addon folder ' , required = False , default = " . " )
args = parser . parse_args ( )
2015-09-20 22:46:43 +00:00
2023-10-18 19:19:20 +00:00
addon_base_path = os . path . dirname ( os . path . dirname ( os . path . realpath ( __file__ ) ) )
for root , dirnames , filenames in os . walk ( addon_base_path + " / " + ' addons ' + ' / ' + args . module ) :
2015-09-18 18:14:00 +00:00
for filename in fnmatch . filter ( filenames , ' *.sqf ' ) :
sqf_list . append ( os . path . join ( root , filename ) )
2015-09-20 22:46:43 +00:00
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 ) )
2015-09-18 18:14:00 +00:00
for filename in sqf_list :
allFunctions = allFunctions + getFunctions ( filename )
2015-09-20 22:46:43 +00:00
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 )
2015-09-18 18:14:00 +00:00
print ( outputCode )
2020-06-30 16:43:00 +00:00
Paste ( outputCode )
2015-09-18 18:14:00 +00:00
print ( " " )
2015-09-20 22:46:43 +00:00
print ( " Copied to clipboard, [funcs {0} / strings {1} ] ' " . format ( len ( set ( allFunctions ) ) , len ( set ( allStrings ) ) ) )
2015-09-18 18:14:00 +00:00
if __name__ == " __main__ " :
main ( )