Added lots of features
This commit is contained in:
parent
818956f0a2
commit
2e8498aa90
421
gen_enum_str.py
421
gen_enum_str.py
@ -1,6 +1,6 @@
|
|||||||
#!/bin/python3
|
#!/bin/python3
|
||||||
"""
|
"""
|
||||||
A python script to generate to_string functions for all enumerations in a cpp file.
|
A python script to generate toString functions for all enumerations in a cpp file.
|
||||||
Copyright © 2022 Matthias Quintern.
|
Copyright © 2022 Matthias Quintern.
|
||||||
This software comes with no warranty.
|
This software comes with no warranty.
|
||||||
This software is licensed under the GPL3
|
This software is licensed under the GPL3
|
||||||
@ -10,40 +10,280 @@ from sys import argv, exit
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
filetypes = [".hpp", ".cpp", ".tpp"]
|
# search in header files for enums
|
||||||
|
header_filetypes = [".hpp"]
|
||||||
|
# definition are written to source file having the same name as the header
|
||||||
|
source_filetype = ".cpp"
|
||||||
|
|
||||||
def error(s):
|
def error(s):
|
||||||
print(s)
|
print(s)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
def getEnumStrF(name: str, enum: dict, spaces: int):
|
class Enum:
|
||||||
s = " " * spaces
|
# settings
|
||||||
s += f"const std::map<{name}, std::string> {name}ToStringMap" + " { // generated by gen_enum_str.py\n"
|
include_docstrings = True
|
||||||
for name_, val in enum.items():
|
"""
|
||||||
s += " " * (spaces + 4)
|
include a doxygen docstring before the declarations
|
||||||
s += "{ " + name_ + ", \"" + name_ + "\" },\n"
|
"""
|
||||||
s += " " * spaces + "};\n"
|
docstring_include_generated = True
|
||||||
s += " " * spaces + "const std::string& to_string(" + name + " v) { return " + f"{name}ToStringMap.at(v);" + " }; // generated by gen_enum_str.py\n\n"
|
"""
|
||||||
|
include a list of the enum values in @details
|
||||||
|
"""
|
||||||
|
docstring_include_names = True
|
||||||
|
"""
|
||||||
|
throw exceptions on invalid arguments
|
||||||
|
if false:
|
||||||
|
toString: return empty string
|
||||||
|
fromString: return the last enum value
|
||||||
|
"""
|
||||||
|
throw_exceptions = True
|
||||||
|
# generate fromString for string_view
|
||||||
|
string_view = True
|
||||||
|
def __init__(self, startLine:int, name:str, numbers:list[int], names:list[str], namespace:str=""):
|
||||||
|
self.startLine = startLine
|
||||||
|
self.name = name
|
||||||
|
self.numbers = numbers
|
||||||
|
self.names = names
|
||||||
|
self.namespace = namespace
|
||||||
|
|
||||||
|
def is_range(self) -> tuple[bool, int, int]:
|
||||||
|
"""
|
||||||
|
check if the enum is a continous range
|
||||||
|
returns: bool, min, max
|
||||||
|
"""
|
||||||
|
sorted_numbers = self.numbers.copy()
|
||||||
|
sorted_numbers.sort()
|
||||||
|
if sorted_numbers == range(sorted_numbers[0], sorted_numbers[-1]+1, 1):
|
||||||
|
return True, sorted_numbers[0], sorted_numbers[-1]
|
||||||
|
else:
|
||||||
|
return False, -1, -1
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
if self.namespace:
|
||||||
|
return self.namespace + "::" + self.name
|
||||||
|
else:
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def get_struct_name(self) -> str:
|
||||||
|
return "EnumStringConversion_" + self.name
|
||||||
|
|
||||||
|
def get_names_for_doc(self, qoutes="") -> str:
|
||||||
|
"""
|
||||||
|
returns all names in quotes, separated with a ,
|
||||||
|
"""
|
||||||
|
s = ""
|
||||||
|
for name in self.names:
|
||||||
|
s += qoutes + name + qoutes + ", "
|
||||||
|
if len(s) > 2: return s[:-1]
|
||||||
|
else: return s
|
||||||
|
|
||||||
|
def get_dec_toString(self) -> str:
|
||||||
|
"""
|
||||||
|
return the declaration for the toString method
|
||||||
|
"""
|
||||||
|
s = ""
|
||||||
|
if Enum.include_docstrings:
|
||||||
|
s += "/**\n"
|
||||||
|
s += f' * @brief Convert @ref {self.get_name()} "an enumeration value" to std::string\n'
|
||||||
|
s += f' * @details\n'
|
||||||
|
if Enum.docstring_include_generated:
|
||||||
|
s += f' * This function was generated by gen_enum_str.py\\n\n'
|
||||||
|
if Enum.throw_exceptions:
|
||||||
|
s += f' * Throws gz::InvalidArgument if v is invalid.\n'
|
||||||
|
s += f' * @throws gz::InvalidArgument if v is invalid.\n'
|
||||||
|
else:
|
||||||
|
s += f' * Returns an empty string if v is invalid.\n'
|
||||||
|
s += f' */\n'
|
||||||
|
s += f"std::string toString(const {self.get_name()}& v);\n"
|
||||||
|
return s
|
||||||
|
|
||||||
|
def get_dec_fromString(self) -> str:
|
||||||
|
"""
|
||||||
|
return the declaration(s) for the fromString method(s)
|
||||||
|
"""
|
||||||
|
s = f"template<std::same_as<{self.get_name()}> T>\n"
|
||||||
|
s += f"{self.get_name()} fromString(const std::string& s);\n"
|
||||||
|
|
||||||
|
if Enum.string_view:
|
||||||
|
s += f"template<std::same_as<{self.get_name()}> T>\n"
|
||||||
|
s += f"{self.get_name()} fromString(const std::string_view& sv);\n"
|
||||||
|
|
||||||
|
if Enum.include_docstrings:
|
||||||
|
s += "/**\n"
|
||||||
|
s += f' * @brief Convert a std::string to @ref {self.get_name()} "an enumeration value"\n'
|
||||||
|
s += f' * @details\n'
|
||||||
|
if Enum.docstring_include_generated:
|
||||||
|
s += f' * This function was generated by gen_enum_str.py\\n\n'
|
||||||
|
if Enum.throw_exceptions:
|
||||||
|
s += f' * Throws gz::InvalidArgument if s is invalid.\n'
|
||||||
|
s += f' * @throws gz::InvalidArgument if s is invalid.\n'
|
||||||
|
else:
|
||||||
|
s += f' * Returns {self.get_name()}::{self.names[-1]} if s is invalid.\n'
|
||||||
|
if Enum.docstring_include_names:
|
||||||
|
s += f' * @param v one of: {self.get_names_for_doc()}\n'
|
||||||
|
s += f' */\n'
|
||||||
|
s += f"template<> {self.get_name()} fromString<{self.get_name()}>(const std::string& s);\n"
|
||||||
|
|
||||||
|
if Enum.string_view:
|
||||||
|
if Enum.include_docstrings:
|
||||||
|
s += '/// @brief Convert a std::string_view to @ref {self.get_name()} "an enumeration value"\n'
|
||||||
|
s += f"template<> {self.get_name()} fromString<{self.get_name()}>(const std::string_view& sv);\n"
|
||||||
|
return s
|
||||||
|
|
||||||
|
def get_def_struct(self) -> str:
|
||||||
|
"""
|
||||||
|
return the definition of the EnumStringConversion struct
|
||||||
|
"""
|
||||||
|
s = ""
|
||||||
|
s += f"// Holds maps used by fromString and toString for conversion of {self.name} values\n"
|
||||||
|
s += f"struct {self.get_struct_name()}" + " {\n"
|
||||||
|
s += f" static gz::util::unordered_string_map<{self.get_name()}> name2type;\n"
|
||||||
|
s += f" static std::map<{self.get_name()}, std::string> type2name;\n"
|
||||||
|
s += "}; // generated by gen_enum_str\n\n"
|
||||||
|
|
||||||
|
# name2type
|
||||||
|
s += f"gz::util::unordered_string_map<{self.get_name()}> {self.get_struct_name()}::name2type " + "{\n"
|
||||||
|
for i in range(len(self.names)):
|
||||||
|
# { "ENUM_VAL", namespace::ENUM_NAME::ENUM_VAL },
|
||||||
|
s += '\t{ "' + self.names[i] + '", ' + self.get_name() + "::" + self.names[i] + " },\n"
|
||||||
|
s += "}; // generated by gen_enum_str\n\n"
|
||||||
|
|
||||||
|
# type2name
|
||||||
|
s += f"std::map<{self.get_name()}, std::string> {self.get_struct_name()}::type2name " + "{\n"
|
||||||
|
for i in range(len(self.names)):
|
||||||
|
# { namespace::ENUM_NAME::ENUM_VAL, "ENUM_VAL", },
|
||||||
|
s += '\t{ ' + self.get_name() + "::" + self.names[i] + ', "' + self.names[i] + '" },\n'
|
||||||
|
s += "}; // generated by gen_enum_str\n\n"
|
||||||
|
return s
|
||||||
|
|
||||||
|
def get_def_toString(self) -> str:
|
||||||
|
s = ""
|
||||||
|
s += f"std::string toString(const {self.get_name()}& v) " + "{\n"
|
||||||
|
s += f"\tif ({self.get_struct_name()}::type2name.contains(v)) " + "{\n"
|
||||||
|
s += f"\t\treturn {self.get_struct_name()}::type2name.at(v);\n"
|
||||||
|
s += "\t}\n"
|
||||||
|
s += "\telse {\n"
|
||||||
|
if Enum.throw_exceptions:
|
||||||
|
s += f'\t\tthrow gz::InvalidArgument("InvalidArgument: \'" + std::to_string(static_cast<int>(v)) + "\'", "toString({self.name})");\n'
|
||||||
|
else:
|
||||||
|
s += f'\t\treturn "";\n'
|
||||||
|
s += "\t}\n"
|
||||||
|
s += "} // generated by gen_enum_str\n\n"
|
||||||
|
return s
|
||||||
|
|
||||||
|
def get_def_fromString(self) -> str:
|
||||||
|
s = ""
|
||||||
|
# string_view
|
||||||
|
s += f"template<> {self.get_name()} fromString<{self.get_name()}>(const std::string_view& sv) " + "{\n"
|
||||||
|
s += f"\tif ({self.get_struct_name()}::name2type.contains(sv)) " + "{\n"
|
||||||
|
s += f"\t\treturn {self.get_struct_name()}::name2type.find(sv)->second;\n"
|
||||||
|
s += "\t}\n"
|
||||||
|
s += "\telse {\n"
|
||||||
|
if Enum.throw_exceptions:
|
||||||
|
s += f'\t\tthrow gz::InvalidArgument("InvalidArgument: \'" + std::string(sv) + "\'", "fromString<{self.name}>");\n'
|
||||||
|
else:
|
||||||
|
s += f'\t\treturn {self.get_name()}::{self.names[-1]};\n'
|
||||||
|
s += "\t}\n"
|
||||||
|
s += "} // generated by gen_enum_str\n\n"
|
||||||
|
# string
|
||||||
|
s += f"template<> {self.get_name()} fromString<{self.get_name()}>(const std::string& s) " + "{\n"
|
||||||
|
s += f"\treturn fromString<{self.get_name()}>(std::string_view(s));\n"
|
||||||
|
s += "} // generated by gen_enum_str\n\n"
|
||||||
return s
|
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:
|
def append_enums_to_files(header_file:str, source_file:str, enums: list[Enum], interactive:bool=False):
|
||||||
|
"""
|
||||||
|
put declaration at the end of the source
|
||||||
|
put definition at the end of the header
|
||||||
|
"""
|
||||||
|
if len(enums) == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
print("append_enums_to_files:", header_file, source_file)
|
||||||
|
if not path.isfile(header_file): error("File does not exist:" + header_file)
|
||||||
|
if not path.isfile(source_file):
|
||||||
|
print("Creating source_file: " + source_file)
|
||||||
|
with open(source_file, "w") as file:
|
||||||
|
file.write(f'// generated by gen_enum_str\n#include "{header_file}"\n\n#include <gz-util/util/string.hpp>\n\n')
|
||||||
|
|
||||||
|
with open(header_file, "r") as file:
|
||||||
|
header = file.read()
|
||||||
|
with open(source_file, "r") as file:
|
||||||
|
source = file.read()
|
||||||
|
|
||||||
|
# delete everything between the two comments
|
||||||
|
comment_gen_begin = "// ENUM - STRING CONVERSION BEGIN\n"
|
||||||
|
comment_gen_end = "// ENUM - STRING CONVERSION END\n"
|
||||||
|
|
||||||
|
gen_begin = header.find(comment_gen_begin)
|
||||||
|
gen_end = header.find(comment_gen_end)
|
||||||
|
if gen_begin > 0 and gen_end > gen_begin:
|
||||||
|
header = header[:gen_begin - 1] + header[gen_end + len(comment_gen_end):]
|
||||||
|
|
||||||
|
gen_begin = source.find(comment_gen_begin)
|
||||||
|
gen_end = source.find(comment_gen_end)
|
||||||
|
if gen_begin > 0 and gen_end > gen_begin:
|
||||||
|
source = source[:gen_begin - 1] + source[gen_end + len(comment_gen_end):]
|
||||||
|
|
||||||
|
header += "\n" + comment_gen_begin
|
||||||
|
header += "// do not write your own code between these comment blocks - it will be overwritten when you run gen_enum_str.py again\n"
|
||||||
|
source += "\n" + comment_gen_begin
|
||||||
|
source += "// do not write your own code between these comment blocks - it will be overwritten when you run gen_enum_str.py again\n"
|
||||||
|
for enum in enums:
|
||||||
|
if interactive:
|
||||||
|
answer = input(f"Generate conversion for: {header_file}:{enum.startLine} - enum {enum.name}? (y/n): ")
|
||||||
|
if answer not in "yY":
|
||||||
|
continue
|
||||||
|
header += f"//\n// {enum.name}\n//\n"
|
||||||
|
header += enum.get_dec_toString()
|
||||||
|
header += enum.get_dec_fromString() + "\n"
|
||||||
|
|
||||||
|
source += f"//\n// {enum.name}\n//\n"
|
||||||
|
source += enum.get_def_struct()
|
||||||
|
source += enum.get_def_toString()
|
||||||
|
source += enum.get_def_fromString()
|
||||||
|
header += "\n" + comment_gen_end
|
||||||
|
source += "\n" + comment_gen_end
|
||||||
|
|
||||||
|
|
||||||
|
with open(header_file, "w") as file:
|
||||||
|
file.write(header)
|
||||||
|
with open(source_file, "w") as file:
|
||||||
|
file.write(source)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_enums(headerfile: str) -> list[Enum]:
|
||||||
|
"""
|
||||||
|
find enums in headerfile
|
||||||
|
namespaces are not properly supported, the script can not detect when a namespace is closed.
|
||||||
|
so it only works when you dont open namespaces in namespaces
|
||||||
|
"""
|
||||||
|
# print("get_enums:", headerfile)
|
||||||
|
if not path.isfile(headerfile): error("File does not exist:" + headerfile)
|
||||||
|
|
||||||
|
with open(headerfile, "r") as file:
|
||||||
lines = file.readlines()
|
lines = file.readlines()
|
||||||
|
|
||||||
# FIND ENUMS
|
# FIND ENUMS
|
||||||
enums_start = []
|
enums_start = []
|
||||||
enums_stop = []
|
enums_stop = []
|
||||||
|
enums_namespace = []
|
||||||
|
current_namespace = ""
|
||||||
in_enum = False
|
in_enum = False
|
||||||
for i in range(len(lines)):
|
for i in range(len(lines)):
|
||||||
|
match = re.match(r" *namespace ([a-zA-Z0-9_:]+) +{.*", lines[i])
|
||||||
|
if match:
|
||||||
|
current_namespace = match.groups()[0]
|
||||||
|
|
||||||
if re.match(r" *enum [a-zA-Z0-9_-]+ {.*", lines[i]) and not "gen_enum_str.py" in lines[i]:
|
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()))
|
if in_enum: error("process_file: could not find end of enum starting at line " + str(enums_start.pop()))
|
||||||
in_enum = True
|
in_enum = True
|
||||||
enums_start.append(i)
|
enums_start.append(i)
|
||||||
|
enums_namespace.append(current_namespace)
|
||||||
|
|
||||||
if in_enum:
|
if in_enum:
|
||||||
if re.match(r" *[^/*]?.*}.*", lines[i]):
|
if re.match(r" *[^/*]?.*}.*", lines[i]):
|
||||||
@ -84,84 +324,149 @@ def process_file(inputfile: str, outputfile: str):
|
|||||||
var_end = len(m.group())
|
var_end = len(m.group())
|
||||||
enum[m.group()[0:var_end]] = enum_val
|
enum[m.group()[0:var_end]] = enum_val
|
||||||
enum_val += 1
|
enum_val += 1
|
||||||
print("enum:", enum_names[i], enum)
|
# print("enum:", enum_names[i], enum)
|
||||||
enum_dicts.append(enum)
|
enum_dicts.append(enum)
|
||||||
|
enums = []
|
||||||
for i in reversed(range(len(enum_names))):
|
for i in range(len(enum_names)):
|
||||||
lines.insert(enums_stop[i] + 1, getEnumStrF(enum_names[i], enum_dicts[i], spaces[i]))
|
enums.append(Enum(enums_start[i], enum_names[i], list(enum_dicts[i].values()), list(enum_dicts[i].keys()), enums_namespace[i]))
|
||||||
lines[enums_start[i]] = lines[enums_start[i]].strip("\n") + " // processed by gen_enum_str.py\n"
|
return enums
|
||||||
|
|
||||||
with open(outputfile, "w") as file:
|
|
||||||
file.writelines(lines)
|
|
||||||
|
|
||||||
|
|
||||||
def process_path(path_):
|
# def process_file(inputfile: str, outputfile: str):
|
||||||
if path.isfile(path_) and path.splitext(path_)[-1] in filetypes:
|
# print("process_file:", inputfile)
|
||||||
process_file(path_, path_)
|
# if not path.isfile(inputfile): error("File does not exist:" + inputfile)
|
||||||
|
|
||||||
elif path.isdir(path_):
|
# 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_, interactive:bool=False, recurse:bool=False):
|
||||||
|
# print("Processing path:", path_)
|
||||||
|
if path.isfile(path_) and path.splitext(path_)[-1] in header_filetypes:
|
||||||
|
enums = get_enums(path_)
|
||||||
|
append_enums_to_files(path_, path_.split('.')[0] + source_filetype, enums, interactive)
|
||||||
|
elif recurse:
|
||||||
|
if path.isdir(path_):
|
||||||
for p in listdir(path_):
|
for p in listdir(path_):
|
||||||
if path.isfile(p) and path.splitext(p)[-1] in filetypes:
|
process_path(path_ + "/" + p, interactive, recurse)
|
||||||
process_file(p, p)
|
|
||||||
elif path.isdir(p):
|
|
||||||
chdir(p)
|
|
||||||
process_path(p)
|
|
||||||
chdir("..")
|
|
||||||
else:
|
|
||||||
print("Invalid path:", path_)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def print_help():
|
def print_help():
|
||||||
"""
|
print("""
|
||||||
Synposis: get_enum_str.py <Options>... <file>...
|
Synposis: get_enum_str.py <Options>... <file>...
|
||||||
-o <path> output: file to path. Only when 1 input file.
|
get_enum_str.py <Options>... -r <path>...
|
||||||
-h --help help
|
-h --help help
|
||||||
-r recurse: Recurse through the directory and process all cpp/hpp files. Implies -i
|
-r recurse: Recurse through given paths process all files.
|
||||||
-i in place: Edit the file in place
|
-i interactive: prompt for every enumeration
|
||||||
"""
|
--no-docs turn off docstring generation
|
||||||
|
--docs-no-names do not list names of enumeration values in docstring
|
||||||
|
--docs-no-gen do not put "generated by gen_enum_str" in docstring
|
||||||
|
--no-throw return empty string/last enum value if the argument for to/fromString is invalid.
|
||||||
|
This would normaly throw gz::InvalidArgument
|
||||||
|
This option does not make the functions noexcept!
|
||||||
|
|
||||||
|
If the generated code produces errors:
|
||||||
|
- check that necessary headers are included in the source file:
|
||||||
|
- gz-util/string.hpp
|
||||||
|
- gz-util/exceptions.hpp (unless you use --no-throw)
|
||||||
|
- check the namespaces of the enumerations, the generated code should be in global namespace
|
||||||
|
nested namespace are not supported, you will have to correct that if you use them
|
||||||
|
""")
|
||||||
|
|
||||||
def missing_arg(arg):
|
def missing_arg(arg):
|
||||||
print("Missing argument for", arg)
|
print("Missing argument for", arg)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
output_file = None
|
|
||||||
input_files = []
|
input_files = []
|
||||||
in_place = False
|
|
||||||
recurse = False
|
recurse = False
|
||||||
|
interactive = False
|
||||||
i = 1
|
i = 1
|
||||||
while i in range(1, len(argv)):
|
while i in range(1, len(argv)):
|
||||||
if argv[i] == "--help" or argv[i] == "-h":
|
if argv[i] == "--help" or argv[i] == "-h":
|
||||||
print_help()
|
print_help()
|
||||||
exit(0)
|
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":
|
elif argv[i] == "-r":
|
||||||
recurse = True
|
recurse = True
|
||||||
elif argv[i] == "-i":
|
elif argv[i] == "-i":
|
||||||
in_place = True
|
interactive = True
|
||||||
|
elif argv[i] == "--no-throw":
|
||||||
|
Enum.throw_exceptions = False
|
||||||
|
elif argv[i] == "--no-docs":
|
||||||
|
Enum.include_docstrings = False
|
||||||
|
elif argv[i] == "--docs-no-names":
|
||||||
|
Enum.docstring_include_names = False
|
||||||
|
elif argv[i] == "--docs-no-gen":
|
||||||
|
Enum.docstring_include_generated = False
|
||||||
else:
|
else:
|
||||||
input_files.append(argv[i])
|
input_files.append(argv[i])
|
||||||
i += 1
|
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:
|
if len(input_files) == 0:
|
||||||
error("Missing input files.")
|
error("Missing input files/paths.")
|
||||||
if in_place:
|
|
||||||
output_file = input_files[0]
|
|
||||||
|
|
||||||
if (recurse):
|
|
||||||
for f in input_files:
|
for f in input_files:
|
||||||
process_path(f)
|
process_path(path.abspath(f), recurse=recurse, interactive=interactive)
|
||||||
else:
|
|
||||||
process_file(input_files[0], output_file)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user