Added gen_enum_str
This commit is contained in:
parent
dd7c42f6f3
commit
46eedfceb5
168
gen_enum_str.py
Normal file
168
gen_enum_str.py
Normal file
@ -0,0 +1,168 @@
|
||||
#!/bin/python3
|
||||
"""
|
||||
A python script to generate to_string functions for all enumerations in a cpp file.
|
||||
Copyright © 2022 Matthias Quintern.
|
||||
This software comes with no warranty.
|
||||
This software is licensed under the GPL3
|
||||
"""
|
||||
from os import path, listdir, chdir
|
||||
from sys import argv, exit
|
||||
import re
|
||||
|
||||
|
||||
filetypes = [".hpp", ".cpp", ".tpp"]
|
||||
|
||||
def error(s):
|
||||
print(s)
|
||||
exit(1)
|
||||
|
||||
|
||||
def getEnumStrF(name: str, enum: dict, spaces: int):
|
||||
s = " " * spaces
|
||||
s += f"const std::map<{name}, std::string> {name}ToStringMap" + " { // generated by gen_enum_str.py\n"
|
||||
for name_, val in enum.items():
|
||||
s += " " * (spaces + 4)
|
||||
s += "{ " + name_ + ", \"" + name_ + "\" },\n"
|
||||
s += " " * spaces + "};\n"
|
||||
s += " " * spaces + "const std::string& to_string(" + name + " v) { return " + f"{name}ToStringMap.at(v);" + " }; // generated by gen_enum_str.py\n\n"
|
||||
return s
|
||||
|
||||
|
||||
def process_file(inputfile: str, outputfile: str):
|
||||
print("process_file:", inputfile)
|
||||
if not path.isfile(inputfile): error("File does not exist:" + inputfile)
|
||||
|
||||
with open(inputfile, "r") as file:
|
||||
lines = file.readlines()
|
||||
|
||||
# FIND ENUMS
|
||||
enums_start = []
|
||||
enums_stop = []
|
||||
in_enum = False
|
||||
for i in range(len(lines)):
|
||||
if re.match(r" *enum [a-zA-Z0-9_-]+ {.*", lines[i]) and not "gen_enum_str.py" in lines[i]:
|
||||
if in_enum: error("process_file: could not find end of enum starting at line " + str(enums_start.pop()))
|
||||
in_enum = True
|
||||
enums_start.append(i)
|
||||
|
||||
if in_enum:
|
||||
if re.match(r" *[^/*]?.*}.*", lines[i]):
|
||||
enums_stop.append(i)
|
||||
in_enum = False
|
||||
if len(enums_start) != len(enums_stop): error("process_file: could not find end of enum starting at line " + str(enums_start.pop()))
|
||||
|
||||
# create a single string with the enum
|
||||
enums = []
|
||||
for i in range(len(enums_start)):
|
||||
enums.append("")
|
||||
j = enums_start[i]
|
||||
while j <= enums_stop[i]:
|
||||
enums[i] += lines[j]
|
||||
j += 1
|
||||
|
||||
# get name and vars
|
||||
enum_names = []
|
||||
enum_dicts = []
|
||||
spaces = []
|
||||
var = "[a-zA-Z0-9_-]+"
|
||||
enumvar = "(" + var + r"(=*-?\d+)?)"
|
||||
restring = "enum (" + var + "){(" + enumvar + ",)*" + enumvar + ",?}"
|
||||
for i in range(len(enums)):
|
||||
enums[i] = enums[i].replace("\n", "").replace("enum ", "enumü").replace(" ", "").replace("enumü", "enum ")
|
||||
match = re.match(restring, enums[i])
|
||||
if not match: error("Invalid enum at line " + str(enums_start[i]))
|
||||
|
||||
spaces.append(lines[enums_start[i]].find("e"))
|
||||
enum_names.append(match.groups()[0])
|
||||
enum_val = 0
|
||||
enum = {}
|
||||
for m in re.finditer(enumvar, enums[i][len("enum " + enum_names[i]):]):
|
||||
if "=" in m.group():
|
||||
enum_val = int(m.group()[m.group().find("=")+1:])
|
||||
var_end = m.group().find("=")
|
||||
else:
|
||||
var_end = len(m.group())
|
||||
enum[m.group()[0:var_end]] = enum_val
|
||||
enum_val += 1
|
||||
print("enum:", enum_names[i], enum)
|
||||
enum_dicts.append(enum)
|
||||
|
||||
for i in reversed(range(len(enum_names))):
|
||||
lines.insert(enums_stop[i] + 1, getEnumStrF(enum_names[i], enum_dicts[i], spaces[i]))
|
||||
lines[enums_start[i]] = lines[enums_start[i]].strip("\n") + " // processed by gen_enum_str.py\n"
|
||||
|
||||
with open(outputfile, "w") as file:
|
||||
file.writelines(lines)
|
||||
|
||||
|
||||
def process_path(path_):
|
||||
if path.isfile(path_) and path.splitext(path_)[-1] in filetypes:
|
||||
process_file(path_, path_)
|
||||
|
||||
elif path.isdir(path_):
|
||||
for p in listdir(path_):
|
||||
if path.isfile(p) and path.splitext(p)[-1] in filetypes:
|
||||
process_file(p, p)
|
||||
elif path.isdir(p):
|
||||
chdir(p)
|
||||
process_path(p)
|
||||
chdir("..")
|
||||
else:
|
||||
print("Invalid path:", path_)
|
||||
|
||||
|
||||
|
||||
|
||||
def print_help():
|
||||
"""
|
||||
Synposis: get_enum_str.py <Options>... <file>...
|
||||
-o <path> output: file to path. Only when 1 input file.
|
||||
-h --help help
|
||||
-r recurse: Recurse through the directory and process all cpp/hpp files. Implies -i
|
||||
-i in place: Edit the file in place
|
||||
"""
|
||||
|
||||
def missing_arg(arg):
|
||||
print("Missing argument for", arg)
|
||||
exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
output_file = None
|
||||
input_files = []
|
||||
in_place = False
|
||||
recurse = False
|
||||
i = 1
|
||||
while i in range(1, len(argv)):
|
||||
if argv[i] == "--help" or argv[i] == "-h":
|
||||
print_help()
|
||||
exit(0)
|
||||
if argv[i] == "-o":
|
||||
if len(argv) > i + 1: output_file = argv[i+1]
|
||||
else: missing_arg(argv[i])
|
||||
i += 1
|
||||
elif argv[i] == "-r":
|
||||
recurse = True
|
||||
elif argv[i] == "-i":
|
||||
in_place = True
|
||||
else:
|
||||
input_files.append(argv[i])
|
||||
i += 1
|
||||
|
||||
if output_file is None and not in_place and not recurse:
|
||||
error("Missing output path or -i")
|
||||
if output_file and (recurse or in_place or len(input_files) > 1):
|
||||
error("Error: -o does not work with -r, -i or multiple input paths.")
|
||||
if len(input_files) == 0:
|
||||
error("Missing input files.")
|
||||
if in_place:
|
||||
output_file = input_files[0]
|
||||
|
||||
if (recurse):
|
||||
for f in input_files:
|
||||
process_path(f)
|
||||
else:
|
||||
process_file(input_files[0], output_file)
|
||||
|
||||
|
||||
|
||||
|
@ -45,6 +45,7 @@ $(OBJECT_DIRS):
|
||||
#
|
||||
install: $(LIB) $(HEADER_INST)
|
||||
install -D -m 755 $< $(DESTDIR)/usr/lib/$(subst ../,,$<)
|
||||
install -D -m 755 ../gen_enum_str.py $(DESTDIR)/usr/bin/gz-gen-enum
|
||||
|
||||
$(OBJECT_DIR)/%.stamp: %.hpp $(OBJECT_DIR)
|
||||
install -D -m 644 $< $(DESTDIR)/usr/include/gz-util/$<
|
||||
|
Loading…
Reference in New Issue
Block a user