37print_indented(std::ostream& s,
const std::string& text,
const char* dx);
42 std::list<std::string>& class_names,
43 const std::string& cpp_ns_name,
44 const std::string& cpp_hdr_dir,
45 const char* conf_header,
46 const char* conf_name,
47 const char* headres_prologue,
48 const char* main_function_prologue);
51 const std::string& cpp_namespace,
52 const std::string& cpp_header_dir,
53 const std::set<
const oks::OksClass*, std::less<const oks::OksClass*>>& class_names);
63 std::list<std::string>& class_names,
64 std::list<std::string>& file_names,
65 std::list<std::string>& include_dirs,
66 std::list<std::string>& user_classes,
67 std::string& cpp_dir_name,
68 std::string& cpp_ns_name,
69 std::string& cpp_hdr_dir,
70 std::string& info_file_name,
75 const std::list<std::string>& include_dirs,
76 const std::list<std::string>& user_classes,
112 for (
const auto& i : *sclasses) {
127 size_t start = s.find_first_not_of(
WHITESPACE);
128 return (start == std::string::npos) ?
"" : s.substr(start);
135 return (end == std::string::npos) ?
"" : s.substr(0, end + 1);
148 std::ostream& cpp_file,
149 const std::string& cpp_ns_name,
150 const std::string& cpp_hdr_dir,
158 cpp_file <<
" // include files for classes used in inheritance hierarchy\n\n";
160 for (
const auto& i : *super_list) {
162 cpp_file <<
"#include \"" <<
get_include_dir(c, cl_info, cpp_hdr_dir) <<
".hpp\"\n";
166 cpp_file << std::endl;
171 std::set<oks::OksClass*> rclasses;
176 rclasses.insert(i->get_class_type());
179 if (
const std::list<oks::OksMethod*>* mlist = cl->
direct_methods()) {
180 for (
const auto& i : *mlist) {
182 const std::string mp(mi->get_prototype());
184 const std::string s(j.second->get_name());
185 std::string::size_type idx = mp.find(s);
186 if (idx != std::string::npos && (idx == 0 || !isalnum(mp[idx - 1])) && !isalnum(mp[idx + s.size()]))
187 rclasses.insert(j.second);
195 for (
const auto& c : rclasses) {
200 ClassInfo::Map::const_iterator idx = cl_info.find(c);
201 ns_info.
add((idx != cl_info.end() ? (*idx).second.get_namespace() : cpp_ns_name),
alnum_name(c->get_name()));
204 if (!ns_info.
empty()) {
205 cpp_file <<
" // forward declaration for classes used in relationships and algorithms\n\n";
206 ns_info.
print(cpp_file, 0);
213 if (
const std::list<oks::OksMethod*>* mlist = cl->
direct_methods())
214 for (
const auto& i : *mlist)
217 cpp_file <<
" // prologue of method " << cl->
get_name() <<
"::" << i->get_name() <<
"()\n";
224 std::string ns_dx =
int2dx(ns_level);
225 std::string ns_dx2 = ns_dx +
" ";
227 const char* dx = ns_dx.c_str();
228 const char* dx2 = ns_dx2.c_str();
234 "Declares methods to get and put values of attributes / relationships, to print and to destroy object.\n");
237 "The methods can throw several exceptions:\n"
239 " <li><code>conffwk.NotFoundException</code> - in case of wrong attribute or relationship name (e.g. in "
240 "case of database schema modification)\n"
241 " <li><code>conffwk.SystemException</code> - in case of system problems (communication or implementation "
242 "database failure, schema modification, object destruction, etc.)\n"
245 "In addition the methods modifying database (set value, destroy object) can throw "
246 "<code>conffwk.NotAllowedException</code> "
247 "exception in case, if there are no write access rights or database is already locked by other process.\n";
255 txt +=
"@author oksdalgen\n";
257 cpp_file << std::endl;
263 cpp_file << dx <<
"class " << name <<
" : ";
268 for (std::list<std::string*>::const_iterator i = super_list->begin(); i != super_list->end();) {
271 if (++i != super_list->end())
275 cpp_file <<
"public virtual dunedaq::conffwk::DalObject";
278 cpp_file <<
" {\n\n";
283 << dx <<
" friend class conffwk::Configuration;\n"
284 << dx <<
" friend class conffwk::DalObject;\n"
285 << dx <<
" friend class conffwk::DalFactory;\n"
286 << dx <<
" friend class conffwk::DalRegistry;\n\n"
287 << dx <<
" protected:\n\n"
288 << dx <<
" " << name <<
"(conffwk::DalRegistry& db, const conffwk::ConfigObject& obj) noexcept;\n"
289 << dx <<
" virtual ~" << name <<
"() noexcept;\n"
290 << dx <<
" virtual void init(bool init_children);\n\n"
291 << dx <<
" public:\n\n"
292 << dx <<
" /** The name of the configuration class. */\n\n"
293 << dx <<
" static const std::string& s_class_name;\n\n\n"
295 << dx <<
" * \\brief Print details of the " << name <<
" object.\n"
297 << dx <<
" * Parameters are:\n"
299 <<
" * \\param offset number of spaces to shift object right (useful to print nested objects)\n"
301 <<
" * \\param print_header if false, do not print object header (to print attributes of base classes)\n"
302 << dx <<
" * \\param s output stream\n"
304 << dx <<
" virtual void print(unsigned int offset, bool print_header, std::ostream& s) const;\n\n\n"
307 <<
" * \\brief Get values of relationships and results of some algorithms as a vector of "
308 "dunedaq::conffwk::DalObject pointers.\n"
310 << dx <<
" * Parameters are:\n"
311 << dx <<
" * \\param name name of the relationship or algorithm\n"
312 << dx <<
" * \\return value of relationship or result of algorithm\n"
314 <<
" * \\throw std::exception if there is no relationship or algorithm with such name in "
315 "this and base classes\n"
318 <<
" virtual std::vector<const dunedaq::conffwk::DalObject *> get(const std::string& name, bool "
319 "upcast_unregistered = true) const;\n\n\n"
320 << dx <<
" protected:\n\n"
322 <<
" bool get(const std::string& name, std::vector<const dunedaq::conffwk::DalObject *>& vec, bool "
323 "upcast_unregistered, bool first_call) const;\n\n\n";
329 cpp_file << dx <<
" private:\n\n";
336 for (
const auto& i : *alist) {
337 const std::string aname(
alnum_name(i->get_name()));
338 std::string cpp_type =
get_type(i->get_data_type(),
true);
340 if (i->get_is_multi_values())
341 cpp_file << dx <<
" std::vector<" << cpp_type <<
"> m_" << aname <<
";\n";
343 cpp_file << dx <<
" " << cpp_type <<
" m_" << aname <<
";\n";
352 for (
const auto& i : *rlist) {
353 const std::string rname(
alnum_name(i->get_name()));
356 cpp_file << dx <<
" std::vector<const " << full_class_name <<
"*> m_" << rname <<
";\n";
358 cpp_file << dx <<
" const " << full_class_name <<
"* m_" << rname <<
";\n";
364 if (
const std::list<oks::OksMethod*>* mlist = cl->
direct_methods()) {
365 for (
const auto& i : *mlist) {
368 if (!method_extension.empty()) {
370 << dx <<
" // extension of method " << cl->
get_name() <<
"::" << i->get_name() <<
"()\n";
377 cpp_file << std::endl << std::endl << dx <<
" public:\n\n";
388 cpp_file << dx <<
" // attribute names\n\n";
390 for (
const auto& i : *alist) {
391 const std::string& aname(i->get_name());
392 cpp_file << dx <<
" inline static const std::string s_" <<
alnum_name(aname) <<
" = \"" << aname <<
"\";\n";
397 for (
const auto& i : *alist) {
398 const std::string& cpp_aname(
alnum_name(i->get_name()));
399 cpp_file << dx <<
" static const std::string& __get_" << cpp_aname <<
"_str() noexcept { return s_"
400 << cpp_aname <<
"; }\n";
403 cpp_file << std::endl << std::endl;
405 for (
const auto& i : *alist) {
406 const std::string aname(
alnum_name(i->get_name()));
411 std::string description(
"Valid enumeration values to compare with value returned by get_");
412 description += aname;
413 description +=
"() and to pass value to set_";
414 description += aname;
415 description +=
"() methods.";
419 description +=
"\nUse toString() method to compare and to pass the values. Do not use name() method.";
425 while (!(token = t.
next()).empty()) {
430 cpp_file << dx <<
" };\n\n";
437 std::string description(
"Get \"");
438 description += i->get_name();
439 description +=
"\" attribute value.\n\n";
440 description += i->get_description();
442 std::string description2(
"\\brief ");
443 description2 += description;
444 description2 +=
"\n\\return the attribute value\n";
445 description2 +=
"\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
452 cpp_file << dx <<
" ";
454 std::string cpp_type =
get_type(i->get_data_type(),
true);
456 if (i->get_is_multi_values()) {
457 cpp_file <<
"const std::vector<" << cpp_type <<
">&";
459 if (cpp_type ==
"std::string")
460 cpp_file <<
"const std::string&";
462 cpp_file << cpp_type;
466 << dx <<
" get_" << aname <<
"() const\n"
468 << dx <<
" std::lock_guard scoped_lock(m_mutex);\n"
469 << dx <<
" check();\n"
470 << dx <<
" check_init();\n"
471 << dx <<
" return m_" << aname <<
";\n"
477 std::string description(
"Set \"");
478 description += i->get_name();
479 description +=
"\" attribute value.\n\n";
480 description += i->get_description();
482 std::string description2(
"\\brief ");
483 description2 += description;
484 description2 +=
"\n\\param value new attribute value\n";
485 description2 +=
"\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
492 cpp_file << dx <<
" void\n" << dx <<
" set_" << aname <<
'(';
494 if (i->get_is_multi_values()) {
495 cpp_file <<
"const std::vector<" << cpp_type <<
">&";
497 if (cpp_type ==
"std::string") {
498 cpp_file <<
"const std::string&";
500 cpp_file << cpp_type;
504 cpp_file <<
" value)\n"
506 << dx <<
" std::lock_guard scoped_lock(m_mutex);\n"
507 << dx <<
" check();\n"
508 << dx <<
" clear();\n"
512 cpp_file <<
"set_by_ref";
514 cpp_file <<
"set_enum";
516 cpp_file <<
"set_class";
518 cpp_file <<
"set_date";
520 cpp_file <<
"set_time";
522 cpp_file <<
"set_by_val";
525 cpp_file <<
"(s_" << aname <<
", value);\n" << dx <<
" }\n\n\n";
538 cpp_file << dx <<
" // relationship names\n\n";
540 for (
const auto& i : *rlist) {
541 const std::string& rname(i->get_name());
542 cpp_file << dx <<
" inline static const std::string s_" <<
alnum_name(rname) <<
" = \"" << rname <<
"\";\n";
547 for (
const auto& i : *rlist) {
548 const std::string& cpp_rname(
alnum_name(i->get_name()));
549 cpp_file << dx <<
" static const std::string& __get_" << cpp_rname <<
"_str() noexcept { return s_"
550 << cpp_rname <<
"; }\n";
553 cpp_file << std::endl << std::endl;
555 for (
const auto& i : *rlist) {
560 std::string description(
"Get \"");
561 description += i->get_name();
562 description +=
"\" relationship value.\n\n";
563 description += i->get_description();
565 std::string description2(
"\\brief ");
566 description2 += description;
567 description2 +=
"\n\\return the relationship value\n";
568 description2 +=
"\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
575 cpp_file << dx <<
" const ";
577 const std::string rname(
alnum_name(i->get_name()));
581 cpp_file <<
"std::vector<const " << full_cpp_class_name <<
"*>&";
583 cpp_file << full_cpp_class_name <<
" *";
587 << dx <<
" get_" << rname <<
"() const\n"
589 << dx <<
" std::lock_guard scoped_lock(m_mutex);\n"
590 << dx <<
" check();\n"
591 << dx <<
" check_init();\n";
595 cpp_file << dx <<
" if (!m_" << rname <<
")\n"
597 << dx <<
" std::ostringstream text;\n"
598 << dx <<
" text << \"relationship \\\"\" << s_" << rname
599 <<
" << \"\\\" of object \" << this << \" is not set\";\n"
600 << dx <<
" throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());\n"
603 cpp_file << dx <<
" if (m_" << rname <<
".empty())\n"
605 << dx <<
" std::ostringstream text;\n"
606 << dx <<
" text << \"relationship \\\"\" << s_" << rname
607 <<
" << \"\\\" of object \" << this << \" is empty\";\n"
608 << dx <<
" throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());\n"
613 cpp_file << dx <<
" return m_" << rname <<
";\n" << dx <<
" }\n\n\n";
618 std::string description(
"Set \"");
619 description += i->get_name();
620 description +=
"\" relationship value.\n\n";
621 description += i->get_description();
623 std::string description2(
"\\brief ");
624 description2 += description;
625 description2 +=
"\n\\param value new relationship value\n";
626 description2 +=
"\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
631 cpp_file << dx <<
" void\n" << dx <<
" set_" << rname <<
"(const ";
634 cpp_file <<
"std::vector<const " << full_cpp_class_name <<
"*>&";
636 cpp_file << full_cpp_class_name <<
" *";
639 cpp_file <<
" value);\n\n";
646 if (
const std::list<oks::OksMethod*>* mlist = cl->
direct_methods()) {
647 bool cpp_comment_is_printed =
false;
649 for (
const auto& i : *mlist) {
654 if (cpp_comment_is_printed ==
false) {
655 cpp_file << std::endl << dx <<
" public:\n\n" << dx <<
" // user-defined algorithms\n\n";
656 cpp_comment_is_printed =
true;
667 cpp_file << dx <<
" " << mi->get_prototype() <<
";\n";
672 if (!public_method_extension.empty()) {
673 cpp_file <<
"\n" <<
" // extension of method " << cl->
get_name() <<
"::" << i->get_name() <<
"()\n";
682 cpp_file << dx <<
"};\n\n";
686 cpp_file << dx <<
" // out stream operator\n\n"
687 << dx <<
"inline std::ostream& operator<<(std::ostream& s, const " << name <<
"& obj)\n"
689 << dx <<
" return obj.print_object(s);\n"
691 << dx <<
"typedef std::vector<const " << name <<
"*>::const_iterator " << name <<
"Iterator;\n\n";
699 if (
const std::list<oks::OksMethod*>* mlist = cl->
direct_methods()) {
700 for (
const auto& i : *mlist) {
703 cpp_file <<
" // epilogue of method " << cl->
get_name() <<
"::" << i->get_name() <<
"()\n";
711set2out(std::ostream&
out,
const std::set<std::string>& data,
bool& is_first)
713 for (
const auto& x : data) {
718 out <<
'\"' << x <<
"()\"";
725 const std::string& cpp_ns_name,
726 const std::string& cpp_hdr_dir,
729 cpp_s <<
"#include \"logging/Logging.hpp\"\n\n";
733 std::set<oks::OksClass*> rclasses;
738 for (
const auto& i : *rlist) {
746 if (
const std::list<oks::OksMethod*>* mlist = cl->
direct_methods()) {
747 for (
const auto& i : *mlist) {
749 std::string prototype(mi->get_prototype());
750 std::string::size_type idx = prototype.find(
'(');
754 if (idx != std::string::npos) {
758 while (isspace(prototype[idx]) && idx > 0)
762 while (!isspace(prototype[idx]) && idx > 0)
766 prototype.erase(idx + 1);
770 std::remove_if(prototype.begin(), prototype.end(), [](
unsigned char x) { return std::isspace(x); }),
773 if (prototype.empty() ==
false) {
774 idx = prototype.find(
'*');
775 prototype.erase(idx--);
777 if (idx != std::string::npos) {
778 while (isalnum(prototype[idx]) && idx > 0)
781 if (idx == 0 &&
get_add_algo_1(mi) && prototype.find(
"const") == 0)
782 prototype.erase(0, 5);
784 prototype.erase(0, idx + 1);
796 if (!rclasses.empty()) {
797 cpp_s <<
" // include files for classes used in relationships and algorithms\n\n";
799 for (
const auto& j : rclasses) {
800 cpp_s <<
"#include \"" <<
get_include_dir(j, cl_info, cpp_hdr_dir) <<
".hpp\"\n";
803 cpp_s << std::endl << std::endl;
809 std::string ns_dx =
int2dx(ns_level);
810 std::string ns_dx2 = ns_dx +
" ";
812 const char* dx = ns_dx.c_str();
813 const char* dx2 = ns_dx2.c_str();
817 cpp_s << dx <<
"const std::string& " << name
818 <<
"::s_class_name(dunedaq::conffwk::DalFactory::instance().get_known_class_name_ref(\"" << name <<
"\"));\n\n";
820 std::set<std::string> algo_n_set, algo_1_set;
822 if (
const std::list<oks::OksMethod*>* mlist = cl->
direct_methods()) {
823 for (
const auto& i : *mlist) {
825 std::string prototype(mi->get_prototype());
826 std::string::size_type idx = prototype.find(
'(');
828 if (idx != std::string::npos) {
832 while (isspace(prototype[idx]) && idx > 0)
836 prototype.erase(idx + 1);
839 while (!isspace(prototype[idx]) && idx > 0)
843 prototype.erase(0, idx + 1);
846 algo_n_set.insert(prototype);
848 algo_1_set.insert(prototype);
857 cpp_s << dx <<
" // the factory initializer\n\n"
858 << dx <<
"static struct __" << name <<
"_Registrator\n"
860 << dx <<
" __" << name <<
"_Registrator()\n"
862 << dx <<
" dunedaq::conffwk::DalFactory::instance().register_dal_class<" << name <<
">(\""
865 << dx <<
" } registrator;\n\n\n";
870 cpp_s << dx <<
" // the constructor\n\n"
871 << dx << name <<
"::" << name <<
"(conffwk::DalRegistry& db, const conffwk::ConfigObject& o) noexcept :\n"
872 << dx <<
" " <<
"dunedaq::conffwk::DalObject(db, o)";
876 std::list<std::string> initializer_list;
879 for (
auto& i : *slist) {
885 for (std::list<oks::OksRelationship*>::const_iterator i = rlist->begin(); i != rlist->end(); ++i) {
887 initializer_list.push_back(std::string(
"m_") +
alnum_name((*i)->get_name()) +
" (nullptr)");
892 if (
const std::list<oks::OksMethod*>* mlist = cl->
direct_methods()) {
893 for (std::list<oks::OksMethod*>::const_iterator i = mlist->begin(); i != mlist->end(); ++i) {
896 member_initializer.erase(remove(member_initializer.begin(), member_initializer.end(),
'\n'),
897 member_initializer.end());
899 if (!member_initializer.empty()) {
900 initializer_list.push_back(member_initializer);
906 if (initializer_list.empty() ==
false) {
907 for (
auto& i : initializer_list) {
908 cpp_s <<
",\n" << dx <<
" " << i;
914 cpp_s <<
"\n" << dx <<
"{\n" << dx <<
" ;\n" << dx <<
"}\n\n\n";
918 cpp_s << dx <<
"void " << name <<
"::print(unsigned int indent, bool print_header, std::ostream& s) const\n"
920 << dx <<
" check_init();\n\n"
924 cpp_s << dx <<
" const std::string str(indent+2, ' ');\n";
926 cpp_s <<
'\n' << dx <<
" if (print_header)\n" << dx <<
" p_hdr(s, indent, s_class_name";
928 if (!cpp_ns_name.empty()) {
929 cpp_s <<
", \"" << cpp_ns_name <<
'\"';
935 cpp_s <<
"\n\n" << dx <<
" // print direct super-classes\n\n";
937 for (
const auto& i : *slist)
939 <<
"::print(indent, false, s);\n";
943 cpp_s <<
"\n\n" << dx <<
" // print direct attributes\n\n";
945 for (
const auto& i : *alist) {
946 const std::string aname(
alnum_name(i->get_name()));
951 if (i->get_is_multi_values())
952 cpp_s << dx <<
" dunedaq::conffwk::p_mv_attr" << abase <<
"(s, str, s_" << aname <<
", m_" << aname
955 cpp_s << dx <<
" dunedaq::conffwk::p_sv_attr" << abase <<
"(s, str, s_" << aname <<
", m_" << aname
961 cpp_s <<
"\n\n" << dx <<
" // print direct relationships\n\n";
963 for (
const auto& i : *rlist) {
964 const std::string rname(
alnum_name(i->get_name()));
967 if (i->get_is_composite())
968 cpp_s << dx <<
" dunedaq::conffwk::p_mv_rel(s, str, indent, s_" << rname <<
", m_" << rname <<
");\n";
970 cpp_s << dx <<
" dunedaq::conffwk::p_mv_rel(s, str, s_" << rname <<
", m_" << rname <<
");\n";
972 if (i->get_is_composite())
973 cpp_s << dx <<
" dunedaq::conffwk::p_sv_rel(s, str, indent, s_" << rname <<
", m_" << rname <<
");\n";
975 cpp_s << dx <<
" dunedaq::conffwk::p_sv_rel(s, str, s_" << rname <<
", m_" << rname <<
");\n";
980 cpp_s << dx <<
" }\n"
981 << dx <<
" catch (dunedaq::conffwk::Exception & ex) {\n"
982 << dx <<
" dunedaq::conffwk::DalObject::p_error(s, ex);\n"
992 :
"/* init_children */");
994 cpp_s << dx <<
"void " << name <<
"::init(bool " << ic_value <<
")\n" << dx <<
"{\n";
998 cpp_s << dx <<
" p_was_read = true;\n" << dx <<
" increment_read();\n";
1004 for (
const auto& i : *slist) {
1005 cpp_s << dx <<
" " <<
alnum_name(*i) <<
"::init(init_children);\n";
1007 if (!slist->empty())
1011 cpp_s << dx <<
" TLOG_DEBUG(5) << \"read object \" << this << \" (class \" << s_class_name << \')\';\n";
1017 if ((alist && !alist->empty()) || (rlist && !rlist->empty())) {
1018 cpp_s << std::endl << dx <<
" try {\n";
1022 for (
const auto& i : *alist) {
1023 const std::string cpp_name =
alnum_name(i->get_name());
1024 cpp_s << dx <<
" p_obj.get(s_" << cpp_name <<
", m_" << cpp_name <<
");\n";
1030 for (
const auto& i : *rlist) {
1031 const std::string& rname = i->get_name();
1035 cpp_s << dx <<
" p_registry._ref<" << rcname <<
">(p_obj, s_" << cpp_name <<
", " <<
"m_" << cpp_name
1036 <<
", init_children);\n";
1038 cpp_s << dx <<
" m_" << cpp_name <<
" = p_registry._ref<" << rcname <<
">(p_obj, s_" << cpp_name
1039 <<
", init_children);\n";
1044 cpp_s << dx <<
" }\n"
1045 << dx <<
" catch (dunedaq::conffwk::Exception & ex) {\n"
1046 << dx <<
" throw_init_ex(ex);\n"
1050 cpp_s << dx <<
"}\n\n";
1054 cpp_s << dx << name <<
"::~" << name <<
"() noexcept\n" << dx <<
"{\n" << dx <<
"}\n\n";
1056 cpp_s << dx <<
"std::vector<const dunedaq::conffwk::DalObject *> " << name
1057 <<
"::get(const std::string& name, bool upcast_unregistered) const\n"
1059 << dx <<
" std::vector<const dunedaq::conffwk::DalObject *> vec;\n\n"
1060 << dx <<
" if (!get(name, vec, upcast_unregistered, true))\n"
1061 << dx <<
" throw_get_ex(name, s_class_name, this);\n\n"
1062 << dx <<
" return vec;\n"
1065 cpp_s << dx <<
"bool " << name
1066 <<
"::get(const std::string& name, std::vector<const dunedaq::conffwk::DalObject *>& vec, bool "
1067 "upcast_unregistered, bool first_call) const\n"
1069 << dx <<
" if (first_call)\n"
1071 << dx <<
" std::lock_guard scoped_lock(m_mutex);\n\n"
1072 << dx <<
" check();\n"
1073 << dx <<
" check_init();\n\n"
1074 << dx <<
" if (get_rel_objects(name, upcast_unregistered, vec))\n"
1075 << dx <<
" return true;\n"
1078 for (
const auto& prototype : algo_n_set)
1079 cpp_s << dx <<
" if (name == \"" << prototype <<
"()\")\n"
1081 << dx <<
" p_registry.downcast_dal_objects(" << prototype <<
"(), upcast_unregistered, vec);\n"
1082 << dx <<
" return true;\n"
1085 for (
const auto& prototype : algo_1_set)
1086 cpp_s << dx <<
" if (name == \"" << prototype <<
"()\")\n"
1088 << dx <<
" p_registry.downcast_dal_object(" << prototype <<
"(), upcast_unregistered, vec);\n"
1089 << dx <<
" return true;\n"
1093 for (
const auto& i : *slist) {
1094 cpp_s << dx <<
" if (" <<
alnum_name(*i) <<
"::get(name, vec, upcast_unregistered, false)) return true;\n";
1100 cpp_s << dx <<
" if (first_call)\n"
1101 << dx <<
" return get_algo_objects(name, vec);\n\n"
1102 << dx <<
" return false;\n"
1108 for (
const auto& i : *rlist) {
1109 const std::string rname(
alnum_name(i->get_name()));
1112 cpp_s << dx <<
"void " << name <<
"::set_" << rname <<
"(const ";
1115 cpp_s <<
"std::vector<const " << full_cpp_class_name <<
"*>& value)\n"
1117 << dx <<
" _set_objects(s_" << rname <<
", value);\n"
1120 cpp_s << full_cpp_class_name <<
" * value)\n"
1122 << dx <<
" _set_object(s_" << rname <<
", value);\n"
1130 if (
const std::list<oks::OksMethod*>* mlist = cl->
direct_methods()) {
1131 bool comment_is_printed =
false;
1132 for (
const auto& i : *mlist) {
1136 if (comment_is_printed ==
false) {
1137 cpp_s << dx <<
" // user-defined algorithms\n\n";
1138 comment_is_printed =
true;
1148 std::string::size_type idx = prototype.find(
'(');
1150 if (idx != std::string::npos) {
1155 while (isspace(prototype[idx]) && idx > 0)
1160 while ((isalnum(prototype[idx]) || prototype[idx] ==
'_') && idx > 0)
1163 prototype[idx] =
'\n';
1167 prototype.insert(idx + 1, s);
1171 std::string::size_type idx_open_bracket = prototype.find(
'(');
1172 std::string::size_type idx_space = prototype.rfind(
' ', idx_open_bracket);
1173 std::string::size_type idx_close_bracket = prototype.rfind(
')');
1175 auto prototype_attrs = prototype.substr(0, idx_space + 1);
1176 auto prototype_head = prototype.substr(idx_space + 1, idx_close_bracket - idx_space);
1177 auto prototype_specs = prototype.substr(idx_close_bracket + 1);
1180 idx = prototype_attrs.find(spec);
1181 if (idx != std::string::npos) {
1182 prototype_attrs.erase(idx, spec.size());
1184 prototype_attrs =
trim(prototype_attrs);
1186 idx = prototype_specs.find(spec);
1187 if (idx != std::string::npos) {
1188 prototype_specs.erase(idx, spec.size());
1190 prototype_specs =
trim(prototype_specs);
1193 prototype = prototype_attrs +
' ' + prototype_head +
' ' + prototype_specs;
1195 cpp_s << dx << prototype << std::endl
1210 const std::list<std::string>& file_names,
1211 std::set<
oks::OksFile*, std::less<oks::OksFile*>>& file_hs)
1213 for (
const auto& i : file_names) {
1217 std::cerr <<
"ERROR: can not load schema file \"" << i <<
"\"\n";
1226 const std::string& cpp_ns_name,
1227 const std::string& cpp_hdr_dir)
1229 s <<
"// *** this file is generated by oksdalgen, do not modify it ***\n\n"
1238 "#include <stdint.h> // to define 64 bits types\n"
1239 "#include <iostream>\n"
1240 "#include <sstream>\n"
1241 "#include <string>\n"
1243 "#include <vector>\n\n"
1245 "#include \"conffwk/Configuration.hpp\"\n"
1246 "#include \"conffwk/DalObject.hpp\"\n\n";
1258 src <<
"#include \"conffwk/ConfigObject.hpp\"\n"
1259 "#include \"conffwk/DalFactory.hpp\"\n"
1260 "#include \"conffwk/DalObjectPrint.hpp\"\n"
1261 "#include \"conffwk/Errors.hpp\"\n"
1263 if (cpp_hdr_dir !=
"") {
1264 src << cpp_hdr_dir <<
"/";
1266 src << file_name <<
".hpp\"\n\n";
1272 std::list<std::string> class_names;
1273 std::list<std::string> file_names;
1274 std::list<std::string> include_dirs;
1275 std::list<std::string> user_classes;
1277 std::string cpp_dir_name =
".";
1278 std::string cpp_hdr_dir =
"";
1279 std::string cpp_ns_name =
"";
1280 std::string info_file_name =
"oksdalgen.info";
1281 bool verbose =
false;
1297 std::set<oks::OksFile*, std::less<oks::OksFile*>> file_hs;
1306 if (class_names.size() == 0) {
1308 std::cout <<
"No explicit classes were provided,\n"
1309 "search for classes which belong to the given schema files:\n";
1314 if (!class_list.empty()) {
1315 for (
const auto& i : class_list) {
1317 std::cout <<
" * check for class \"" << i.first <<
"\" ";
1320 if (file_hs.find(i.second->get_file()) != file_hs.end()) {
1321 class_names.push_back(i.second->get_name());
1323 std::cout <<
"OK\n";
1327 std::cout <<
"skip\n";
1332 std::cerr <<
"No classes in schema file and no user classes specified\n";
1340 typedef std::set<const oks::OksClass*, std::less<const oks::OksClass*>> Set;
1341 Set generated_classes;
1344 unsigned int error_num = 0;
1348 for (
const auto& i : class_names) {
1350 generated_classes.insert(cl);
1352 std::cerr <<
"ERROR: can not find class " << i << std::endl;
1359 for (
const auto& i : generated_classes) {
1360 if (
const std::list<oks::OksRelationship*>* rels = i->direct_relationships()) {
1361 for (
const auto& j : *rels) {
1365 std::cerr <<
"\nERROR: the class \"" << j->get_type() <<
"\" (it is used by the relationship \""
1366 << j->get_name() <<
"\" of class \"" << i->get_name() <<
"\") is not defined by the schema.\n";
1368 }
else if (generated_classes.find(rc) == generated_classes.end()) {
1370 std::cerr <<
"\nERROR: the class \"" << j->get_type() <<
"\" is used by the relationship \""
1371 << j->get_name() <<
"\" of class \"" << i->get_name()
1373 " The class is not in the list of generated classes, "
1374 "it was not found among already generated headers "
1375 "(search list is defined by the -I | --include-dirs parameter) and "
1376 "it is not defined by user via -D | --user-defined-classes.\n";
1383 if (
const std::list<std::string*>* sclasses = i->direct_super_classes()) {
1384 for (
const auto& j : *sclasses) {
1388 std::cerr <<
"\nERROR: the class \"" << *j <<
"\" (it is direct superclass of class \"" << i->get_name()
1389 <<
"\") is not defined by the schema.\n";
1391 }
else if (generated_classes.find(rc) == generated_classes.end()) {
1393 std::cerr <<
"\nERROR: the class \"" << rc->
get_name() <<
"\" is direct superclass of class \""
1396 " The class is not in the list of generated classes, "
1397 "it was not found among already generated headers "
1398 "(search list is defined by the -I | --include-dirs parameter) and "
1399 "it is not defined by user via -D | --user-defined-classes.\n";
1407 if (error_num != 0) {
1408 std::cerr <<
"\n*** " << error_num << (error_num == 1 ?
" error was" :
" errors were") <<
" found.\n\n";
1409 return (EXIT_FAILURE);
1412 for (
const auto& cl : generated_classes) {
1413 std::string name(
alnum_name(cl->get_name()));
1415 std::string cpp_hdr_name = cpp_dir_name +
"/" + name +
".hpp";
1416 std::string cpp_src_name = cpp_dir_name +
"/" + name +
".cpp";
1418 std::ofstream cpp_hdr_file(cpp_hdr_name.c_str());
1419 std::ofstream cpp_src_file(cpp_src_name.c_str());
1421 if (!cpp_hdr_file) {
1422 std::cerr <<
"ERROR: can not create file \"" << cpp_hdr_name <<
"\"\n";
1423 return (EXIT_FAILURE);
1426 if (!cpp_src_file) {
1427 std::cerr <<
"ERROR: can not create file \"" << cpp_src_name <<
"\"\n";
1428 return (EXIT_FAILURE);
1434 gen_header(cl, cpp_hdr_file, cpp_ns_name, cpp_hdr_dir, cl_info);
1435 gen_cpp_body(cl, cpp_src_file, cpp_ns_name, cpp_hdr_dir, cl_info);
1443 struct ConfigurationImplementations
1447 const char* class_name;
1448 const char* header_prologue;
1449 const char* main_function_prologue;
1450 } confs[] = { { 0,
"conffwk/Configuration.hpp", 0,
"",
"" } };
1452 for (
unsigned int i = 0; i <
sizeof(confs) /
sizeof(ConfigurationImplementations); ++i) {
1453 std::string dump_name = cpp_dir_name +
"/dump";
1454 if (!cpp_ns_name.empty()) {
1458 if (confs[i].name) {
1460 dump_name += confs[i].name;
1462 dump_name +=
".cpp";
1464 std::ofstream dmp(dump_name.c_str());
1466 dmp.exceptions(std::ostream::failbit | std::ostream::badbit);
1475 confs[i].class_name,
1476 confs[i].header_prologue,
1477 confs[i].main_function_prologue);
1478 }
catch (std::exception& ex) {
1479 std::cerr <<
"ERROR: can not create file \"" << dump_name <<
"\": " << ex.what() << std::endl;
1482 std::cerr <<
"ERROR: can not create file \"" << dump_name <<
"\"\n";
1483 return (EXIT_FAILURE);
1491 std::ofstream info(info_file_name.c_str());
1496 std::cerr <<
"ERROR: can not create file \"" << info_file_name <<
"\"\n";
1497 return (EXIT_FAILURE);
1502 std::cerr <<
"Caught oks exception:\n" << ex << std::endl;
1503 return (EXIT_FAILURE);
1504 }
catch (std::exception& e) {
1505 std::cerr <<
"Caught standard C++ exception: " << e.what() << std::endl;
1506 return (EXIT_FAILURE);
1508 std::cerr <<
"Caught unknown exception" << std::endl;
1509 return (EXIT_FAILURE);
1512 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
const std::list< OksAttribute * > * direct_attributes() const noexcept
const std::list< std::string * > * direct_super_classes() const noexcept
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
int main(int argc, char *argv[])
FELIX Initialization std::string initerror FELIX queue timed out
oks::OksMethodImplementation * find_cpp_method_implementation(const oks::OksMethod *method)
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 print_description(std::ostream &s, const std::string &text, const char *dx)
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)