31extern std::string
alnum_name(
const std::string& in);
33extern void print_description(std::ostream& s,
const std::string& text,
const char * dx);
34extern void print_indented(std::ostream& s,
const std::string& text,
const char * dx);
36extern 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);
37extern 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);
41extern 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);
43extern std::string
int2dx(
int level);
67 for (
const auto& i : *sclasses)
81std::string
ltrim(
const std::string &s)
83 size_t start = s.find_first_not_of(
WHITESPACE);
84 return (start == std::string::npos) ?
"" : s.substr(start);
87std::string
rtrim(
const std::string &s)
90 return (end == std::string::npos) ?
"" : s.substr(0, end + 1);
93std::string
trim(
const std::string &s) {
105 std::ostream& cpp_file,
106 const std::string& cpp_ns_name,
107 const std::string& cpp_hdr_dir,
117 cpp_file <<
" // include files for classes used in inheritance hierarchy\n\n";
119 for (
const auto& i : *super_list)
122 cpp_file <<
"#include \"" <<
get_include_dir(c, cl_info, cpp_hdr_dir) <<
".hpp\"\n";
126 cpp_file << std::endl;
132 std::set<oks::OksClass*> rclasses;
137 rclasses.insert(i->get_class_type());
140 if (
const std::list<oks::OksMethod*> *mlist = cl->
direct_methods())
142 for (
const auto &i : *mlist)
146 const std::string mp(mi->get_prototype());
149 const std::string s(j.second->get_name());
150 std::string::size_type idx = mp.find(s);
151 if (idx != std::string::npos && (idx == 0 || !isalnum(mp[idx - 1])) && !isalnum(mp[idx + s.size()]))
152 rclasses.insert(j.second);
160 for (
const auto &c : rclasses)
166 ClassInfo::Map::const_iterator idx = cl_info.find(c);
167 ns_info.
add((idx != cl_info.end() ? (*idx).second.get_namespace() : cpp_ns_name),
alnum_name(c->get_name()));
170 if (!ns_info.
empty())
172 cpp_file <<
" // forward declaration for classes used in relationships and algorithms\n\n";
173 ns_info.
print(cpp_file, 0);
180 if (
const std::list<oks::OksMethod*> *mlist = cl->
direct_methods())
181 for (
const auto &i : *mlist)
185 cpp_file <<
" // prologue of method " << cl->
get_name() <<
"::" << i->get_name() <<
"()\n";
193 std::string ns_dx =
int2dx(ns_level);
194 std::string ns_dx2 = ns_dx +
" ";
196 const char * dx = ns_dx.c_str();
197 const char * dx2 = ns_dx2.c_str();
203 std::string txt(
"Declares methods to get and put values of attributes / relationships, to print and to destroy object.\n");
207 "The methods can throw several exceptions:\n"
209 " <li><code>conffwk.NotFoundException</code> - in case of wrong attribute or relationship name (e.g. in case of database schema modification)\n"
210 " <li><code>conffwk.SystemException</code> - in case of system problems (communication or implementation database failure, schema modification, object destruction, etc.)\n"
213 "In addition the methods modifying database (set value, destroy object) can throw <code>conffwk.NotAllowedException</code> "
214 "exception in case, if there are no write access rights or database is already locked by other process.\n";
223 txt +=
"@author oksdalgen\n";
225 cpp_file << std::endl;
231 cpp_file << dx <<
"class " << name <<
" : ";
237 for (std::list<std::string*>::const_iterator i = super_list->begin(); i != super_list->end();)
241 if (++i != super_list->end())
247 cpp_file <<
"public virtual dunedaq::conffwk::DalObject";
250 cpp_file <<
" {\n\n";
255 << dx <<
" friend class conffwk::Configuration;\n"
256 << dx <<
" friend class conffwk::DalObject;\n"
257 << dx <<
" friend class conffwk::DalFactory;\n"
258 << dx <<
" friend class conffwk::DalRegistry;\n\n"
259 << dx <<
" protected:\n\n"
260 << dx <<
" " << name <<
"(conffwk::DalRegistry& db, const conffwk::ConfigObject& obj) noexcept;\n"
261 << dx <<
" virtual ~" << name <<
"() noexcept;\n"
262 << dx <<
" virtual void init(bool init_children);\n\n"
263 << dx <<
" public:\n\n"
264 << dx <<
" /** The name of the configuration class. */\n\n"
265 << dx <<
" static const std::string& s_class_name;\n\n\n"
267 << dx <<
" * \\brief Print details of the " << name <<
" object.\n"
269 << dx <<
" * Parameters are:\n"
270 << dx <<
" * \\param offset number of spaces to shift object right (useful to print nested objects)\n"
271 << dx <<
" * \\param print_header if false, do not print object header (to print attributes of base classes)\n"
272 << dx <<
" * \\param s output stream\n"
274 << dx <<
" virtual void print(unsigned int offset, bool print_header, std::ostream& s) const;\n\n\n"
276 << dx <<
" * \\brief Get values of relationships and results of some algorithms as a vector of dunedaq::conffwk::DalObject pointers.\n"
278 << dx <<
" * Parameters are:\n"
279 << dx <<
" * \\param name name of the relationship or algorithm\n"
280 << dx <<
" * \\return value of relationship or result of algorithm\n"
281 << dx <<
" * \\throw std::exception if there is no relationship or algorithm with such name in this and base classes\n"
283 << dx <<
" virtual std::vector<const dunedaq::conffwk::DalObject *> get(const std::string& name, bool upcast_unregistered = true) const;\n\n\n"
284 << dx <<
" protected:\n\n"
285 << dx <<
" bool get(const std::string& name, std::vector<const dunedaq::conffwk::DalObject *>& vec, bool upcast_unregistered, bool first_call) const;\n\n\n";
293 cpp_file << dx <<
" private:\n\n";
301 for (
const auto& i : *alist)
303 const std::string aname(
alnum_name(i->get_name()));
304 std::string cpp_type =
get_type(i->get_data_type(),
true);
306 if (i->get_is_multi_values())
307 cpp_file << dx <<
" std::vector<" << cpp_type <<
"> m_" << aname <<
";\n";
309 cpp_file << dx <<
" " << cpp_type <<
" m_" << aname <<
";\n";
320 for (
const auto& i : *rlist)
322 const std::string rname(
alnum_name(i->get_name()));
325 cpp_file << dx <<
" std::vector<const " << full_class_name <<
"*> m_" << rname <<
";\n";
327 cpp_file << dx <<
" const " << full_class_name <<
"* m_" << rname <<
";\n";
334 if (
const std::list<oks::OksMethod*> * mlist = cl->
direct_methods())
336 for (
const auto& i : *mlist)
341 if (!method_extension.empty())
343 cpp_file <<
"\n" << dx <<
" // extension of method " << cl->
get_name() <<
"::" << i->get_name() <<
"()\n";
351 cpp_file << std::endl << std::endl << dx <<
" public:\n\n";
364 cpp_file << dx <<
" // attribute names\n\n";
366 for (
const auto& i : *alist)
368 const std::string& aname(i->get_name());
369 cpp_file << dx <<
" inline static const std::string s_" <<
alnum_name(aname) <<
" = \"" << aname <<
"\";\n";
374 for (
const auto& i : *alist)
376 const std::string& cpp_aname(
alnum_name(i->get_name()));
377 cpp_file << dx <<
" static const std::string& __get_" << cpp_aname <<
"_str() noexcept { return s_" << cpp_aname <<
"; }\n";
380 cpp_file << std::endl << std::endl;
382 for (
const auto& i : *alist)
384 const std::string aname(
alnum_name(i->get_name()));
390 std::string description(
"Valid enumeration values to compare with value returned by get_");
391 description += aname;
392 description +=
"() and to pass value to set_";
393 description += aname;
394 description +=
"() methods.";
398 description +=
"\nUse toString() method to compare and to pass the values. Do not use name() method.";
404 while (!(token = t.
next()).empty())
406 cpp_file << dx <<
" inline static const std::string " <<
capitalize_name(
alnum_name(token)) <<
" = \"" << token <<
"\";\n";
409 cpp_file << dx <<
" };\n\n";
416 std::string description(
"Get \"");
417 description += i->get_name();
418 description +=
"\" attribute value.\n\n";
419 description += i->get_description();
421 std::string description2(
"\\brief ");
422 description2 += description;
423 description2 +=
"\n\\return the attribute value\n";
424 description2 +=
"\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
431 cpp_file << dx <<
" ";
433 std::string cpp_type =
get_type(i->get_data_type(),
true);
435 if (i->get_is_multi_values())
437 cpp_file <<
"const std::vector<" << cpp_type <<
">&";
441 if (cpp_type ==
"std::string")
442 cpp_file <<
"const std::string&";
444 cpp_file << cpp_type;
448 << dx <<
" get_" << aname <<
"() const\n"
450 << dx <<
" std::lock_guard scoped_lock(m_mutex);\n"
451 << dx <<
" check();\n"
452 << dx <<
" check_init();\n"
453 << dx <<
" return m_" << aname <<
";\n"
459 std::string description(
"Set \"");
460 description += i->get_name();
461 description +=
"\" attribute value.\n\n";
462 description += i->get_description();
464 std::string description2(
"\\brief ");
465 description2 += description;
466 description2 +=
"\n\\param value new attribute value\n";
467 description2 +=
"\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
474 cpp_file << dx <<
" void\n" << dx <<
" set_" << aname <<
'(';
476 if (i->get_is_multi_values())
478 cpp_file <<
"const std::vector<" << cpp_type <<
">&";
482 if (cpp_type ==
"std::string")
484 cpp_file <<
"const std::string&";
488 cpp_file << cpp_type;
492 cpp_file <<
" value)\n"
494 << dx <<
" std::lock_guard scoped_lock(m_mutex);\n"
495 << dx <<
" check();\n"
496 << dx <<
" clear();\n"
501 cpp_file <<
"set_by_ref";
505 cpp_file <<
"set_enum";
509 cpp_file <<
"set_class";
513 cpp_file <<
"set_date";
517 cpp_file <<
"set_time";
521 cpp_file <<
"set_by_val";
524 cpp_file <<
"(s_" << aname <<
", value);\n"
540 cpp_file << dx <<
" // relationship names\n\n";
542 for (
const auto& i : *rlist)
544 const std::string& rname(i->get_name());
545 cpp_file << dx <<
" inline static const std::string s_" <<
alnum_name(rname) <<
" = \"" << rname <<
"\";\n";
550 for (
const auto& i : *rlist)
552 const std::string& cpp_rname(
alnum_name(i->get_name()));
553 cpp_file << dx <<
" static const std::string& __get_" << cpp_rname <<
"_str() noexcept { return s_" << cpp_rname <<
"; }\n";
556 cpp_file << std::endl << std::endl;
558 for (
const auto& i : *rlist)
564 std::string description(
"Get \"");
565 description += i->get_name();
566 description +=
"\" relationship value.\n\n";
567 description += i->get_description();
569 std::string description2(
"\\brief ");
570 description2 += description;
571 description2 +=
"\n\\return the relationship value\n";
572 description2 +=
"\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
579 cpp_file << dx <<
" const ";
581 const std::string rname(
alnum_name(i->get_name()));
586 cpp_file <<
"std::vector<const " << full_cpp_class_name <<
"*>&";
590 cpp_file << full_cpp_class_name <<
" *";
594 << dx <<
" get_" << rname <<
"() const\n"
596 << dx <<
" std::lock_guard scoped_lock(m_mutex);\n"
597 << dx <<
" check();\n"
598 << dx <<
" check_init();\n";
605 << dx <<
" if (!m_" << rname <<
")\n"
607 << dx <<
" std::ostringstream text;\n"
608 << dx <<
" text << \"relationship \\\"\" << s_" << rname <<
" << \"\\\" of object \" << this << \" is not set\";\n"
609 << dx <<
" throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());\n"
615 << dx <<
" if (m_" << rname <<
".empty())\n"
617 << dx <<
" std::ostringstream text;\n"
618 << dx <<
" text << \"relationship \\\"\" << s_" << rname <<
" << \"\\\" of object \" << this << \" is empty\";\n"
619 << dx <<
" throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());\n"
625 << dx <<
" return m_" << rname <<
";\n"
631 std::string description(
"Set \"");
632 description += i->get_name();
633 description +=
"\" relationship value.\n\n";
634 description += i->get_description();
636 std::string description2(
"\\brief ");
637 description2 += description;
638 description2 +=
"\n\\param value new relationship value\n";
639 description2 +=
"\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
644 cpp_file << dx <<
" void\n" << dx <<
" set_" << rname <<
"(const ";
648 cpp_file <<
"std::vector<const " << full_cpp_class_name <<
"*>&";
652 cpp_file << full_cpp_class_name <<
" *";
655 cpp_file <<
" value);\n\n";
663 if (
const std::list<oks::OksMethod*> *mlist = cl->
direct_methods())
665 bool cpp_comment_is_printed =
false;
667 for (
const auto& i : *mlist)
674 if (cpp_comment_is_printed ==
false)
676 cpp_file << std::endl << dx <<
" public:\n\n" << dx <<
" // user-defined algorithms\n\n";
677 cpp_comment_is_printed =
true;
690 cpp_file << dx <<
" " << mi->get_prototype() <<
";\n";
696 if (!public_method_extension.empty())
698 cpp_file <<
"\n" <<
" // extension of method " << cl->
get_name() <<
"::" << i->get_name() <<
"()\n";
709 cpp_file << dx <<
"};\n\n";
715 << dx <<
" // out stream operator\n\n"
716 << dx <<
"inline std::ostream& operator<<(std::ostream& s, const " << name <<
"& obj)\n"
718 << dx <<
" return obj.print_object(s);\n"
720 << dx <<
"typedef std::vector<const " << name <<
"*>::const_iterator " << name <<
"Iterator;\n\n";
730 if (
const std::list<oks::OksMethod*> * mlist = cl->
direct_methods())
732 for (
const auto & i : *mlist)
737 cpp_file <<
" // epilogue of method " << cl->
get_name() <<
"::" << i->get_name() <<
"()\n";
747set2out(std::ostream&
out,
const std::set<std::string>& data,
bool& is_first)
749 for (
const auto& x : data)
755 out <<
'\"' << x <<
"()\"";
763 cpp_s <<
"#include \"logging/Logging.hpp\"\n\n";
767 std::set<oks::OksClass *> rclasses;
773 for (
const auto& i : *rlist)
783 if (
const std::list<oks::OksMethod*> * mlist = cl->
direct_methods())
785 for (
const auto& i : *mlist)
789 std::string prototype(mi->get_prototype());
790 std::string::size_type idx = prototype.find(
'(');
795 if (idx != std::string::npos)
800 while (isspace(prototype[idx]) && idx > 0)
804 while (!isspace(prototype[idx]) && idx > 0)
808 prototype.erase(idx + 1);
811 prototype.erase(std::remove_if(prototype.begin(), prototype.end(), [](
unsigned char x)
812 { return std::isspace(x);}), prototype.end());
814 if (prototype.empty() ==
false)
816 idx = prototype.find(
'*');
817 prototype.erase(idx--);
819 if (idx != std::string::npos)
821 while (isalnum(prototype[idx]) && idx > 0)
824 if(idx == 0 &&
get_add_algo_1(mi) && prototype.find(
"const") == 0)
825 prototype.erase(0, 5);
827 prototype.erase(0, idx+1);
839 if (!rclasses.empty())
841 cpp_s <<
" // include files for classes used in relationships and algorithms\n\n";
843 for (
const auto& j : rclasses)
845 cpp_s <<
"#include \"" <<
get_include_dir(j, cl_info, cpp_hdr_dir) <<
".hpp\"\n";
848 cpp_s << std::endl << std::endl;
855 std::string ns_dx =
int2dx(ns_level);
856 std::string ns_dx2 = ns_dx +
" ";
858 const char * dx = ns_dx.c_str();
859 const char * dx2 = ns_dx2.c_str();
864 cpp_s << dx <<
"const std::string& " << name <<
"::s_class_name(dunedaq::conffwk::DalFactory::instance().get_known_class_name_ref(\"" << name <<
"\"));\n\n";
866 std::set<std::string> algo_n_set, algo_1_set;
868 if (
const std::list<oks::OksMethod*> * mlist = cl->
direct_methods())
870 for (
const auto& i : *mlist)
874 std::string prototype(mi->get_prototype());
875 std::string::size_type idx = prototype.find(
'(');
877 if (idx != std::string::npos)
882 while (isspace(prototype[idx]) && idx > 0)
886 prototype.erase(idx+1);
889 while (!isspace(prototype[idx]) && idx > 0)
894 prototype.erase(0, idx+1);
898 algo_n_set.insert(prototype);
902 algo_1_set.insert(prototype);
913 << dx <<
" // the factory initializer\n\n"
914 << dx <<
"static struct __" << name <<
"_Registrator\n"
916 << dx <<
" __" << name <<
"_Registrator()\n"
918 << dx <<
" dunedaq::conffwk::DalFactory::instance().register_dal_class<" << name <<
">(\"" << cl->
get_name() <<
"\");\n"
920 << dx <<
" } registrator;\n\n\n";
926 << dx <<
" // the constructor\n\n"
927 << dx << name <<
"::" << name <<
"(conffwk::DalRegistry& db, const conffwk::ConfigObject& o) noexcept :\n"
928 << dx <<
" " <<
"dunedaq::conffwk::DalObject(db, o)";
933 std::list<std::string> initializer_list;
937 for(
auto & i : *slist)
945 for (std::list<oks::OksRelationship*>::const_iterator i = rlist->begin(); i != rlist->end(); ++i)
949 initializer_list.push_back(std::string(
"m_") +
alnum_name((*i)->get_name()) +
" (nullptr)");
955 if(
const std::list<oks::OksMethod*> * mlist = cl->
direct_methods())
957 for (std::list<oks::OksMethod*>::const_iterator i = mlist->begin(); i != mlist->end(); ++i)
962 member_initializer.erase(remove(member_initializer.begin(), member_initializer.end(),
'\n'), member_initializer.end());
964 if (!member_initializer.empty())
966 initializer_list.push_back(member_initializer);
972 if (initializer_list.empty() ==
false)
974 for (
auto & i : initializer_list)
976 cpp_s <<
",\n" << dx <<
" " << i;
991 << dx <<
"void " << name <<
"::print(unsigned int indent, bool print_header, std::ostream& s) const\n"
993 << dx <<
" check_init();\n\n"
997 cpp_s << dx <<
" const std::string str(indent+2, ' ');\n";
1001 << dx <<
" if (print_header)\n"
1002 << dx <<
" p_hdr(s, indent, s_class_name";
1004 if(!cpp_ns_name.empty()) {
1005 cpp_s <<
", \"" << cpp_ns_name <<
'\"';
1013 cpp_s <<
"\n\n" << dx <<
" // print direct super-classes\n\n";
1015 for (
const auto& i : *slist)
1020 cpp_s <<
"\n\n" << dx <<
" // print direct attributes\n\n";
1022 for(
const auto& i : *alist) {
1023 const std::string aname(
alnum_name(i->get_name()));
1026 if (i->get_is_multi_values())
1027 cpp_s << dx <<
" dunedaq::conffwk::p_mv_attr" << abase <<
"(s, str, s_" << aname <<
", m_" << aname <<
");\n";
1029 cpp_s << dx <<
" dunedaq::conffwk::p_sv_attr" << abase <<
"(s, str, s_" << aname <<
", m_" << aname <<
");\n";
1035 cpp_s <<
"\n\n" << dx <<
" // print direct relationships\n\n";
1037 for (
const auto& i : *rlist)
1039 const std::string rname(
alnum_name(i->get_name()));
1043 if (i->get_is_composite())
1044 cpp_s << dx <<
" dunedaq::conffwk::p_mv_rel(s, str, indent, s_" << rname <<
", m_" << rname <<
");\n";
1046 cpp_s << dx <<
" dunedaq::conffwk::p_mv_rel(s, str, s_" << rname <<
", m_" << rname <<
");\n";
1050 if (i->get_is_composite())
1051 cpp_s << dx <<
" dunedaq::conffwk::p_sv_rel(s, str, indent, s_" << rname <<
", m_" << rname <<
");\n";
1053 cpp_s << dx <<
" dunedaq::conffwk::p_sv_rel(s, str, s_" << rname <<
", m_" << rname <<
");\n";
1058 cpp_s << dx <<
" }\n"
1059 << dx <<
" catch (dunedaq::conffwk::Exception & ex) {\n"
1060 << dx <<
" dunedaq::conffwk::DalObject::p_error(s, ex);\n"
1068 const char * ic_value = (
1072 :
"/* init_children */"
1076 << dx <<
"void " << name <<
"::init(bool " << ic_value <<
")\n"
1083 << dx <<
" p_was_read = true;\n"
1084 << dx <<
" increment_read();\n";
1091 for (
const auto& i : *slist)
1093 cpp_s << dx <<
" " <<
alnum_name(*i) <<
"::init(init_children);\n";
1095 if (!slist->empty())
1099 cpp_s << dx <<
" TLOG_DEBUG(5) << \"read object \" << this << \" (class \" << s_class_name << \')\';\n";
1105 if ((alist && !alist->empty()) || (rlist && !rlist->empty()))
1107 cpp_s << std::endl << dx <<
" try {\n";
1113 for (
const auto& i : *alist)
1115 const std::string cpp_name =
alnum_name(i->get_name());
1116 cpp_s << dx <<
" p_obj.get(s_" << cpp_name <<
", m_" << cpp_name <<
");\n";
1124 for (
const auto& i : *rlist)
1126 const std::string& rname = i->get_name();
1131 cpp_s << dx <<
" p_registry._ref<" << rcname <<
">(p_obj, s_" << cpp_name <<
", " <<
"m_" << cpp_name <<
", init_children);\n";
1135 cpp_s << dx <<
" m_" << cpp_name <<
" = p_registry._ref<" << rcname <<
">(p_obj, s_" << cpp_name <<
", init_children);\n";
1142 << dx <<
" catch (dunedaq::conffwk::Exception & ex) {\n"
1143 << dx <<
" throw_init_ex(ex);\n"
1148 cpp_s << dx <<
"}\n\n";
1154 << dx << name <<
"::~" << name <<
"() noexcept\n"
1159 << dx <<
"std::vector<const dunedaq::conffwk::DalObject *> " << name <<
"::get(const std::string& name, bool upcast_unregistered) const\n"
1161 << dx <<
" std::vector<const dunedaq::conffwk::DalObject *> vec;\n\n"
1162 << dx <<
" if (!get(name, vec, upcast_unregistered, true))\n"
1163 << dx <<
" throw_get_ex(name, s_class_name, this);\n\n"
1164 << dx <<
" return vec;\n"
1168 << dx <<
"bool " << name <<
"::get(const std::string& name, std::vector<const dunedaq::conffwk::DalObject *>& vec, bool upcast_unregistered, bool first_call) const\n"
1170 << dx <<
" if (first_call)\n"
1172 << dx <<
" std::lock_guard scoped_lock(m_mutex);\n\n"
1173 << dx <<
" check();\n"
1174 << dx <<
" check_init();\n\n"
1175 << dx <<
" if (get_rel_objects(name, upcast_unregistered, vec))\n"
1176 << dx <<
" return true;\n"
1180 for (
const auto &prototype : algo_n_set)
1182 << dx <<
" if (name == \"" << prototype <<
"()\")\n"
1184 << dx <<
" p_registry.downcast_dal_objects(" << prototype <<
"(), upcast_unregistered, vec);\n"
1185 << dx <<
" return true;\n"
1188 for (
const auto &prototype : algo_1_set)
1190 << dx <<
" if (name == \"" << prototype <<
"()\")\n"
1192 << dx <<
" p_registry.downcast_dal_object(" << prototype <<
"(), upcast_unregistered, vec);\n"
1193 << dx <<
" return true;\n"
1199 for (
const auto& i : *slist)
1201 cpp_s << dx <<
" if (" <<
alnum_name(*i) <<
"::get(name, vec, upcast_unregistered, false)) return true;\n";
1208 << dx <<
" if (first_call)\n"
1209 << dx <<
" return get_algo_objects(name, vec);\n\n"
1210 << dx <<
" return false;\n"
1218 for (
const auto& i : *rlist)
1220 const std::string rname(
alnum_name(i->get_name()));
1223 cpp_s << dx <<
"void " << name <<
"::set_" << rname <<
"(const ";
1228 <<
"std::vector<const " << full_cpp_class_name <<
"*>& value)\n"
1230 << dx <<
" _set_objects(s_" << rname <<
", value);\n"
1236 << full_cpp_class_name <<
" * value)\n"
1238 << dx <<
" _set_object(s_" << rname <<
", value);\n"
1247 if (
const std::list<oks::OksMethod*> * mlist = cl->
direct_methods())
1249 bool comment_is_printed =
false;
1250 for (
const auto& i : *mlist)
1256 if (comment_is_printed ==
false)
1258 cpp_s << dx <<
" // user-defined algorithms\n\n";
1259 comment_is_printed =
true;
1269 std::string::size_type idx = prototype.find(
'(');
1271 if (idx != std::string::npos)
1277 while (isspace(prototype[idx]) && idx > 0)
1282 while ((isalnum(prototype[idx]) || prototype[idx] ==
'_') && idx > 0)
1285 prototype[idx] =
'\n';
1289 prototype.insert(idx + 1, s);
1293 std::string::size_type idx_open_bracket = prototype.find(
'(');
1294 std::string::size_type idx_space = prototype.rfind(
' ', idx_open_bracket);
1295 std::string::size_type idx_close_bracket = prototype.rfind(
')');
1297 auto prototype_attrs = prototype.substr(0,idx_space+1);
1298 auto prototype_head = prototype.substr(idx_space+1,idx_close_bracket-idx_space);
1299 auto prototype_specs = prototype.substr(idx_close_bracket+1);
1302 idx = prototype_attrs.find(spec);
1303 if ( idx != std::string::npos) {
1304 prototype_attrs.erase(idx,spec.size());
1306 prototype_attrs =
trim(prototype_attrs);
1308 idx = prototype_specs.find(spec);
1309 if ( idx != std::string::npos) {
1310 prototype_specs.erase(idx,spec.size());
1312 prototype_specs =
trim(prototype_specs);
1315 prototype = prototype_attrs +
' ' + prototype_head +
' ' + prototype_specs;
1318 << dx << prototype << std::endl
1335 for (
const auto& i : file_names)
1343 std::cerr <<
"ERROR: can not load schema file \"" << i <<
"\"\n";
1352 const std::string& cpp_ns_name,
1353 const std::string& cpp_hdr_dir)
1356 "// *** this file is generated by oksdalgen, do not modify it ***\n\n"
1361 "#include <stdint.h> // to define 64 bits types\n"
1362 "#include <iostream>\n"
1363 "#include <sstream>\n"
1364 "#include <string>\n"
1366 "#include <vector>\n\n"
1368 "#include \"conffwk/Configuration.hpp\"\n"
1369 "#include \"conffwk/DalObject.hpp\"\n\n";
1383 const std::string& cpp_hdr_dir)
1386 "#include \"conffwk/ConfigObject.hpp\"\n"
1387 "#include \"conffwk/DalFactory.hpp\"\n"
1388 "#include \"conffwk/DalObjectPrint.hpp\"\n"
1389 "#include \"conffwk/Errors.hpp\"\n"
1391 if(cpp_hdr_dir !=
"") {
1392 src << cpp_hdr_dir <<
"/";
1394 src << file_name <<
".hpp\"\n\n";
1401 std::list<std::string> class_names;
1402 std::list<std::string> file_names;
1403 std::list<std::string> include_dirs;
1404 std::list<std::string> user_classes;
1406 std::string cpp_dir_name =
".";
1407 std::string cpp_hdr_dir =
"";
1408 std::string cpp_ns_name =
"";
1409 std::string info_file_name =
"oksdalgen.info";
1410 bool verbose =
false;
1412 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);
1416 std::set<oks::OksFile *, std::less<oks::OksFile *> > file_hs;
1426 if (class_names.size() == 0)
1430 std::cout <<
"No explicit classes were provided,\n"
1431 "search for classes which belong to the given schema files:\n";
1436 if (!class_list.empty())
1438 for (
const auto& i : class_list)
1442 std::cout <<
" * check for class \"" << i.first <<
"\" ";
1445 if (file_hs.find(i.second->get_file()) != file_hs.end())
1447 class_names.push_back(i.second->get_name());
1450 std::cout <<
"OK\n";
1457 std::cout <<
"skip\n";
1464 std::cerr <<
"No classes in schema file and no user classes specified\n";
1472 typedef std::set<const oks::OksClass *, std::less<const oks::OksClass *> > Set;
1473 Set generated_classes;
1476 unsigned int error_num = 0;
1480 for (
const auto& i : class_names)
1484 generated_classes.insert(cl);
1488 std::cerr <<
"ERROR: can not find class " << i << std::endl;
1495 for (
const auto& i : generated_classes)
1497 if (
const std::list<oks::OksRelationship *> * rels = i->direct_relationships())
1499 for (
const auto& j : *rels)
1505 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";
1508 else if (generated_classes.find(rc) == generated_classes.end())
1512 std::cerr <<
"\nERROR: the class \"" << j->get_type() <<
"\" is used by the relationship \"" << j->get_name() <<
"\" of class \"" << i->get_name() <<
"\".\n"
1513 " The class is not in the list of generated classes, "
1514 "it was not found among already generated headers "
1515 "(search list is defined by the -I | --include-dirs parameter) and "
1516 "it is not defined by user via -D | --user-defined-classes.\n";
1523 if (
const std::list<std::string *> * sclasses = i->direct_super_classes())
1525 for (
const auto& j : *sclasses)
1531 std::cerr <<
"\nERROR: the class \"" << *j <<
"\" (it is direct superclass of class \"" << i->get_name() <<
"\") is not defined by the schema.\n";
1534 else if (generated_classes.find(rc) == generated_classes.end())
1538 std::cerr <<
"\nERROR: the class \"" << rc->
get_name() <<
"\" is direct superclass of class \"" << i->get_name() <<
"\".\n"
1539 " The class is not in the list of generated classes, "
1540 "it was not found among already generated headers "
1541 "(search list is defined by the -I | --include-dirs parameter) and "
1542 "it is not defined by user via -D | --user-defined-classes.\n";
1552 std::cerr <<
"\n*** " << error_num << (error_num == 1 ?
" error was" :
" errors were") <<
" found.\n\n";
1553 return (EXIT_FAILURE);
1556 for (
const auto& cl : generated_classes)
1558 std::string name(
alnum_name(cl->get_name()));
1560 std::string cpp_hdr_name = cpp_dir_name +
"/" + name +
".hpp";
1561 std::string cpp_src_name = cpp_dir_name +
"/" + name +
".cpp";
1563 std::ofstream cpp_hdr_file(cpp_hdr_name.c_str());
1564 std::ofstream cpp_src_file(cpp_src_name.c_str());
1568 std::cerr <<
"ERROR: can not create file \"" << cpp_hdr_name <<
"\"\n";
1569 return (EXIT_FAILURE);
1574 std::cerr <<
"ERROR: can not create file \"" << cpp_src_name <<
"\"\n";
1575 return (EXIT_FAILURE);
1581 gen_header(cl, cpp_hdr_file, cpp_ns_name, cpp_hdr_dir, cl_info);
1582 gen_cpp_body(cl, cpp_src_file, cpp_ns_name, cpp_hdr_dir, cl_info);
1590 struct ConfigurationImplementations
1593 const char * header;
1594 const char * class_name;
1595 const char * header_prologue;
1596 const char * main_function_prologue;
1599 { 0,
"conffwk/Configuration.hpp", 0,
"",
"" } };
1601 for (
unsigned int i = 0; i <
sizeof(confs) /
sizeof(ConfigurationImplementations); ++i)
1603 std::string dump_name = cpp_dir_name +
"/dump";
1604 if (!cpp_ns_name.empty())
1612 dump_name += confs[i].name;
1614 dump_name +=
".cpp";
1616 std::ofstream dmp(dump_name.c_str());
1618 dmp.exceptions(std::ostream::failbit | std::ostream::badbit);
1624 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);
1626 catch (std::exception& ex)
1628 std::cerr <<
"ERROR: can not create file \"" << dump_name <<
"\": " << ex.what() << std::endl;
1633 std::cerr <<
"ERROR: can not create file \"" << dump_name <<
"\"\n";
1634 return (EXIT_FAILURE);
1642 std::ofstream info(info_file_name.c_str());
1650 std::cerr <<
"ERROR: can not create file \"" << info_file_name <<
"\"\n";
1651 return (EXIT_FAILURE);
1658 std::cerr <<
"Caught oks exception:\n" << ex << std::endl;
1659 return (EXIT_FAILURE);
1661 catch (std::exception & e)
1663 std::cerr <<
"Caught standard C++ exception: " << e.what() << std::endl;
1664 return (EXIT_FAILURE);
1668 std::cerr <<
"Caught unknown exception" << std::endl;
1669 return (EXIT_FAILURE);
1672 return (EXIT_SUCCESS);
bool get_is_abstract() const noexcept
std::list< OksClass *, boost::fast_pool_allocator< OksClass * > > FList
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
std::map< const char *, OksClass *, SortStr > Map
const std::list< OksAttribute * > * direct_attributes() const noexcept
const std::list< std::string * > * direct_super_classes() const noexcept
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)