23extern std::string
alnum_name(
const std::string& in);
25extern void print_description(std::ostream& s,
const std::string& text,
const char * dx);
26extern void print_indented(std::ostream& s,
const std::string& text,
const char * dx);
28extern void gen_dump_application(std::ostream& s, std::list<std::string>& class_names,
const std::string& cpp_ns_name,
const std::string& cpp_hdr_dir,
const char * conf_header,
const char * conf_name,
const char * headres_prologue,
const char * main_function_prologue);
29extern void write_info_file(std::ostream& s,
const std::string& cpp_namespace,
const std::string& cpp_header_dir,
const std::set<
const oks::OksClass *, std::less<const oks::OksClass *> >& class_names);
33extern void parse_arguments(
int argc,
char *argv[], std::list<std::string>& class_names, std::list<std::string>& file_names, std::list<std::string>& include_dirs, std::list<std::string>& user_classes, std::string& cpp_dir_name, std::string& cpp_ns_name, std::string& cpp_hdr_dir, std::string& info_file_name,
bool& verbose);
35extern std::string
int2dx(
int level);
59 for (
const auto& i : *sclasses)
73std::string
ltrim(
const std::string &s)
75 size_t start = s.find_first_not_of(
WHITESPACE);
76 return (start == std::string::npos) ?
"" : s.substr(start);
79std::string
rtrim(
const std::string &s)
82 return (end == std::string::npos) ?
"" : s.substr(0, end + 1);
85std::string
trim(
const std::string &s) {
97 std::ostream& cpp_file,
98 const std::string& cpp_ns_name,
99 const std::string& cpp_hdr_dir,
109 cpp_file <<
" // include files for classes used in inheritance hierarchy\n\n";
111 for (
const auto& i : *super_list)
114 cpp_file <<
"#include \"" <<
get_include_dir(c, cl_info, cpp_hdr_dir) <<
".hpp\"\n";
118 cpp_file << std::endl;
124 std::set<oks::OksClass*> rclasses;
129 rclasses.insert(i->get_class_type());
132 if (
const std::list<oks::OksMethod*> *mlist = cl->
direct_methods())
134 for (
const auto &i : *mlist)
138 const std::string mp(mi->get_prototype());
141 const std::string s(j.second->get_name());
142 std::string::size_type idx = mp.find(s);
143 if (idx != std::string::npos && (idx == 0 || !isalnum(mp[idx - 1])) && !isalnum(mp[idx + s.size()]))
144 rclasses.insert(j.second);
152 for (
const auto &c : rclasses)
158 ClassInfo::Map::const_iterator idx = cl_info.find(c);
159 ns_info.
add((idx != cl_info.end() ? (*idx).second.get_namespace() : cpp_ns_name),
alnum_name(c->get_name()));
162 if (!ns_info.
empty())
164 cpp_file <<
" // forward declaration for classes used in relationships and algorithms\n\n";
165 ns_info.
print(cpp_file, 0);
172 if (
const std::list<oks::OksMethod*> *mlist = cl->
direct_methods())
173 for (
const auto &i : *mlist)
177 cpp_file <<
" // prologue of method " << cl->
get_name() <<
"::" << i->get_name() <<
"()\n";
185 std::string ns_dx =
int2dx(ns_level);
186 std::string ns_dx2 = ns_dx +
" ";
188 const char * dx = ns_dx.c_str();
189 const char * dx2 = ns_dx2.c_str();
195 std::string txt(
"Declares methods to get and put values of attributes / relationships, to print and to destroy object.\n");
199 "The methods can throw several exceptions:\n"
201 " <li><code>conffwk.NotFoundException</code> - in case of wrong attribute or relationship name (e.g. in case of database schema modification)\n"
202 " <li><code>conffwk.SystemException</code> - in case of system problems (communication or implementation database failure, schema modification, object destruction, etc.)\n"
205 "In addition the methods modifying database (set value, destroy object) can throw <code>conffwk.NotAllowedException</code> "
206 "exception in case, if there are no write access rights or database is already locked by other process.\n";
215 txt +=
"@author oksdalgen\n";
217 cpp_file << std::endl;
223 cpp_file << dx <<
"class " << name <<
" : ";
229 for (std::list<std::string*>::const_iterator i = super_list->begin(); i != super_list->end();)
233 if (++i != super_list->end())
239 cpp_file <<
"public virtual dunedaq::conffwk::DalObject";
242 cpp_file <<
" {\n\n";
247 << dx <<
" friend class conffwk::Configuration;\n"
248 << dx <<
" friend class conffwk::DalObject;\n"
249 << dx <<
" friend class conffwk::DalFactory;\n"
250 << dx <<
" friend class conffwk::DalRegistry;\n\n"
251 << dx <<
" protected:\n\n"
252 << dx <<
" " << name <<
"(conffwk::DalRegistry& db, const conffwk::ConfigObject& obj) noexcept;\n"
253 << dx <<
" virtual ~" << name <<
"() noexcept;\n"
254 << dx <<
" virtual void init(bool init_children);\n\n"
255 << dx <<
" public:\n\n"
256 << dx <<
" /** The name of the configuration class. */\n\n"
257 << dx <<
" static const std::string& s_class_name;\n\n\n"
259 << dx <<
" * \\brief Print details of the " << name <<
" object.\n"
261 << dx <<
" * Parameters are:\n"
262 << dx <<
" * \\param offset number of spaces to shift object right (useful to print nested objects)\n"
263 << dx <<
" * \\param print_header if false, do not print object header (to print attributes of base classes)\n"
264 << dx <<
" * \\param s output stream\n"
266 << dx <<
" virtual void print(unsigned int offset, bool print_header, std::ostream& s) const;\n\n\n"
268 << dx <<
" * \\brief Get values of relationships and results of some algorithms as a vector of dunedaq::conffwk::DalObject pointers.\n"
270 << dx <<
" * Parameters are:\n"
271 << dx <<
" * \\param name name of the relationship or algorithm\n"
272 << dx <<
" * \\return value of relationship or result of algorithm\n"
273 << dx <<
" * \\throw std::exception if there is no relationship or algorithm with such name in this and base classes\n"
275 << dx <<
" virtual std::vector<const dunedaq::conffwk::DalObject *> get(const std::string& name, bool upcast_unregistered = true) const;\n\n\n"
276 << dx <<
" protected:\n\n"
277 << dx <<
" bool get(const std::string& name, std::vector<const dunedaq::conffwk::DalObject *>& vec, bool upcast_unregistered, bool first_call) const;\n\n\n";
285 cpp_file << dx <<
" private:\n\n";
293 for (
const auto& i : *alist)
295 const std::string aname(
alnum_name(i->get_name()));
296 std::string cpp_type =
get_type(i->get_data_type(),
true);
298 if (i->get_is_multi_values())
299 cpp_file << dx <<
" std::vector<" << cpp_type <<
"> m_" << aname <<
";\n";
301 cpp_file << dx <<
" " << cpp_type <<
" m_" << aname <<
";\n";
312 for (
const auto& i : *rlist)
314 const std::string rname(
alnum_name(i->get_name()));
317 cpp_file << dx <<
" std::vector<const " << full_class_name <<
"*> m_" << rname <<
";\n";
319 cpp_file << dx <<
" const " << full_class_name <<
"* m_" << rname <<
";\n";
326 if (
const std::list<oks::OksMethod*> * mlist = cl->
direct_methods())
328 for (
const auto& i : *mlist)
333 if (!method_extension.empty())
335 cpp_file <<
"\n" << dx <<
" // extension of method " << cl->
get_name() <<
"::" << i->get_name() <<
"()\n";
343 cpp_file << std::endl << std::endl << dx <<
" public:\n\n";
356 cpp_file << dx <<
" // attribute names\n\n";
358 for (
const auto& i : *alist)
360 const std::string& aname(i->get_name());
361 cpp_file << dx <<
" inline static const std::string s_" <<
alnum_name(aname) <<
" = \"" << aname <<
"\";\n";
366 for (
const auto& i : *alist)
368 const std::string& cpp_aname(
alnum_name(i->get_name()));
369 cpp_file << dx <<
" static const std::string& __get_" << cpp_aname <<
"_str() noexcept { return s_" << cpp_aname <<
"; }\n";
372 cpp_file << std::endl << std::endl;
374 for (
const auto& i : *alist)
376 const std::string aname(
alnum_name(i->get_name()));
382 std::string description(
"Valid enumeration values to compare with value returned by get_");
383 description += aname;
384 description +=
"() and to pass value to set_";
385 description += aname;
386 description +=
"() methods.";
390 description +=
"\nUse toString() method to compare and to pass the values. Do not use name() method.";
396 while (!(token = t.
next()).empty())
398 cpp_file << dx <<
" inline static const std::string " <<
capitalize_name(
alnum_name(token)) <<
" = \"" << token <<
"\";\n";
401 cpp_file << dx <<
" };\n\n";
408 std::string description(
"Get \"");
409 description += i->get_name();
410 description +=
"\" attribute value.\n\n";
411 description += i->get_description();
413 std::string description2(
"\\brief ");
414 description2 += description;
415 description2 +=
"\n\\return the attribute value\n";
416 description2 +=
"\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
423 cpp_file << dx <<
" ";
425 std::string cpp_type =
get_type(i->get_data_type(),
true);
427 if (i->get_is_multi_values())
429 cpp_file <<
"const std::vector<" << cpp_type <<
">&";
433 if (cpp_type ==
"std::string")
434 cpp_file <<
"const std::string&";
436 cpp_file << cpp_type;
440 << dx <<
" get_" << aname <<
"() const\n"
442 << dx <<
" std::lock_guard scoped_lock(m_mutex);\n"
443 << dx <<
" check();\n"
444 << dx <<
" check_init();\n"
445 << dx <<
" return m_" << aname <<
";\n"
451 std::string description(
"Set \"");
452 description += i->get_name();
453 description +=
"\" attribute value.\n\n";
454 description += i->get_description();
456 std::string description2(
"\\brief ");
457 description2 += description;
458 description2 +=
"\n\\param value new attribute value\n";
459 description2 +=
"\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
466 cpp_file << dx <<
" void\n" << dx <<
" set_" << aname <<
'(';
468 if (i->get_is_multi_values())
470 cpp_file <<
"const std::vector<" << cpp_type <<
">&";
474 if (cpp_type ==
"std::string")
476 cpp_file <<
"const std::string&";
480 cpp_file << cpp_type;
484 cpp_file <<
" value)\n"
486 << dx <<
" std::lock_guard scoped_lock(m_mutex);\n"
487 << dx <<
" check();\n"
488 << dx <<
" clear();\n"
493 cpp_file <<
"set_by_ref";
497 cpp_file <<
"set_enum";
501 cpp_file <<
"set_class";
505 cpp_file <<
"set_date";
509 cpp_file <<
"set_time";
513 cpp_file <<
"set_by_val";
516 cpp_file <<
"(s_" << aname <<
", value);\n"
532 cpp_file << dx <<
" // relationship names\n\n";
534 for (
const auto& i : *rlist)
536 const std::string& rname(i->get_name());
537 cpp_file << dx <<
" inline static const std::string s_" <<
alnum_name(rname) <<
" = \"" << rname <<
"\";\n";
542 for (
const auto& i : *rlist)
544 const std::string& cpp_rname(
alnum_name(i->get_name()));
545 cpp_file << dx <<
" static const std::string& __get_" << cpp_rname <<
"_str() noexcept { return s_" << cpp_rname <<
"; }\n";
548 cpp_file << std::endl << std::endl;
550 for (
const auto& i : *rlist)
556 std::string description(
"Get \"");
557 description += i->get_name();
558 description +=
"\" relationship value.\n\n";
559 description += i->get_description();
561 std::string description2(
"\\brief ");
562 description2 += description;
563 description2 +=
"\n\\return the relationship value\n";
564 description2 +=
"\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
571 cpp_file << dx <<
" const ";
573 const std::string rname(
alnum_name(i->get_name()));
578 cpp_file <<
"std::vector<const " << full_cpp_class_name <<
"*>&";
582 cpp_file << full_cpp_class_name <<
" *";
586 << dx <<
" get_" << rname <<
"() const\n"
588 << dx <<
" std::lock_guard scoped_lock(m_mutex);\n"
589 << dx <<
" check();\n"
590 << dx <<
" check_init();\n";
597 << dx <<
" if (!m_" << rname <<
")\n"
599 << dx <<
" std::ostringstream text;\n"
600 << dx <<
" text << \"relationship \\\"\" << s_" << rname <<
" << \"\\\" of object \" << this << \" is not set\";\n"
601 << dx <<
" throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());\n"
607 << dx <<
" if (m_" << rname <<
".empty())\n"
609 << dx <<
" std::ostringstream text;\n"
610 << dx <<
" text << \"relationship \\\"\" << s_" << rname <<
" << \"\\\" of object \" << this << \" is empty\";\n"
611 << dx <<
" throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());\n"
617 << dx <<
" return m_" << rname <<
";\n"
623 std::string description(
"Set \"");
624 description += i->get_name();
625 description +=
"\" relationship value.\n\n";
626 description += i->get_description();
628 std::string description2(
"\\brief ");
629 description2 += description;
630 description2 +=
"\n\\param value new relationship value\n";
631 description2 +=
"\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
636 cpp_file << dx <<
" void\n" << dx <<
" set_" << rname <<
"(const ";
640 cpp_file <<
"std::vector<const " << full_cpp_class_name <<
"*>&";
644 cpp_file << full_cpp_class_name <<
" *";
647 cpp_file <<
" value);\n\n";
655 if (
const std::list<oks::OksMethod*> *mlist = cl->
direct_methods())
657 bool cpp_comment_is_printed =
false;
659 for (
const auto& i : *mlist)
666 if (cpp_comment_is_printed ==
false)
668 cpp_file << std::endl << dx <<
" public:\n\n" << dx <<
" // user-defined algorithms\n\n";
669 cpp_comment_is_printed =
true;
682 cpp_file << dx <<
" " << mi->get_prototype() <<
";\n";
688 if (!public_method_extension.empty())
690 cpp_file <<
"\n" <<
" // extension of method " << cl->
get_name() <<
"::" << i->get_name() <<
"()\n";
701 cpp_file << dx <<
"};\n\n";
707 << dx <<
" // out stream operator\n\n"
708 << dx <<
"inline std::ostream& operator<<(std::ostream& s, const " << name <<
"& obj)\n"
710 << dx <<
" return obj.print_object(s);\n"
712 << dx <<
"typedef std::vector<const " << name <<
"*>::const_iterator " << name <<
"Iterator;\n\n";
722 if (
const std::list<oks::OksMethod*> * mlist = cl->
direct_methods())
724 for (
const auto & i : *mlist)
729 cpp_file <<
" // epilogue of method " << cl->
get_name() <<
"::" << i->get_name() <<
"()\n";
739set2out(std::ostream&
out,
const std::set<std::string>& data,
bool& is_first)
741 for (
const auto& x : data)
747 out <<
'\"' << x <<
"()\"";
755 cpp_s <<
"#include \"logging/Logging.hpp\"\n\n";
759 std::set<oks::OksClass *> rclasses;
765 for (
const auto& i : *rlist)
775 if (
const std::list<oks::OksMethod*> * mlist = cl->
direct_methods())
777 for (
const auto& i : *mlist)
781 std::string prototype(mi->get_prototype());
782 std::string::size_type idx = prototype.find(
'(');
787 if (idx != std::string::npos)
792 while (isspace(prototype[idx]) && idx > 0)
796 while (!isspace(prototype[idx]) && idx > 0)
800 prototype.erase(idx + 1);
803 prototype.erase(std::remove_if(prototype.begin(), prototype.end(), [](
unsigned char x)
804 { return std::isspace(x);}), prototype.end());
806 if (prototype.empty() ==
false)
808 idx = prototype.find(
'*');
809 prototype.erase(idx--);
811 if (idx != std::string::npos)
813 while (isalnum(prototype[idx]) && idx > 0)
816 if(idx == 0 &&
get_add_algo_1(mi) && prototype.find(
"const") == 0)
817 prototype.erase(0, 5);
819 prototype.erase(0, idx+1);
831 if (!rclasses.empty())
833 cpp_s <<
" // include files for classes used in relationships and algorithms\n\n";
835 for (
const auto& j : rclasses)
837 cpp_s <<
"#include \"" <<
get_include_dir(j, cl_info, cpp_hdr_dir) <<
".hpp\"\n";
840 cpp_s << std::endl << std::endl;
847 std::string ns_dx =
int2dx(ns_level);
848 std::string ns_dx2 = ns_dx +
" ";
850 const char * dx = ns_dx.c_str();
851 const char * dx2 = ns_dx2.c_str();
856 cpp_s << dx <<
"const std::string& " << name <<
"::s_class_name(dunedaq::conffwk::DalFactory::instance().get_known_class_name_ref(\"" << name <<
"\"));\n\n";
858 std::set<std::string> algo_n_set, algo_1_set;
860 if (
const std::list<oks::OksMethod*> * mlist = cl->
direct_methods())
862 for (
const auto& i : *mlist)
866 std::string prototype(mi->get_prototype());
867 std::string::size_type idx = prototype.find(
'(');
869 if (idx != std::string::npos)
874 while (isspace(prototype[idx]) && idx > 0)
878 prototype.erase(idx+1);
881 while (!isspace(prototype[idx]) && idx > 0)
886 prototype.erase(0, idx+1);
890 algo_n_set.insert(prototype);
894 algo_1_set.insert(prototype);
905 << dx <<
" // the factory initializer\n\n"
906 << dx <<
"static struct __" << name <<
"_Registrator\n"
908 << dx <<
" __" << name <<
"_Registrator()\n"
910 << dx <<
" dunedaq::conffwk::DalFactory::instance().register_dal_class<" << name <<
">(\"" << cl->
get_name() <<
"\");\n"
912 << dx <<
" } registrator;\n\n\n";
918 << dx <<
" // the constructor\n\n"
919 << dx << name <<
"::" << name <<
"(conffwk::DalRegistry& db, const conffwk::ConfigObject& o) noexcept :\n"
920 << dx <<
" " <<
"dunedaq::conffwk::DalObject(db, o)";
925 std::list<std::string> initializer_list;
929 for(
auto & i : *slist)
937 for (std::list<oks::OksRelationship*>::const_iterator i = rlist->begin(); i != rlist->end(); ++i)
941 initializer_list.push_back(std::string(
"m_") +
alnum_name((*i)->get_name()) +
" (nullptr)");
947 if(
const std::list<oks::OksMethod*> * mlist = cl->
direct_methods())
949 for (std::list<oks::OksMethod*>::const_iterator i = mlist->begin(); i != mlist->end(); ++i)
954 member_initializer.erase(remove(member_initializer.begin(), member_initializer.end(),
'\n'), member_initializer.end());
956 if (!member_initializer.empty())
958 initializer_list.push_back(member_initializer);
964 if (initializer_list.empty() ==
false)
966 for (
auto & i : initializer_list)
968 cpp_s <<
",\n" << dx <<
" " << i;
983 << dx <<
"void " << name <<
"::print(unsigned int indent, bool print_header, std::ostream& s) const\n"
985 << dx <<
" check_init();\n\n"
989 cpp_s << dx <<
" const std::string str(indent+2, ' ');\n";
993 << dx <<
" if (print_header)\n"
994 << dx <<
" p_hdr(s, indent, s_class_name";
996 if(!cpp_ns_name.empty()) {
997 cpp_s <<
", \"" << cpp_ns_name <<
'\"';
1005 cpp_s <<
"\n\n" << dx <<
" // print direct super-classes\n\n";
1007 for (
const auto& i : *slist)
1012 cpp_s <<
"\n\n" << dx <<
" // print direct attributes\n\n";
1014 for(
const auto& i : *alist) {
1015 const std::string aname(
alnum_name(i->get_name()));
1018 if (i->get_is_multi_values())
1019 cpp_s << dx <<
" dunedaq::conffwk::p_mv_attr" << abase <<
"(s, str, s_" << aname <<
", m_" << aname <<
");\n";
1021 cpp_s << dx <<
" dunedaq::conffwk::p_sv_attr" << abase <<
"(s, str, s_" << aname <<
", m_" << aname <<
");\n";
1027 cpp_s <<
"\n\n" << dx <<
" // print direct relationships\n\n";
1029 for (
const auto& i : *rlist)
1031 const std::string rname(
alnum_name(i->get_name()));
1035 if (i->get_is_composite())
1036 cpp_s << dx <<
" dunedaq::conffwk::p_mv_rel(s, str, indent, s_" << rname <<
", m_" << rname <<
");\n";
1038 cpp_s << dx <<
" dunedaq::conffwk::p_mv_rel(s, str, s_" << rname <<
", m_" << rname <<
");\n";
1042 if (i->get_is_composite())
1043 cpp_s << dx <<
" dunedaq::conffwk::p_sv_rel(s, str, indent, s_" << rname <<
", m_" << rname <<
");\n";
1045 cpp_s << dx <<
" dunedaq::conffwk::p_sv_rel(s, str, s_" << rname <<
", m_" << rname <<
");\n";
1050 cpp_s << dx <<
" }\n"
1051 << dx <<
" catch (dunedaq::conffwk::Exception & ex) {\n"
1052 << dx <<
" dunedaq::conffwk::DalObject::p_error(s, ex);\n"
1060 const char * ic_value = (
1064 :
"/* init_children */"
1068 << dx <<
"void " << name <<
"::init(bool " << ic_value <<
")\n"
1075 << dx <<
" p_was_read = true;\n"
1076 << dx <<
" increment_read();\n";
1083 for (
const auto& i : *slist)
1085 cpp_s << dx <<
" " <<
alnum_name(*i) <<
"::init(init_children);\n";
1087 if (!slist->empty())
1091 cpp_s << dx <<
" TLOG_DEBUG(5) << \"read object \" << this << \" (class \" << s_class_name << \')\';\n";
1097 if ((alist && !alist->empty()) || (rlist && !rlist->empty()))
1099 cpp_s << std::endl << dx <<
" try {\n";
1105 for (
const auto& i : *alist)
1107 const std::string cpp_name =
alnum_name(i->get_name());
1108 cpp_s << dx <<
" p_obj.get(s_" << cpp_name <<
", m_" << cpp_name <<
");\n";
1116 for (
const auto& i : *rlist)
1118 const std::string& rname = i->get_name();
1123 cpp_s << dx <<
" p_registry._ref<" << rcname <<
">(p_obj, s_" << cpp_name <<
", " <<
"m_" << cpp_name <<
", init_children);\n";
1127 cpp_s << dx <<
" m_" << cpp_name <<
" = p_registry._ref<" << rcname <<
">(p_obj, s_" << cpp_name <<
", init_children);\n";
1134 << dx <<
" catch (dunedaq::conffwk::Exception & ex) {\n"
1135 << dx <<
" throw_init_ex(ex);\n"
1140 cpp_s << dx <<
"}\n\n";
1146 << dx << name <<
"::~" << name <<
"() noexcept\n"
1151 << dx <<
"std::vector<const dunedaq::conffwk::DalObject *> " << name <<
"::get(const std::string& name, bool upcast_unregistered) const\n"
1153 << dx <<
" std::vector<const dunedaq::conffwk::DalObject *> vec;\n\n"
1154 << dx <<
" if (!get(name, vec, upcast_unregistered, true))\n"
1155 << dx <<
" throw_get_ex(name, s_class_name, this);\n\n"
1156 << dx <<
" return vec;\n"
1160 << dx <<
"bool " << name <<
"::get(const std::string& name, std::vector<const dunedaq::conffwk::DalObject *>& vec, bool upcast_unregistered, bool first_call) const\n"
1162 << dx <<
" if (first_call)\n"
1164 << dx <<
" std::lock_guard scoped_lock(m_mutex);\n\n"
1165 << dx <<
" check();\n"
1166 << dx <<
" check_init();\n\n"
1167 << dx <<
" if (get_rel_objects(name, upcast_unregistered, vec))\n"
1168 << dx <<
" return true;\n"
1172 for (
const auto &prototype : algo_n_set)
1174 << dx <<
" if (name == \"" << prototype <<
"()\")\n"
1176 << dx <<
" p_registry.downcast_dal_objects(" << prototype <<
"(), upcast_unregistered, vec);\n"
1177 << dx <<
" return true;\n"
1180 for (
const auto &prototype : algo_1_set)
1182 << dx <<
" if (name == \"" << prototype <<
"()\")\n"
1184 << dx <<
" p_registry.downcast_dal_object(" << prototype <<
"(), upcast_unregistered, vec);\n"
1185 << dx <<
" return true;\n"
1191 for (
const auto& i : *slist)
1193 cpp_s << dx <<
" if (" <<
alnum_name(*i) <<
"::get(name, vec, upcast_unregistered, false)) return true;\n";
1200 << dx <<
" if (first_call)\n"
1201 << dx <<
" return get_algo_objects(name, vec);\n\n"
1202 << dx <<
" return false;\n"
1210 for (
const auto& i : *rlist)
1212 const std::string rname(
alnum_name(i->get_name()));
1215 cpp_s << dx <<
"void " << name <<
"::set_" << rname <<
"(const ";
1220 <<
"std::vector<const " << full_cpp_class_name <<
"*>& value)\n"
1222 << dx <<
" _set_objects(s_" << rname <<
", value);\n"
1228 << full_cpp_class_name <<
" * value)\n"
1230 << dx <<
" _set_object(s_" << rname <<
", value);\n"
1239 if (
const std::list<oks::OksMethod*> * mlist = cl->
direct_methods())
1241 bool comment_is_printed =
false;
1242 for (
const auto& i : *mlist)
1248 if (comment_is_printed ==
false)
1250 cpp_s << dx <<
" // user-defined algorithms\n\n";
1251 comment_is_printed =
true;
1261 std::string::size_type idx = prototype.find(
'(');
1263 if (idx != std::string::npos)
1269 while (isspace(prototype[idx]) && idx > 0)
1274 while ((isalnum(prototype[idx]) || prototype[idx] ==
'_') && idx > 0)
1277 prototype[idx] =
'\n';
1281 prototype.insert(idx + 1, s);
1285 std::string::size_type idx_open_bracket = prototype.find(
'(');
1286 std::string::size_type idx_space = prototype.rfind(
' ', idx_open_bracket);
1287 std::string::size_type idx_close_bracket = prototype.rfind(
')');
1289 auto prototype_attrs = prototype.substr(0,idx_space+1);
1290 auto prototype_head = prototype.substr(idx_space+1,idx_close_bracket-idx_space);
1291 auto prototype_specs = prototype.substr(idx_close_bracket+1);
1294 idx = prototype_attrs.find(spec);
1295 if ( idx != std::string::npos) {
1296 prototype_attrs.erase(idx,spec.size());
1298 prototype_attrs =
trim(prototype_attrs);
1300 idx = prototype_specs.find(spec);
1301 if ( idx != std::string::npos) {
1302 prototype_specs.erase(idx,spec.size());
1304 prototype_specs =
trim(prototype_specs);
1307 prototype = prototype_attrs +
' ' + prototype_head +
' ' + prototype_specs;
1310 << dx << prototype << std::endl
1327 for (
const auto& i : file_names)
1335 std::cerr <<
"ERROR: can not load schema file \"" << i <<
"\"\n";
1344 const std::string& cpp_ns_name,
1345 const std::string& cpp_hdr_dir)
1348 "// *** this file is generated by oksdalgen, do not modify it ***\n\n"
1353 "#include <stdint.h> // to define 64 bits types\n"
1354 "#include <iostream>\n"
1355 "#include <sstream>\n"
1356 "#include <string>\n"
1358 "#include <vector>\n\n"
1360 "#include \"conffwk/Configuration.hpp\"\n"
1361 "#include \"conffwk/DalObject.hpp\"\n\n";
1375 const std::string& cpp_hdr_dir)
1378 "#include \"conffwk/ConfigObject.hpp\"\n"
1379 "#include \"conffwk/DalFactory.hpp\"\n"
1380 "#include \"conffwk/DalObjectPrint.hpp\"\n"
1381 "#include \"conffwk/Errors.hpp\"\n"
1383 if(cpp_hdr_dir !=
"") {
1384 src << cpp_hdr_dir <<
"/";
1386 src << file_name <<
".hpp\"\n\n";
1393 std::list<std::string> class_names;
1394 std::list<std::string> file_names;
1395 std::list<std::string> include_dirs;
1396 std::list<std::string> user_classes;
1398 std::string cpp_dir_name =
".";
1399 std::string cpp_hdr_dir =
"";
1400 std::string cpp_ns_name =
"";
1401 std::string info_file_name =
"oksdalgen.info";
1402 bool verbose =
false;
1404 parse_arguments(argc, argv, class_names, file_names, include_dirs, user_classes, cpp_dir_name, cpp_ns_name, cpp_hdr_dir, info_file_name, verbose);
1408 std::set<oks::OksFile *, std::less<oks::OksFile *> > file_hs;
1418 if (class_names.size() == 0)
1422 std::cout <<
"No explicit classes were provided,\n"
1423 "search for classes which belong to the given schema files:\n";
1428 if (!class_list.empty())
1430 for (
const auto& i : class_list)
1434 std::cout <<
" * check for class \"" << i.first <<
"\" ";
1437 if (file_hs.find(i.second->get_file()) != file_hs.end())
1439 class_names.push_back(i.second->get_name());
1442 std::cout <<
"OK\n";
1449 std::cout <<
"skip\n";
1456 std::cerr <<
"No classes in schema file and no user classes specified\n";
1464 typedef std::set<const oks::OksClass *, std::less<const oks::OksClass *> > Set;
1465 Set generated_classes;
1468 unsigned int error_num = 0;
1472 for (
const auto& i : class_names)
1476 generated_classes.insert(cl);
1480 std::cerr <<
"ERROR: can not find class " << i << std::endl;
1487 for (
const auto& i : generated_classes)
1489 if (
const std::list<oks::OksRelationship *> * rels = i->direct_relationships())
1491 for (
const auto& j : *rels)
1497 std::cerr <<
"\nERROR: the class \"" << j->get_type() <<
"\" (it is used by the relationship \"" << j->get_name() <<
"\" of class \"" << i->get_name() <<
"\") is not defined by the schema.\n";
1500 else if (generated_classes.find(rc) == generated_classes.end())
1504 std::cerr <<
"\nERROR: the class \"" << j->get_type() <<
"\" is used by the relationship \"" << j->get_name() <<
"\" of class \"" << i->get_name() <<
"\".\n"
1505 " The class is not in the list of generated classes, "
1506 "it was not found among already generated headers "
1507 "(search list is defined by the -I | --include-dirs parameter) and "
1508 "it is not defined by user via -D | --user-defined-classes.\n";
1515 if (
const std::list<std::string *> * sclasses = i->direct_super_classes())
1517 for (
const auto& j : *sclasses)
1523 std::cerr <<
"\nERROR: the class \"" << *j <<
"\" (it is direct superclass of class \"" << i->get_name() <<
"\") is not defined by the schema.\n";
1526 else if (generated_classes.find(rc) == generated_classes.end())
1530 std::cerr <<
"\nERROR: the class \"" << rc->
get_name() <<
"\" is direct superclass of class \"" << i->get_name() <<
"\".\n"
1531 " The class is not in the list of generated classes, "
1532 "it was not found among already generated headers "
1533 "(search list is defined by the -I | --include-dirs parameter) and "
1534 "it is not defined by user via -D | --user-defined-classes.\n";
1544 std::cerr <<
"\n*** " << error_num << (error_num == 1 ?
" error was" :
" errors were") <<
" found.\n\n";
1545 return (EXIT_FAILURE);
1548 for (
const auto& cl : generated_classes)
1550 std::string name(
alnum_name(cl->get_name()));
1552 std::string cpp_hdr_name = cpp_dir_name +
"/" + name +
".hpp";
1553 std::string cpp_src_name = cpp_dir_name +
"/" + name +
".cpp";
1555 std::ofstream cpp_hdr_file(cpp_hdr_name.c_str());
1556 std::ofstream cpp_src_file(cpp_src_name.c_str());
1560 std::cerr <<
"ERROR: can not create file \"" << cpp_hdr_name <<
"\"\n";
1561 return (EXIT_FAILURE);
1566 std::cerr <<
"ERROR: can not create file \"" << cpp_src_name <<
"\"\n";
1567 return (EXIT_FAILURE);
1573 gen_header(cl, cpp_hdr_file, cpp_ns_name, cpp_hdr_dir, cl_info);
1574 gen_cpp_body(cl, cpp_src_file, cpp_ns_name, cpp_hdr_dir, cl_info);
1582 struct ConfigurationImplementations
1585 const char * header;
1586 const char * class_name;
1587 const char * header_prologue;
1588 const char * main_function_prologue;
1591 { 0,
"conffwk/Configuration.hpp", 0,
"",
"" } };
1593 for (
unsigned int i = 0; i <
sizeof(confs) /
sizeof(ConfigurationImplementations); ++i)
1595 std::string dump_name = cpp_dir_name +
"/dump";
1596 if (!cpp_ns_name.empty())
1604 dump_name += confs[i].name;
1606 dump_name +=
".cpp";
1608 std::ofstream dmp(dump_name.c_str());
1610 dmp.exceptions(std::ostream::failbit | std::ostream::badbit);
1616 gen_dump_application(dmp, class_names, cpp_ns_name, cpp_hdr_dir, confs[i].header, confs[i].class_name, confs[i].header_prologue, confs[i].main_function_prologue);
1618 catch (std::exception& ex)
1620 std::cerr <<
"ERROR: can not create file \"" << dump_name <<
"\": " << ex.what() << std::endl;
1625 std::cerr <<
"ERROR: can not create file \"" << dump_name <<
"\"\n";
1626 return (EXIT_FAILURE);
1634 std::ofstream info(info_file_name.c_str());
1642 std::cerr <<
"ERROR: can not create file \"" << info_file_name <<
"\"\n";
1643 return (EXIT_FAILURE);
1650 std::cerr <<
"Caught oks exception:\n" << ex << std::endl;
1651 return (EXIT_FAILURE);
1653 catch (std::exception & e)
1655 std::cerr <<
"Caught standard C++ exception: " << e.what() << std::endl;
1656 return (EXIT_FAILURE);
1660 std::cerr <<
"Caught unknown exception" << std::endl;
1661 return (EXIT_FAILURE);
1664 return (EXIT_SUCCESS);
bool get_is_abstract() const noexcept
OksKernel * get_kernel() const noexcept
const std::string & get_name() const noexcept
const FList * all_super_classes() const noexcept
const std::list< OksRelationship * > * direct_relationships() const noexcept
const std::string & get_description() const noexcept
const std::list< OksMethod * > * direct_methods() const noexcept
const std::list< OksAttribute * > * direct_attributes() const noexcept
const std::list< std::string * > * direct_super_classes() const noexcept
std::list< OksClass *, boost::fast_pool_allocator< OksClass * > > FList
std::map< const char *, OksClass *, SortStr > Map
Provides interface to the OKS XML schema and data files.
Provides interface to the OKS kernel.
const OksClass::Map & classes() const
Get classes.
OksClass * find_class(const std::string &class_name) const
Find class by name (C++ string).
OksFile * load_schema(const std::string &name, const OksFile *parent=0)
Load OKS schema file.
OKS method implementation class.
const std::string & get_prototype() const noexcept
std::map< const oks::OksClass *, ClassInfo, SortByName > Map
FELIX Initialization std::string initerror FELIX queue timed out
oks::OksMethodImplementation * find_cpp_method_implementation(const oks::OksMethod *method)
int main(int argc, char *argv[])
static void load_schemas(oks::OksKernel &kernel, const std::list< std::string > &file_names, std::set< oks::OksFile *, std::less< oks::OksFile * > > &file_hs)
std::string get_full_cpp_class_name(const oks::OksClass *c, const ClassInfo::Map &cl_info, const std::string &cpp_ns_name)
std::string trim(const std::string &s)
static void gen_header(const oks::OksClass *cl, std::ostream &cpp_file, const std::string &cpp_ns_name, const std::string &cpp_hdr_dir, const ClassInfo::Map &cl_info)
std::string ltrim(const std::string &s)
static void gen_cpp_body_prologue(const std::string &file_name, std::ostream &src, const std::string &cpp_hdr_dir)
std::string get_member_initializer_list(oks::OksMethodImplementation *mi)
std::string get_public_section(oks::OksMethodImplementation *mi)
static bool has_superclass(const oks::OksClass *tested, const oks::OksClass *c)
void close_cpp_namespace(std::ostream &s, int level)
static void gen_cpp_body(const oks::OksClass *cl, std::ostream &cpp_s, const std::string &cpp_ns_name, const std::string &cpp_hdr_dir, const ClassInfo::Map &cl_info)
bool get_add_algo_1(oks::OksMethodImplementation *mi)
const std::vector< std::string > cpp_method_virtual_specifiers
static void set2out(std::ostream &out, const std::set< std::string > &data, bool &is_first)
std::string get_include_dir(const oks::OksClass *c, const ClassInfo::Map &cl_info, const std::string &cpp_hdr_dir)
std::string get_type(oks::OksData::Type oks_type, bool is_cpp)
std::string get_method_header_prologue(oks::OksMethodImplementation *)
std::string rtrim(const std::string &s)
std::string get_private_section(oks::OksMethodImplementation *mi)
int open_cpp_namespace(std::ostream &s, const std::string &value)
std::string get_method_header_epilogue(oks::OksMethodImplementation *)
bool process_external_class(ClassInfo::Map &cl_info, const oks::OksClass *c, const std::list< std::string > &include_dirs, const std::list< std::string > &user_classes, bool verbose)
void print_indented(std::ostream &s, const std::string &text, const char *dx)
std::string int2dx(int level)
bool get_add_algo_n(oks::OksMethodImplementation *mi)
std::string alnum_name(const std::string &in)
static void gen_cpp_header_epilogue(std::ostream &s)
void parse_arguments(int argc, char *argv[], std::list< std::string > &class_names, std::list< std::string > &file_names, std::list< std::string > &include_dirs, std::list< std::string > &user_classes, std::string &cpp_dir_name, std::string &cpp_ns_name, std::string &cpp_hdr_dir, std::string &info_file_name, bool &verbose)
std::string get_method_implementation_body(oks::OksMethodImplementation *mi)
std::string capitalize_name(const std::string &in)
void write_info_file(std::ostream &s, const std::string &cpp_namespace, const std::string &cpp_header_dir, const std::set< const oks::OksClass *, std::less< const oks::OksClass * > > &class_names)
const std::string WHITESPACE
void gen_dump_application(std::ostream &s, std::list< std::string > &class_names, const std::string &cpp_ns_name, const std::string &cpp_hdr_dir, const char *conf_header, const char *conf_name, const char *headres_prologue, const char *main_function_prologue)
static void gen_cpp_header_prologue(const std::string &file_name, std::ostream &s, const std::string &cpp_ns_name, const std::string &cpp_hdr_dir)
void print(std::ostream &s, int level) const
void add(const std::string &ns_name, const std::string &class_name)