2 from __future__
import print_function
9 r = re.compile(
r"([_\/:][a-z]|[_\/:][0-9])")
12 tokens = r.split(name, 1)
15 if tokens[1][0] ==
"_":
19 + tokens[0][1:].lower()
20 + tokens[1][1].upper()
23 ret += tokens[0].lower() + tokens[1][1].upper()
28 + tokens[0][1:].lower()
30 + tokens[1][1].upper()
33 ret += tokens[0].lower() + tokens[1][0] + tokens[1][1].upper()
34 tokens = r.split(tokens[2], 1)
38 ret += tokens[0][0].upper() + tokens[0][1:].lower() + tokens[1][0]
40 ret += tokens[0][0].upper() + tokens[0][1:].lower()
42 ret += tokens[0].lower()
48 r = re.compile(
r"([A-Za-z][0-9]|[0-9][A-z]|[a-z][A-Z]|[A-Z][A-Z][a-z]|[_\/:][A-z])")
50 tokens = r.split(name, 1)
55 or tokens[1][0] ==
":"
56 or tokens[1][0] ==
"_"
57 or tokens[1][1] ==
"_"
59 ret += tokens[0].lower() + tokens[1][0].lower() + tokens[1][1:].lower()
63 + tokens[1][0].lower()
65 + tokens[1][1:].lower()
67 tokens = r.split(tokens[2], 1)
69 ret += tokens[0].lower()
77 print(*args, file=sys.stderr, **kwargs)
81 sys.stderr.write(msg +
"\n")
99 ret +=
",\n " + (d[
"Name"]) +
"(_" + (d[
"Name"]) +
") "
104 if data[
"Value"]
is None:
106 elif data[
"Value"] ==
"{}":
113 if data[
"Value"] ==
None:
116 return " = " + data[
"Value"]
129 if "Required" in d
and not d[
"Required"]:
142 if "Required" in data:
143 return " " + data[
"Type"] +
" " + (data[
"Name"]) +
";\n"
150 if type_in ==
"std::string":
151 return "boost::any_cast<" + type_in +
">(prop.Get())"
152 elif type_in ==
"exotica::Initializer" or type_in ==
"Initializer":
153 return "prop.IsInitializerVectorType()?boost::any_cast<std::vector<exotica::Initializer>>(prop.Get()).at(0):boost::any_cast<exotica::Initializer>(prop.Get())"
155 type_in ==
"std::vector<Initializer>"
156 or type_in ==
"std::vector<exotica::Initializer>"
158 return "boost::any_cast<std::vector<exotica::Initializer>>(prop.Get())"
159 elif type_in ==
"Eigen::VectorXd":
160 parser =
"ParseVector<double,Eigen::Dynamic>"
161 elif type_in ==
"Eigen::Vector4d":
162 parser =
"ParseVector<double,4>"
163 elif type_in ==
"Eigen::Vector3d":
164 parser =
"ParseVector<double,3>"
165 elif type_in ==
"Eigen::Vector2d":
166 parser =
"ParseVector<double,2>"
167 elif type_in ==
"Eigen::VectorXi":
168 parser =
"ParseVector<int,Eigen::Dynamic>"
169 elif type_in ==
"bool":
171 elif type_in ==
"double":
172 parser =
"ParseDouble"
173 elif type_in ==
"int":
175 elif type_in ==
"std::vector<std::string>":
177 elif type_in ==
"std::vector<int>":
178 parser =
"ParseIntList"
179 elif type_in ==
"std::vector<bool>":
180 parser =
"ParseBoolList"
182 eprint(
"Unknown data type '" + type_in +
"'")
186 "prop.IsStringType()?"
188 +
"(boost::any_cast<std::string>(prop.Get())):boost::any_cast<"
195 if "Required" in data:
197 ' ret.properties_.emplace("'
212 if "Required" in data:
214 ' if (other.HasProperty("'
216 +
'")) { const Property& prop = other.properties_.at("'
218 +
'"); if(prop.IsSet()) {'
230 if "Required" in d
and d[
"Required"]:
236 if "Required" in data
and data[
"Required"]:
238 ' if(!other.HasProperty("'
240 +
'") || !other.properties_.at("'
242 +
'").IsSet()) ThrowPretty("Initializer '
244 +
" requires property "
252 def construct(namespace, class_name_orig, data, include):
253 class_name = class_name_orig +
"Initializer"
255 """// This file was automatically generated. Do not edit this file!
256 #ifndef INITIALIZER_"""
261 #define INITIALIZER_"""
267 #include <exotica_core/property.h>
271 inline std::vector<Initializer> Get"""
281 +
" : public InitializerBase"
285 static std::string GetContainerName() { return """
296 +
"() : InitializerBase()"
308 +
") : InitializerBase()"
316 +
"""(const Initializer& other) : """
333 virtual Initializer GetTemplate() const
335 return (Initializer)"""
340 virtual std::vector<Initializer> GetAllTemplates() const
347 virtual void Check(const Initializer& """
354 ret +=
check(d, class_name)
357 operator Initializer()
359 Initializer ret(GetContainerName());
363 ret +=
""" return ret;
379 +
"""_initializers_numerator.h>
384 ret +=
"#include <" + i +
".h>\n"
392 if line.startswith(
"//"):
395 last = line.find(
";")
397 line = line[0:last].strip()
399 last = line.find(
"//")
401 line = line[0:last].strip()
408 if line.startswith(
"include"):
410 "Include": line[7:].strip().strip(
">").strip(
"<").strip(
'"'),
411 "Code": line.strip(),
413 if line.startswith(
"extend"):
415 "Extends": line[6:].strip().strip(
">").strip(
"<").strip(
'"'),
416 "Code": line.strip(),
418 if line.startswith(
"class"):
420 "ClassName": line[5:].strip().strip(
">").strip(
"<").strip(
'"'),
421 "Code": line.strip(),
425 eprint(
"Can't find ';' in '" + function_name +
"', on line " + str(line_number))
429 if line.startswith(
"Required"):
431 elif line.startswith(
"Optional"):
435 "Can't parse 'Required/Optional' tag in '"
447 has_default_arg =
not (eq == -1)
449 value = line[eq + 1 : last]
453 name_start = line[0:eq].strip().rfind(
" ")
454 name = line[name_start:eq].strip()
455 field_type = line[9:name_start].strip()
456 if not has_default_arg:
457 eprint(
"Optional parameter '" + name +
"' requires a default argument!")
459 name_start = line[0:last].strip().rfind(
" ")
460 name = line[name_start:last].strip()
461 field_type = line[9:name_start].strip()
463 return {
"Required": required,
"Type": field_type,
"Name": name,
"Value": value}
467 with open(file_name)
as f:
468 lines = f.readlines()
480 if d[
"Required"] ==
False:
485 "Required properties_ have to come before Optional ones, in '"
493 include.append(d[
"Include"])
495 extends.append(d[
"Extends"])
497 names.append(d[
"ClassName"])
499 eprint(
"Could not parse initializer class name in '" + file_name +
"'!")
502 return {
"Data": data,
"Include": include,
"Extends": extends,
"ClassName": names[0]}
507 if d[
"Type"] == type_name
and d[
"Name"] == name:
528 class_name = file_content[
"ClassName"]
529 if "Extends" in file_content:
530 for e
in file_content[
"Extends"]:
534 for d
in search_dirs:
535 ff = d +
"/share/" + ext[0] +
"/init/" + ext[1] +
".in"
536 if os.path.isfile(ff):
540 eprint(
"Cannot find extension '" + e +
"'!")
541 content[
"Extends"].append(e)
544 if "Data" in file_content:
545 for d
in file_content[
"Data"]:
548 for e
in content[
"Data"]:
549 if e[
"Name"] == d[
"Name"]:
550 e[
"Value"] = d[
"Value"]
552 d[
"Class"] = class_name
553 content[
"Data"].append(d)
554 if "Include" in file_content:
555 for i
in file_content[
"Include"]:
557 content[
"Include"].append(i)
559 content[
"ClassName"] = class_name
574 def generate(input_files, output_files, namespace, search_dirs, devel_dir):
575 print(
"Generating " + output_files)
577 input_files, search_dirs, {
"Data": [],
"Include": [],
"Extends": []}
580 namespace, content[
"ClassName"],
sort_data(content[
"Data"]), content[
"Include"]
582 path = os.path.dirname(output_files)
583 if not os.path.exists(path):
585 with open(output_files,
"w")
as f:
587 return content[
"ClassName"]
592 """// This file was automatically generated. Do not edit this file!
593 #ifndef INITIALIZE_PROJECT_HEADER_"""
596 #define INITIALIZE_PROJECT_HEADER_"""
600 #include <exotica_core/property.h>
603 for init
in class_inits:
604 ret +=
"#include <" + namespace +
"/" + init[0] +
"_initializer.h>\n"
611 inline std::vector<Initializer> Get"""
615 std::vector<Initializer> ret;
618 for init
in class_inits:
619 ret +=
" ret.push_back(" + init[1] +
"Initializer().GetTemplate());\n"
620 ret +=
""" return ret;
627 path = os.path.dirname(file_name)
628 if not os.path.exists(path):
630 with open(file_name,
"w")
as f:
634 if __name__ ==
"__main__":
635 if len(sys.argv) > 5:
637 n = int((len(sys.argv) - offset) / 2)
638 namespace = sys.argv[1]
639 search_dirs = sys.argv[2].split(
":")
640 devel_dir = sys.argv[3]
641 class_inits_header_file = sys.argv[4]
642 if not os.path.exists(devel_dir +
"/init"):
643 os.makedirs(devel_dir +
"/init")
645 for i
in range(0, n):
646 input_files = sys.argv[offset + i]
647 class_name = os.path.basename(sys.argv[offset + i][0:-3])
648 with open(input_files,
"r")
as fi:
649 with open(devel_dir +
"/init/" + class_name +
".in",
"w")
as f:
653 for i
in range(0, n):
654 input_files = sys.argv[offset + i]
655 output_files = sys.argv[offset + n + i]
656 class_file_name = os.path.basename(sys.argv[offset + i][0:-3])
661 input_files, output_files, namespace, search_dirs, devel_dir
668 eprint(
"Initializer generation failure: invalid arguments!")