import os import sys import re un_capitalize = lambda s: s[:1].lower() + s[1:] if s else '' def add_to_config(old, new): with open(add_to_config.file, "r+") as file: contents = file.read() events_class = re.search(r"class\s+ACE_newEvents\s+{\n",contents,re.I) if events_class: newline_index = events_class.end() insert = " {0} = \"{1}\";\n".format(old,new) else: newline_index = len(contents) insert = "\nclass ACE_newEvents {{\n {0} = \"{1}\";\n}};".format(old,new) contents = contents[:newline_index] + insert + contents[newline_index:] file.seek(0) file.write(contents) file.truncate() def event_replace(match): event = un_capitalize(match.group(1)) add_to_config(match.group(1), "ace_" + event) return "[\"ace_{0}\", {1}] call CBA_fnc_{2}".format(event,match.group(2),match.group(3)) def process_directory(dir, config=""): if not config: config = os.path.join(dir,"config.cpp") if os.path.isfile(config): add_to_config.file = config for p in os.listdir(dir): path = os.path.join(dir, p) if os.path.isdir(path): process_directory(path, config) continue ext = os.path.splitext(path)[1] if ext not in [".sqf",".hpp",".cpp"]: continue with open(path, "r+") as file: contents = file.read() # Simple single-line substitutions find = r"\[\s*\"(?!ace_)(\w+)\"\s*,\s*(.+?)\s*\]\s+call\s+CBA_fnc_((add|remove|local|global|target|server)Event(Handler)?)" contents, subbed = re.subn(find,event_replace,contents,0,re.I) # Handle multi-line code blocks for match in re.finditer(r"\[\s*\"(?!ace_)(\w+)\"\s*,\s*({.+?})\s*\]\s+call\s*CBA_fnc_(add|remove)EventHandler",contents,re.I|re.S): pair = 0 for i, c in enumerate(contents[match.start(2):]): if c == "{": pair += 1 elif c == "}": pair -= 1 if pair == 0: pair = i break if re.match(r"\s*\]\s+call\s+CBA_fnc_(add|remove)EventHandler",contents[pair+match.start(2)+1:],re.I): event = un_capitalize(match.group(1)) add_to_config(match.group(1), "ace_" + event) contents = contents[:match.start(1)] + "ace_" + event + contents[match.end(1):] subbed += 1 # Handle multi-line argument arrays for match in re.finditer(r"\[\s*\"(?!ace_)(\w+)\"\s*,\s*(\[.+?\])\s*\]\s+call\s*CBA_fnc_(local|global|server)Event",contents,re.I|re.S): pair = 0 for i, c in enumerate(contents[match.start(2):]): if c == "[": pair += 1 elif c == "]": pair -= 1 if pair == 0: pair = i break if re.match(r"\s*\]\s+call\s+CBA_fnc_(local|global|server)Event",contents[pair+match.start(2)+1:],re.I): event = un_capitalize(match.group(1)) add_to_config(match.group(1), "ace_" + event) contents = contents[:match.start(1)] + "ace_" + event + contents[match.end(1):] subbed += 1 if subbed > 0: print("Making {0} substitutions: {1}".format(subbed,path)) file.seek(0) file.write(contents) file.truncate() def main(): scriptpath = os.path.realpath(sys.argv[0]) projectpath = os.path.dirname(os.path.dirname(scriptpath)) addonspath = os.path.join(projectpath, "addons") os.chdir(addonspath) for p in os.listdir(addonspath): path = os.path.join(addonspath, p) if not os.path.isdir(path): continue if p[0] == ".": continue process_directory(path) if __name__ == "__main__": sys.exit(main())