DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
oksdalgen.cxx File Reference
#include "class_info.hpp"
#include "oks/attribute.hpp"
#include "oks/class.hpp"
#include "oks/kernel.hpp"
#include "oks/method.hpp"
#include "oks/relationship.hpp"
#include <ctype.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <list>
#include <set>
#include <string>
Include dependency graph for oksdalgen.cxx:

Go to the source code of this file.

Functions

std::string alnum_name (const std::string &in)
std::string capitalize_name (const std::string &in)
void print_description (std::ostream &s, const std::string &text, const char *dx)
void print_indented (std::ostream &s, const std::string &text, const char *dx)
std::string get_type (oks::OksData::Type oks_type, bool is_cpp)
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)
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)
std::string get_full_cpp_class_name (const oks::OksClass *c, const ClassInfo::Map &cl_info, const std::string &cpp_ns_name)
std::string get_include_dir (const oks::OksClass *c, const ClassInfo::Map &cl_info, const std::string &cpp_hdr_dir)
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)
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)
std::string int2dx (int level)
int open_cpp_namespace (std::ostream &s, const std::string &value)
void close_cpp_namespace (std::ostream &s, int level)
std::string get_method_header_prologue (oks::OksMethodImplementation *)
std::string get_method_header_epilogue (oks::OksMethodImplementation *)
std::string get_public_section (oks::OksMethodImplementation *mi)
std::string get_private_section (oks::OksMethodImplementation *mi)
std::string get_member_initializer_list (oks::OksMethodImplementation *mi)
std::string get_method_implementation_body (oks::OksMethodImplementation *mi)
bool get_add_algo_1 (oks::OksMethodImplementation *mi)
bool get_add_algo_n (oks::OksMethodImplementation *mi)
oks::OksMethodImplementation * find_cpp_method_implementation (const oks::OksMethod *method)
static bool has_superclass (const oks::OksClass *tested, const oks::OksClass *c)
std::string ltrim (const std::string &s)
std::string rtrim (const std::string &s)
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)
static void set2out (std::ostream &out, const std::set< std::string > &data, bool &is_first)
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)
static void load_schemas (oks::OksKernel &kernel, const std::list< std::string > &file_names, std::set< oks::OksFile *, std::less< oks::OksFile * > > &file_hs)
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)
static void gen_cpp_header_epilogue (std::ostream &s)
static void gen_cpp_body_prologue (const std::string &file_name, std::ostream &src, const std::string &cpp_hdr_dir)
int main (int argc, char *argv[])

Variables

const std::string WHITESPACE = " \n\r\t\f\v"
const std::vector< std::string > cpp_method_virtual_specifiers = { "virtual", "override", "final" }

Function Documentation

◆ alnum_name()

std::string alnum_name ( const std::string & in)
extern

Definition at line 37 of file utils.cpp.

38{
39 std::string s(in);
40 std::transform(s.begin(), s.end(), s.begin(), cvt_symbol);
41 return s;
42}
char cvt_symbol(char c)
Definition utils.cpp:31

◆ capitalize_name()

std::string capitalize_name ( const std::string & in)
extern

Definition at line 45 of file utils.cpp.

46{
47 std::string s(in);
48 if (!in.empty()) {
49 if (isalpha(in[0])) {
50 if (islower(in[0]))
51 s[0] = toupper(in[0]);
52 } else {
53 s.insert(s.begin(), '_');
54 }
55 }
56 return s;
57}

◆ close_cpp_namespace()

void close_cpp_namespace ( std::ostream & s,
int level )
extern

Definition at line 612 of file utils.cpp.

613{
614 while (level > 0) {
615 std::string dx = int2dx(--level);
616 s << dx << "}\n";
617 }
618}
std::string int2dx(int level)
Definition utils.cpp:586

◆ find_cpp_method_implementation()

oks::OksMethodImplementation * find_cpp_method_implementation ( const oks::OksMethod * method)
extern

◆ gen_cpp_body()

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 )
static

Definition at line 723 of file oksdalgen.cxx.

728{
729 cpp_s << "#include \"logging/Logging.hpp\"\n\n";
730
731 const std::string name(alnum_name(cl->get_name()));
732
733 std::set<oks::OksClass*> rclasses;
734
735 // for each relationship, include the header file
736
737 if (const std::list<oks::OksRelationship*>* rlist = cl->direct_relationships()) {
738 for (const auto& i : *rlist) {
739 oks::OksClass* c = i->get_class_type();
740 if (has_superclass(cl, c) == false && cl != c) {
741 rclasses.insert(c);
742 }
743 }
744 }
745
746 if (const std::list<oks::OksMethod*>* mlist = cl->direct_methods()) {
747 for (const auto& i : *mlist) {
748 if (oks::OksMethodImplementation* mi = find_cpp_method_implementation(i)) {
749 std::string prototype(mi->get_prototype());
750 std::string::size_type idx = prototype.find('(');
751
752 if (get_add_algo_n(mi) || get_add_algo_1(mi)) {
753
754 if (idx != std::string::npos) {
755 idx--;
756
757 // skip spaces between method name and ()
758 while (isspace(prototype[idx]) && idx > 0)
759 idx--;
760
761 // find beginning of the method name
762 while (!isspace(prototype[idx]) && idx > 0)
763 idx--;
764
765 // remove method name and arguments
766 prototype.erase(idx + 1);
767
768 // remove spaces
769 prototype.erase(
770 std::remove_if(prototype.begin(), prototype.end(), [](unsigned char x) { return std::isspace(x); }),
771 prototype.end());
772
773 if (prototype.empty() == false) {
774 idx = prototype.find('*');
775 prototype.erase(idx--);
776
777 if (idx != std::string::npos) {
778 while (isalnum(prototype[idx]) && idx > 0)
779 idx--;
780
781 if (idx == 0 && get_add_algo_1(mi) && prototype.find("const") == 0)
782 prototype.erase(0, 5);
783 else
784 prototype.erase(0, idx + 1);
785
786 if (oks::OksClass* c = cl->get_kernel()->find_class(prototype))
787 rclasses.insert(c);
788 }
789 }
790 }
791 }
792 }
793 }
794 }
795
796 if (!rclasses.empty()) {
797 cpp_s << " // include files for classes used in relationships and algorithms\n\n";
798
799 for (const auto& j : rclasses) {
800 cpp_s << "#include \"" << get_include_dir(j, cl_info, cpp_hdr_dir) << ".hpp\"\n";
801 }
802
803 cpp_s << std::endl << std::endl;
804 }
805
806 // open namespace
807
808 int ns_level = open_cpp_namespace(cpp_s, cpp_ns_name);
809 std::string ns_dx = int2dx(ns_level);
810 std::string ns_dx2 = ns_dx + " ";
811
812 const char* dx = ns_dx.c_str(); // are used for alignment
813 const char* dx2 = ns_dx2.c_str();
814
815 // static objects
816
817 cpp_s << dx << "const std::string& " << name
818 << "::s_class_name(dunedaq::conffwk::DalFactory::instance().get_known_class_name_ref(\"" << name << "\"));\n\n";
819
820 std::set<std::string> algo_n_set, algo_1_set;
821
822 if (const std::list<oks::OksMethod*>* mlist = cl->direct_methods()) {
823 for (const auto& i : *mlist) {
824 if (oks::OksMethodImplementation* mi = find_cpp_method_implementation(i)) {
825 std::string prototype(mi->get_prototype());
826 std::string::size_type idx = prototype.find('(');
827
828 if (idx != std::string::npos) {
829 idx--;
830
831 // skip spaces between method name and ()
832 while (isspace(prototype[idx]) && idx > 0)
833 idx--;
834
835 // remove method arguments
836 prototype.erase(idx + 1);
837
838 // find beginning of the method name
839 while (!isspace(prototype[idx]) && idx > 0)
840 idx--;
841
842 if (idx > 0) {
843 prototype.erase(0, idx + 1);
844
845 if (get_add_algo_n(mi)) {
846 algo_n_set.insert(prototype);
847 } else if (get_add_algo_1(mi)) {
848 algo_1_set.insert(prototype);
849 }
850 }
851 }
852 }
853 }
854 }
855
856 if (!cl->get_is_abstract()) {
857 cpp_s << dx << " // the factory initializer\n\n"
858 << dx << "static struct __" << name << "_Registrator\n"
859 << dx << " {\n"
860 << dx << " __" << name << "_Registrator()\n"
861 << dx << " {\n"
862 << dx << " dunedaq::conffwk::DalFactory::instance().register_dal_class<" << name << ">(\""
863 << cl->get_name() << "\");\n"
864 << dx << " }\n"
865 << dx << " } registrator;\n\n\n";
866 }
867
868 // the constructor
869
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)";
873
874 // fill member initializer list, if any
875
876 std::list<std::string> initializer_list;
877
878 if (const std::list<std::string*>* slist = cl->direct_super_classes()) {
879 for (auto& i : *slist) {
880 initializer_list.push_back(get_full_cpp_class_name(cl->get_kernel()->find_class(*i), cl_info, "") + "(db, o)");
881 }
882 }
883
884 if (const std::list<oks::OksRelationship*>* rlist = cl->direct_relationships()) {
885 for (std::list<oks::OksRelationship*>::const_iterator i = rlist->begin(); i != rlist->end(); ++i) {
886 if ((*i)->get_high_cardinality_constraint() != oks::OksRelationship::Many) {
887 initializer_list.push_back(std::string("m_") + alnum_name((*i)->get_name()) + " (nullptr)");
888 }
889 }
890 }
891
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) {
894 if (oks::OksMethodImplementation* mi = find_cpp_method_implementation(*i)) {
895 std::string member_initializer = get_member_initializer_list(mi);
896 member_initializer.erase(remove(member_initializer.begin(), member_initializer.end(), '\n'),
897 member_initializer.end());
898
899 if (!member_initializer.empty()) {
900 initializer_list.push_back(member_initializer);
901 }
902 }
903 }
904 }
905
906 if (initializer_list.empty() == false) {
907 for (auto& i : initializer_list) {
908 cpp_s << ",\n" << dx << " " << i;
909 }
910
911 cpp_s << std::endl;
912 }
913
914 cpp_s << "\n" << dx << "{\n" << dx << " ;\n" << dx << "}\n\n\n";
915
916 // print method
917
918 cpp_s << dx << "void " << name << "::print(unsigned int indent, bool print_header, std::ostream& s) const\n"
919 << dx << "{\n"
920 << dx << " check_init();\n\n"
921 << dx << " try {\n";
922
923 if (cl->direct_attributes() || cl->direct_relationships())
924 cpp_s << dx << " const std::string str(indent+2, ' ');\n";
925
926 cpp_s << '\n' << dx << " if (print_header)\n" << dx << " p_hdr(s, indent, s_class_name";
927
928 if (!cpp_ns_name.empty()) {
929 cpp_s << ", \"" << cpp_ns_name << '\"';
930 }
931
932 cpp_s << ");\n";
933
934 if (const std::list<std::string*>* slist = cl->direct_super_classes()) {
935 cpp_s << "\n\n" << dx << " // print direct super-classes\n\n";
936
937 for (const auto& i : *slist)
938 cpp_s << dx << " " << get_full_cpp_class_name(cl->get_kernel()->find_class(*i), cl_info, cpp_ns_name)
939 << "::print(indent, false, s);\n";
940 }
941
942 if (const std::list<oks::OksAttribute*>* alist = cl->direct_attributes()) {
943 cpp_s << "\n\n" << dx << " // print direct attributes\n\n";
944
945 for (const auto& i : *alist) {
946 const std::string aname(alnum_name(i->get_name()));
947 std::string abase = (i->get_format() == oks::OksAttribute::Hex) ? "<dunedaq::conffwk::hex>"
948 : (i->get_format() == oks::OksAttribute::Oct) ? "<dunedaq::conffwk::oct>"
949 : "";
950
951 if (i->get_is_multi_values())
952 cpp_s << dx << " dunedaq::conffwk::p_mv_attr" << abase << "(s, str, s_" << aname << ", m_" << aname
953 << ");\n";
954 else
955 cpp_s << dx << " dunedaq::conffwk::p_sv_attr" << abase << "(s, str, s_" << aname << ", m_" << aname
956 << ");\n";
957 }
958 }
959
960 if (const std::list<oks::OksRelationship*>* rlist = cl->direct_relationships()) {
961 cpp_s << "\n\n" << dx << " // print direct relationships\n\n";
962
963 for (const auto& i : *rlist) {
964 const std::string rname(alnum_name(i->get_name()));
965
966 if (i->get_high_cardinality_constraint() == oks::OksRelationship::Many) {
967 if (i->get_is_composite())
968 cpp_s << dx << " dunedaq::conffwk::p_mv_rel(s, str, indent, s_" << rname << ", m_" << rname << ");\n";
969 else
970 cpp_s << dx << " dunedaq::conffwk::p_mv_rel(s, str, s_" << rname << ", m_" << rname << ");\n";
971 } else {
972 if (i->get_is_composite())
973 cpp_s << dx << " dunedaq::conffwk::p_sv_rel(s, str, indent, s_" << rname << ", m_" << rname << ");\n";
974 else
975 cpp_s << dx << " dunedaq::conffwk::p_sv_rel(s, str, s_" << rname << ", m_" << rname << ");\n";
976 }
977 }
978 }
979
980 cpp_s << dx << " }\n"
981 << dx << " catch (dunedaq::conffwk::Exception & ex) {\n"
982 << dx << " dunedaq::conffwk::DalObject::p_error(s, ex);\n"
983 << dx << " }\n"
984 << dx << "}\n\n\n";
985
986 // init method
987
988 {
989 const char* ic_value = ((cl->direct_relationships() && cl->direct_relationships()->size()) ||
990 (cl->direct_super_classes() && cl->direct_super_classes()->size())
991 ? "init_children"
992 : "/* init_children */");
993
994 cpp_s << dx << "void " << name << "::init(bool " << ic_value << ")\n" << dx << "{\n";
995 }
996
997 if (cl->direct_super_classes() == nullptr) {
998 cpp_s << dx << " p_was_read = true;\n" << dx << " increment_read();\n";
999 }
1000
1001 // generate initialization for super classes
1002
1003 if (const std::list<std::string*>* slist = cl->direct_super_classes()) {
1004 for (const auto& i : *slist) {
1005 cpp_s << dx << " " << alnum_name(*i) << "::init(init_children);\n";
1006 }
1007 if (!slist->empty())
1008 cpp_s << std::endl;
1009 }
1010
1011 cpp_s << dx << " TLOG_DEBUG(5) << \"read object \" << this << \" (class \" << s_class_name << \')\';\n";
1012
1013 // put try / catch only if there are attributes or relationships to be initialized
1014 const std::list<oks::OksAttribute*>* alist = cl->direct_attributes();
1015 const std::list<oks::OksRelationship*>* rlist = cl->direct_relationships();
1016
1017 if ((alist && !alist->empty()) || (rlist && !rlist->empty())) {
1018 cpp_s << std::endl << dx << " try {\n";
1019
1020 // generate initialization for attributes
1021 if (alist) {
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";
1025 }
1026 }
1027
1028 // generate initialization for relationships
1029 if (rlist) {
1030 for (const auto& i : *rlist) {
1031 const std::string& rname = i->get_name();
1032 std::string cpp_name = alnum_name(rname);
1033 std::string rcname = get_full_cpp_class_name(i->get_class_type(), cl_info, cpp_ns_name);
1034 if (i->get_high_cardinality_constraint() == oks::OksRelationship::Many) {
1035 cpp_s << dx << " p_registry._ref<" << rcname << ">(p_obj, s_" << cpp_name << ", " << "m_" << cpp_name
1036 << ", init_children);\n";
1037 } else {
1038 cpp_s << dx << " m_" << cpp_name << " = p_registry._ref<" << rcname << ">(p_obj, s_" << cpp_name
1039 << ", init_children);\n";
1040 }
1041 }
1042 }
1043
1044 cpp_s << dx << " }\n"
1045 << dx << " catch (dunedaq::conffwk::Exception & ex) {\n"
1046 << dx << " throw_init_ex(ex);\n"
1047 << dx << " }\n";
1048 }
1049
1050 cpp_s << dx << "}\n\n";
1051
1052 // destructor
1053
1054 cpp_s << dx << name << "::~" << name << "() noexcept\n" << dx << "{\n" << dx << "}\n\n";
1055
1056 cpp_s << dx << "std::vector<const dunedaq::conffwk::DalObject *> " << name
1057 << "::get(const std::string& name, bool upcast_unregistered) const\n"
1058 << dx << "{\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"
1063 << dx << "}\n\n";
1064
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"
1068 << dx << "{\n"
1069 << dx << " if (first_call)\n"
1070 << dx << " {\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"
1076 << dx << " }\n\n";
1077
1078 for (const auto& prototype : algo_n_set)
1079 cpp_s << dx << " if (name == \"" << prototype << "()\")\n"
1080 << dx << " {\n"
1081 << dx << " p_registry.downcast_dal_objects(" << prototype << "(), upcast_unregistered, vec);\n"
1082 << dx << " return true;\n"
1083 << dx << " }\n\n";
1084
1085 for (const auto& prototype : algo_1_set)
1086 cpp_s << dx << " if (name == \"" << prototype << "()\")\n"
1087 << dx << " {\n"
1088 << dx << " p_registry.downcast_dal_object(" << prototype << "(), upcast_unregistered, vec);\n"
1089 << dx << " return true;\n"
1090 << dx << " }\n\n";
1091
1092 if (const std::list<std::string*>* slist = cl->direct_super_classes()) {
1093 for (const auto& i : *slist) {
1094 cpp_s << dx << " if (" << alnum_name(*i) << "::get(name, vec, upcast_unregistered, false)) return true;\n";
1095 }
1096
1097 cpp_s << "\n";
1098 }
1099
1100 cpp_s << dx << " if (first_call)\n"
1101 << dx << " return get_algo_objects(name, vec);\n\n"
1102 << dx << " return false;\n"
1103 << dx << "}\n\n";
1104
1105 // generate relationship set methods
1106
1107 if (const std::list<oks::OksRelationship*>* rlist = cl->direct_relationships()) {
1108 for (const auto& i : *rlist) {
1109 const std::string rname(alnum_name(i->get_name()));
1110 std::string full_cpp_class_name = get_full_cpp_class_name(i->get_class_type(), cl_info, cpp_ns_name);
1111
1112 cpp_s << dx << "void " << name << "::set_" << rname << "(const ";
1113
1114 if (i->get_high_cardinality_constraint() == oks::OksRelationship::Many) {
1115 cpp_s << "std::vector<const " << full_cpp_class_name << "*>& value)\n"
1116 << dx << "{\n"
1117 << dx << " _set_objects(s_" << rname << ", value);\n"
1118 << dx << "}\n\n";
1119 } else {
1120 cpp_s << full_cpp_class_name << " * value)\n"
1121 << dx << "{\n"
1122 << dx << " _set_object(s_" << rname << ", value);\n"
1123 << dx << "}\n\n";
1124 }
1125 }
1126 }
1127
1128 // generate methods for c++
1129
1130 if (const std::list<oks::OksMethod*>* mlist = cl->direct_methods()) {
1131 bool comment_is_printed = false;
1132 for (const auto& i : *mlist) {
1133 oks::OksMethodImplementation* mi = find_cpp_method_implementation(i);
1134
1135 if (mi && !get_method_implementation_body(mi).empty()) {
1136 if (comment_is_printed == false) {
1137 cpp_s << dx << " // user-defined algorithms\n\n";
1138 comment_is_printed = true;
1139 }
1140
1141 // generate description
1142
1143 print_description(cpp_s, i->get_description(), dx2);
1144
1145 // generate prototype
1146
1147 std::string prototype(mi->get_prototype());
1148 std::string::size_type idx = prototype.find('(');
1149
1150 if (idx != std::string::npos) {
1151 idx--;
1152
1153 // skip spaces between method name and ()
1154
1155 while (isspace(prototype[idx]) && idx > 0)
1156 idx--;
1157
1158 // find beginning of the method name
1159
1160 while ((isalnum(prototype[idx]) || prototype[idx] == '_') && idx > 0)
1161 idx--;
1162
1163 prototype[idx] = '\n';
1164 std::string s(dx);
1165 s += alnum_name(name);
1166 s += "::";
1167 prototype.insert(idx + 1, s);
1168 }
1169
1170 // Second pass
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(')');
1174
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);
1178
1179 for (const auto& spec : cpp_method_virtual_specifiers) {
1180 idx = prototype_attrs.find(spec);
1181 if (idx != std::string::npos) {
1182 prototype_attrs.erase(idx, spec.size());
1183 }
1184 prototype_attrs = trim(prototype_attrs);
1185
1186 idx = prototype_specs.find(spec);
1187 if (idx != std::string::npos) {
1188 prototype_specs.erase(idx, spec.size());
1189 }
1190 prototype_specs = trim(prototype_specs);
1191 }
1192
1193 prototype = prototype_attrs + ' ' + prototype_head + ' ' + prototype_specs;
1194
1195 cpp_s << dx << prototype << std::endl
1196 << dx << "{\n"
1197 << get_method_implementation_body(mi) << std::endl
1198 << dx << "}\n\n";
1199 }
1200 }
1201 }
1202
1203 // close namespace
1204
1205 close_cpp_namespace(cpp_s, ns_level);
1206}
void remove(QString const &db, QString const &fn)
oks::OksMethodImplementation * find_cpp_method_implementation(const oks::OksMethod *method)
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)
std::string get_member_initializer_list(oks::OksMethodImplementation *mi)
static bool has_superclass(const oks::OksClass *tested, const oks::OksClass *c)
void close_cpp_namespace(std::ostream &s, int level)
Definition utils.cpp:612
bool get_add_algo_1(oks::OksMethodImplementation *mi)
const std::vector< std::string > cpp_method_virtual_specifiers
std::string get_include_dir(const oks::OksClass *c, const ClassInfo::Map &cl_info, const std::string &cpp_hdr_dir)
int open_cpp_namespace(std::ostream &s, const std::string &value)
Definition utils.cpp:592
bool get_add_algo_n(oks::OksMethodImplementation *mi)
std::string alnum_name(const std::string &in)
Definition utils.cpp:37
std::string get_method_implementation_body(oks::OksMethodImplementation *mi)
void print_description(std::ostream &s, const std::string &text, const char *dx)
Definition utils.cpp:65

◆ gen_cpp_body_prologue()

void gen_cpp_body_prologue ( const std::string & file_name,
std::ostream & src,
const std::string & cpp_hdr_dir )
static

Definition at line 1256 of file oksdalgen.cxx.

1257{
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"
1262 "#include \"";
1263 if (cpp_hdr_dir != "") {
1264 src << cpp_hdr_dir << "/";
1265 }
1266 src << file_name << ".hpp\"\n\n";
1267}

◆ gen_cpp_header_epilogue()

void gen_cpp_header_epilogue ( std::ostream & s)
static

Definition at line 1250 of file oksdalgen.cxx.

1251{
1252 s << "\n#endif\n";
1253}

◆ gen_cpp_header_prologue()

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 )
static

Definition at line 1224 of file oksdalgen.cxx.

1228{
1229 s << "// *** this file is generated by oksdalgen, do not modify it ***\n\n"
1230
1231 "#ifndef _"
1232 << alnum_name(file_name) << "_0_" << alnum_name(cpp_ns_name) << "_0_" << alnum_name(cpp_hdr_dir)
1233 << "_H_\n"
1234 "#define _"
1235 << alnum_name(file_name) << "_0_" << alnum_name(cpp_ns_name) << "_0_" << alnum_name(cpp_hdr_dir)
1236 << "_H_\n\n"
1237
1238 "#include <stdint.h> // to define 64 bits types\n"
1239 "#include <iostream>\n"
1240 "#include <sstream>\n"
1241 "#include <string>\n"
1242 "#include <map>\n"
1243 "#include <vector>\n\n"
1244
1245 "#include \"conffwk/Configuration.hpp\"\n"
1246 "#include \"conffwk/DalObject.hpp\"\n\n";
1247}

◆ gen_dump_application()

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 )
extern

Definition at line 157 of file utils.cpp.

165{
166 s << " // *** this file is generated by oksdalgen ***\n"
167 "\n"
168 "#include \"conffwk/ConfigObject.hpp\"\n"
169 "#include \""
170 << conf_header << "\"\n\n";
171
172 // generate list of includes
173 for (const auto& i : class_names) {
174 std::string hname(cpp_hdr_dir);
175 if (!hname.empty())
176 hname += '/';
177 hname += i;
178 s << "#include \"" << hname << ".hpp\"\n";
179 }
180
181 if (headres_prologue && *headres_prologue) {
182 s << "\n // db implementation-specific headrers prologue\n\n" << headres_prologue << "\n";
183 }
184
185 s << "\n"
186 "\n"
187 "static void usage(const char * s)\n"
188 "{\n"
189 " std::cout << s << \" -d db-name -c class-name [-q query | -i object-id] [-t]\\n\"\n"
190 " \"\\n\"\n"
191 " \"Options/Arguments:\\n\"\n"
192 " \" -d | --data db-name mandatory name of the database\\n\"\n"
193 " \" -c | --class-name class-name mandatory name of class\\n\"\n"
194 " \" -q | --query query optional query to select class objects\\n\"\n"
195 " \" -i | --object-id object-id optional identity to select one object\\n\"\n"
196 " \" -t | --init-children all referenced objects are initialized (is used\\n\"\n"
197 " \" for debug purposes and performance measurements)\\n\"\n"
198 " \" -h | --help print this message\\n\"\n"
199 " \"\\n\"\n"
200 " \"Description:\\n\"\n"
201 " \" The program prints out object(s) of given class.\\n\"\n"
202 " \" If no query or object id is provided, all objects of the class are printed.\\n\"\n"
203 " \" It is automatically generated by oksdalgen utility.\\n\"\n"
204 " \"\\n\";\n"
205 "}\n"
206 "\n"
207 "static void no_param(const char * s)\n"
208 "{\n"
209 " std::cerr << \"ERROR: the required argument for option \\\'\" << s << \"\\\' is missing\\n\\n\";\n"
210 " exit (EXIT_FAILURE);\n"
211 "}\n"
212 "\n"
213 "int main(int argc, char *argv[])\n"
214 "{\n";
215
216 if (main_function_prologue && *main_function_prologue) {
217 s << " // db implementation-specific main function prologue\n\n " << main_function_prologue << "\n\n";
218 }
219
220 s << " // parse parameters\n"
221 "\n"
222 " const char * db_name = nullptr;\n"
223 " const char * object_id = nullptr;\n"
224 " const char * query = \"\";\n"
225 " std::string class_name;\n"
226 " bool init_children = false;\n"
227 "\n"
228 " for(int i = 1; i < argc; i++) {\n"
229 " const char * cp = argv[i];\n"
230 " if(!strcmp(cp, \"-h\") || !strcmp(cp, \"--help\")) {\n"
231 " usage(argv[0]);\n"
232 " return 0;\n"
233 " }\n"
234 " if(!strcmp(cp, \"-t\") || !strcmp(cp, \"--init-children\")) {\n"
235 " init_children = true;\n"
236 " }\n"
237 " else if(!strcmp(cp, \"-d\") || !strcmp(cp, \"--data\")) {\n"
238 " if(++i == argc || argv[i][0] == '-') { no_param(cp); } else { db_name = argv[i]; }\n"
239 " }\n"
240 " else if(!strcmp(cp, \"-c\") || !strcmp(cp, \"--class-name\")) {\n"
241 " if(++i == argc || argv[i][0] == '-') { no_param(cp); } else { class_name = argv[i]; }\n"
242 " }\n"
243 " else if(!strcmp(cp, \"-i\") || !strcmp(cp, \"--object-id\")) {\n"
244 " if(++i == argc || argv[i][0] == '-') { no_param(cp); } else { object_id = argv[i]; }\n"
245 " }\n"
246 " else if(!strcmp(cp, \"-q\") || !strcmp(cp, \"--query\")) {\n"
247 " if(++i == argc || argv[i][0] == '-') { no_param(cp); } else { query = argv[i]; }\n"
248 " }\n"
249 " else {\n"
250 " std::cerr << \"ERROR: bad parameter \" << cp << std::endl;\n"
251 " usage(argv[0]);\n"
252 " return (EXIT_FAILURE);\n"
253 " }\n"
254 " }\n"
255 "\n"
256 " if(db_name == nullptr) {\n"
257 " std::cerr << \"ERROR: no database name provided\\n\";\n"
258 " return (EXIT_FAILURE);\n"
259 " }\n"
260 "\n"
261 " if(class_name.empty()) {\n"
262 " std::cerr << \"ERROR: no class name provided\\n\";\n"
263 " return (EXIT_FAILURE);\n"
264 " }\n"
265 "\n"
266 " if(*query != 0 && object_id != nullptr) {\n"
267 " std::cerr << \"ERROR: only one parameter -i or -q can be provided\\n\";\n"
268 " return (EXIT_FAILURE);\n"
269 " }\n"
270 "\n"
271 "\n"
272 "std::cout << std::boolalpha;\n"
273 "\n";
274
275 if (conf_name) {
276 s << " " << conf_name
277 << " impl_conf;\n"
278 "\n"
279 " {\n"
280 " dunedaq::conffwk::Configuration conf(db_name, &impl_conf);\n";
281 } else {
282 s << " try {\n"
283 " dunedaq::conffwk::Configuration conf(db_name);\n";
284 }
285
286 s << "\n"
287 " if(!conf.loaded()) {\n"
288 " std::cerr << \"Can not load database: \" << db_name << std::endl;\n"
289 " return (EXIT_FAILURE);\n"
290 " }\n"
291 " \n"
292 " std::vector< dunedaq::conffwk::ConfigObject > objects;\n"
293 " \n"
294 " if(object_id) {\n"
295 " dunedaq::conffwk::ConfigObject obj;\n"
296 " try {\n"
297 " conf.get(class_name, object_id, obj, 1);\n"
298 " }\n"
299 " catch (dunedaq::conffwk::NotFound & ex) {\n"
300 " std::cerr << \"Can not get object \\'\" << object_id << \"\\' of class \\'\" << class_name << "
301 "\"\\':\\n\" << ex << std::endl;\n"
302 " return (EXIT_FAILURE);\n"
303 " }\n"
304 " objects.push_back(obj);\n"
305 " }\n"
306 " else {\n"
307 " try {\n"
308 " conf.get(class_name, objects, query, 1);\n"
309 " }\n"
310 " catch (dunedaq::conffwk::NotFound & ex) {\n"
311 " std::cerr << \"Can not get objects of class \\'\" << class_name << \"\\':\\n\" << ex << std::endl;\n"
312 " return (EXIT_FAILURE);\n"
313 " }\n"
314 " }\n"
315 " \n"
316 " struct SortByUId {\n"
317 " bool operator() (const dunedaq::conffwk::ConfigObject * o1, const dunedaq::conffwk::ConfigObject * o2) "
318 "const {\n"
319 " return (o1->UID() < o2->UID());\n"
320 " };\n"
321 " };\n"
322 " \n"
323 " std::set< dunedaq::conffwk::ConfigObject *, SortByUId > sorted_objects;\n"
324 " \n"
325 " for(auto& i : objects)\n"
326 " sorted_objects.insert(&i);\n"
327 " \n"
328 " for(auto& i : sorted_objects) {\n";
329
330 for (std::list<std::string>::iterator i = class_names.begin(); i != class_names.end(); ++i) {
331 const char* op = (i == class_names.begin() ? "if" : "else if");
332 std::string cname(cpp_ns_name);
333
334 if (!cname.empty())
335 cname += "::";
336
337 cname += *i;
338
339 s << " " << op << "(class_name == \"" << *i
340 << "\") {\n"
341 " std::cout << *conf.get<"
342 << cname
343 << ">(*i, init_children) << std::endl;\n"
344 " }\n";
345 }
346
347 s << " else {\n"
348 " std::cerr << \"ERROR: do not know how to dump object of \" << class_name << \" class\\n\";\n"
349 " return (EXIT_FAILURE);\n"
350 " }\n"
351 " }\n"
352 " }\n"
353 " catch (dunedaq::conffwk::Exception & ex) {\n"
354 " std::cerr << \"Caught \" << ex << std::endl;\n"
355 " return (EXIT_FAILURE);\n"
356 " }\n"
357 "\n"
358 " return 0;\n"
359 "}\n";
360}

◆ gen_header()

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 )
static

Definition at line 147 of file oksdalgen.cxx.

152{
153 const std::string name(alnum_name(cl->get_name()));
154
155 // get includes for super classes if necessary
156
157 if (const std::list<std::string*>* super_list = cl->direct_super_classes()) {
158 cpp_file << " // include files for classes used in inheritance hierarchy\n\n";
159
160 for (const auto& i : *super_list) {
161 oks::OksClass* c = cl->get_kernel()->find_class(*i);
162 cpp_file << "#include \"" << get_include_dir(c, cl_info, cpp_hdr_dir) << ".hpp\"\n";
163 }
164 }
165
166 cpp_file << std::endl;
167
168 // generate forward declarations if necessary
169 {
170 // create set of classes to avoid multiple forward declarations of the same class
171 std::set<oks::OksClass*> rclasses;
172
173 // check direct relationships (c++)
174 if (cl->direct_relationships() && !cl->direct_relationships()->empty())
175 for (const auto& i : *cl->direct_relationships())
176 rclasses.insert(i->get_class_type());
177
178 // check methods
179 if (const std::list<oks::OksMethod*>* mlist = cl->direct_methods()) {
180 for (const auto& i : *mlist) {
181 if (oks::OksMethodImplementation* mi = find_cpp_method_implementation(i)) {
182 const std::string mp(mi->get_prototype());
183 for (const auto& j : cl->get_kernel()->classes()) {
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);
188 }
189 }
190 }
191 }
192
193 NameSpaceInfo ns_info;
194
195 for (const auto& c : rclasses) {
196 // check if the class' header is not already included
197 if (has_superclass(cl, c) || cl == c)
198 continue;
199
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()));
202 }
203
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);
207 cpp_file << "\n\n";
208 }
209 }
210
211 // generate methods prologues if necessary
212
213 if (const std::list<oks::OksMethod*>* mlist = cl->direct_methods())
214 for (const auto& i : *mlist)
215 if (oks::OksMethodImplementation* mi = find_cpp_method_implementation(i))
216 if (!get_method_header_prologue(mi).empty()) {
217 cpp_file << " // prologue of method " << cl->get_name() << "::" << i->get_name() << "()\n";
218 cpp_file << get_method_header_prologue(mi) << std::endl;
219 }
220
221 // open namespace
222
223 int ns_level = open_cpp_namespace(cpp_file, cpp_ns_name);
224 std::string ns_dx = int2dx(ns_level);
225 std::string ns_dx2 = ns_dx + " ";
226
227 const char* dx = ns_dx.c_str(); // are used for alignment
228 const char* dx2 = ns_dx2.c_str();
229
230 // generate description
231
232 {
233 std::string txt(
234 "Declares methods to get and put values of attributes / relationships, to print and to destroy object.\n");
235
236 txt += "<p>\n"
237 "The methods can throw several exceptions:\n"
238 "<ul>\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"
243 "</ul>\n"
244 "<p>\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";
248
249 if (!cl->get_description().empty()) {
250 txt += "\n<p>\n";
251 txt += cl->get_description();
252 txt += "\n";
253 }
254
255 txt += "@author oksdalgen\n";
256
257 cpp_file << std::endl;
258 print_description(cpp_file, cl->get_description(), dx);
259 }
260
261 // generate class declaration itself
262
263 cpp_file << dx << "class " << name << " : ";
264
265 // generate inheritance list
266
267 if (const std::list<std::string*>* super_list = cl->direct_super_classes()) {
268 for (std::list<std::string*>::const_iterator i = super_list->begin(); i != super_list->end();) {
269 const oks::OksClass* c = cl->get_kernel()->find_class(**i);
270 cpp_file << "public " << get_full_cpp_class_name(c, cl_info, cpp_ns_name);
271 if (++i != super_list->end())
272 cpp_file << ", ";
273 }
274 } else {
275 cpp_file << "public virtual dunedaq::conffwk::DalObject";
276 }
277
278 cpp_file << " {\n\n";
279
280 // generate standard methods
281
282 cpp_file
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"
294 << dx << " /**\n"
295 << dx << " * \\brief Print details of the " << name << " object.\n"
296 << dx << " *\n"
297 << dx << " * Parameters are:\n"
298 << dx
299 << " * \\param offset number of spaces to shift object right (useful to print nested objects)\n"
300 << dx
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"
303 << dx << " */\n\n"
304 << dx << " virtual void print(unsigned int offset, bool print_header, std::ostream& s) const;\n\n\n"
305 << dx << " /**\n"
306 << dx
307 << " * \\brief Get values of relationships and results of some algorithms as a vector of "
308 "dunedaq::conffwk::DalObject pointers.\n"
309 << dx << " *\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"
313 << dx
314 << " * \\throw std::exception if there is no relationship or algorithm with such name in "
315 "this and base classes\n"
316 << dx << " */\n\n"
317 << dx
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"
321 << dx
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";
324
325 // generate class attributes and relationships in accordance with
326 // database schema
327
328 if (cl->direct_attributes() || cl->direct_relationships() || cl->direct_methods()) {
329 cpp_file << dx << " private:\n\n";
330
331 // generate attributes:
332 // - for single attributes this is a normal member variable.
333 // - for multiple values this is a std::vector<T>.
334
335 if (const std::list<oks::OksAttribute*>* alist = cl->direct_attributes()) {
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);
339
340 if (i->get_is_multi_values())
341 cpp_file << dx << " std::vector<" << cpp_type << "> m_" << aname << ";\n";
342 else
343 cpp_file << dx << " " << cpp_type << " m_" << aname << ";\n";
344 }
345 }
346
347 // generate relationships:
348 // - for single values this is just a pointer.
349 // - for multiple values this is a vector of pointers.
350
351 if (const std::list<oks::OksRelationship*>* rlist = cl->direct_relationships()) {
352 for (const auto& i : *rlist) {
353 const std::string rname(alnum_name(i->get_name()));
354 const std::string full_class_name(get_full_cpp_class_name(i->get_class_type(), cl_info, cpp_ns_name));
355 if (i->get_high_cardinality_constraint() == oks::OksRelationship::Many)
356 cpp_file << dx << " std::vector<const " << full_class_name << "*> m_" << rname << ";\n";
357 else
358 cpp_file << dx << " const " << full_class_name << "* m_" << rname << ";\n";
359 }
360 }
361
362 // generate methods extension if any
363
364 if (const std::list<oks::OksMethod*>* mlist = cl->direct_methods()) {
365 for (const auto& i : *mlist) {
366 if (oks::OksMethodImplementation* mi = find_cpp_method_implementation(i)) {
367 std::string method_extension = get_private_section(mi);
368 if (!method_extension.empty()) {
369 cpp_file << "\n"
370 << dx << " // extension of method " << cl->get_name() << "::" << i->get_name() << "()\n";
371 print_indented(cpp_file, method_extension, dx2);
372 }
373 }
374 }
375 }
376
377 cpp_file << std::endl << std::endl << dx << " public:\n\n";
378
379 // generate attribute accessors:
380 // 1. for each attribute generate static std::string with it's name
381 // 2a. for single values this is just:
382 // - attribute_type attribute_name() const { return m_attribute; }
383 // 2b. for multiple values this is:
384 // - const std::vector<attribute_type>& attribute_name() const { return m_attribute; }
385
386 if (const std::list<oks::OksAttribute*>* alist = cl->direct_attributes()) {
387
388 cpp_file << dx << " // attribute names\n\n";
389
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";
393 }
394
395 cpp_file << "\n";
396
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";
401 }
402
403 cpp_file << std::endl << std::endl;
404
405 for (const auto& i : *alist) {
406 const std::string aname(alnum_name(i->get_name()));
407
408 // generate enum values
409
410 if (i->get_data_type() == oks::OksData::enum_type && !i->get_range().empty()) {
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.";
416
417 print_description(cpp_file, description, dx2);
418
419 description += "\nUse toString() method to compare and to pass the values. Do not use name() method.";
420
421 cpp_file << dx << " struct " << capitalize_name(aname) << " {\n";
422
423 oks::Oks::Tokenizer t(i->get_range(), ",");
424 std::string token;
425 while (!(token = t.next()).empty()) {
426 cpp_file << dx << " inline static const std::string " << capitalize_name(alnum_name(token)) << " = \""
427 << token << "\";\n";
428 }
429
430 cpp_file << dx << " };\n\n";
431 }
432
433 // generate get method description
434
435 {
436
437 std::string description("Get \"");
438 description += i->get_name();
439 description += "\" attribute value.\n\n";
440 description += i->get_description();
441
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";
446
447 print_description(cpp_file, description2, dx2);
448 }
449
450 // generate method body
451
452 cpp_file << dx << " ";
453
454 std::string cpp_type = get_type(i->get_data_type(), true);
455
456 if (i->get_is_multi_values()) {
457 cpp_file << "const std::vector<" << cpp_type << ">&";
458 } else {
459 if (cpp_type == "std::string")
460 cpp_file << "const std::string&";
461 else
462 cpp_file << cpp_type;
463 }
464
465 cpp_file << '\n'
466 << dx << " get_" << aname << "() const\n"
467 << dx << " {\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"
472 << dx << " }\n\n";
473
474 // generate set method description
475
476 {
477 std::string description("Set \"");
478 description += i->get_name();
479 description += "\" attribute value.\n\n";
480 description += i->get_description();
481
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";
486
487 print_description(cpp_file, description2, dx2);
488 }
489
490 // generate set method
491
492 cpp_file << dx << " void\n" << dx << " set_" << aname << '(';
493
494 if (i->get_is_multi_values()) {
495 cpp_file << "const std::vector<" << cpp_type << ">&";
496 } else {
497 if (cpp_type == "std::string") {
498 cpp_file << "const std::string&";
499 } else {
500 cpp_file << cpp_type;
501 }
502 }
503
504 cpp_file << " value)\n"
505 << dx << " {\n"
506 << dx << " std::lock_guard scoped_lock(m_mutex);\n"
507 << dx << " check();\n"
508 << dx << " clear();\n"
509 << dx << " p_obj.";
510
511 if (i->get_data_type() == oks::OksData::string_type && i->get_is_multi_values() == false) {
512 cpp_file << "set_by_ref";
513 } else if (i->get_data_type() == oks::OksData::enum_type) {
514 cpp_file << "set_enum";
515 } else if (i->get_data_type() == oks::OksData::class_type) {
516 cpp_file << "set_class";
517 } else if (i->get_data_type() == oks::OksData::date_type) {
518 cpp_file << "set_date";
519 } else if (i->get_data_type() == oks::OksData::time_type) {
520 cpp_file << "set_time";
521 } else {
522 cpp_file << "set_by_val";
523 }
524
525 cpp_file << "(s_" << aname << ", value);\n" << dx << " }\n\n\n";
526 }
527 }
528
529 // generate relationship accessors.
530 // 1. for each relationship generate static std::string with it's name
531 // 2a. for single values this is just:
532 // - const relation_type * relation() const { return m_relation; }
533 // 2b. for multiple values this is:
534 // - const std::vector<const relation_type*>& relation() const { return m_relation; }
535
536 if (const std::list<oks::OksRelationship*>* rlist = cl->direct_relationships()) {
537
538 cpp_file << dx << " // relationship names\n\n";
539
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";
543 }
544
545 cpp_file << "\n";
546
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";
551 }
552
553 cpp_file << std::endl << std::endl;
554
555 for (const auto& i : *rlist) {
556
557 // generate description
558
559 {
560 std::string description("Get \"");
561 description += i->get_name();
562 description += "\" relationship value.\n\n";
563 description += i->get_description();
564
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";
569
570 print_description(cpp_file, description2, dx2);
571 }
572
573 // generate method body
574
575 cpp_file << dx << " const ";
576
577 const std::string rname(alnum_name(i->get_name()));
578 std::string full_cpp_class_name = get_full_cpp_class_name(i->get_class_type(), cl_info, cpp_ns_name);
579
580 if (i->get_high_cardinality_constraint() == oks::OksRelationship::Many) {
581 cpp_file << "std::vector<const " << full_cpp_class_name << "*>&";
582 } else {
583 cpp_file << full_cpp_class_name << " *";
584 }
585
586 cpp_file << "\n"
587 << dx << " get_" << rname << "() const\n"
588 << dx << " {\n"
589 << dx << " std::lock_guard scoped_lock(m_mutex);\n"
590 << dx << " check();\n"
591 << dx << " check_init();\n";
592
593 if (i->get_low_cardinality_constraint() == oks::OksRelationship::One) {
594 if (i->get_high_cardinality_constraint() == oks::OksRelationship::One) {
595 cpp_file << dx << " if (!m_" << rname << ")\n"
596 << dx << " {\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"
601 << dx << " }\n";
602 } else {
603 cpp_file << dx << " if (m_" << rname << ".empty())\n"
604 << dx << " {\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"
609 << dx << " }\n";
610 }
611 }
612
613 cpp_file << dx << " return m_" << rname << ";\n" << dx << " }\n\n\n";
614
615 // generate set method
616
617 {
618 std::string description("Set \"");
619 description += i->get_name();
620 description += "\" relationship value.\n\n";
621 description += i->get_description();
622
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";
627
628 print_description(cpp_file, description2, dx2);
629 }
630
631 cpp_file << dx << " void\n" << dx << " set_" << rname << "(const ";
632
633 if (i->get_high_cardinality_constraint() == oks::OksRelationship::Many) {
634 cpp_file << "std::vector<const " << full_cpp_class_name << "*>&";
635 } else {
636 cpp_file << full_cpp_class_name << " *";
637 }
638
639 cpp_file << " value);\n\n";
640 }
641 }
642 }
643
644 // generate methods
645
646 if (const std::list<oks::OksMethod*>* mlist = cl->direct_methods()) {
647 bool cpp_comment_is_printed = false;
648
649 for (const auto& i : *mlist) {
650
651 // C++ algorithms
652
653 if (oks::OksMethodImplementation* mi = find_cpp_method_implementation(i)) {
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;
657 } else {
658 cpp_file << "\n\n";
659 }
660
661 // generate description
662
663 print_description(cpp_file, i->get_description(), dx2);
664
665 // generate prototype
666
667 cpp_file << dx << " " << mi->get_prototype() << ";\n";
668
669 // generate public section extension
670
671 std::string public_method_extension = get_public_section(mi);
672 if (!public_method_extension.empty()) {
673 cpp_file << "\n" << " // extension of method " << cl->get_name() << "::" << i->get_name() << "()\n";
674 print_indented(cpp_file, public_method_extension, " ");
675 }
676 }
677 }
678 }
679
680 // class finished
681
682 cpp_file << dx << "};\n\n";
683
684 // generate ostream operators and typedef for iterator
685
686 cpp_file << dx << " // out stream operator\n\n"
687 << dx << "inline std::ostream& operator<<(std::ostream& s, const " << name << "& obj)\n"
688 << dx << " {\n"
689 << dx << " return obj.print_object(s);\n"
690 << dx << " }\n\n"
691 << dx << "typedef std::vector<const " << name << "*>::const_iterator " << name << "Iterator;\n\n";
692
693 // close namespace
694
695 close_cpp_namespace(cpp_file, ns_level);
696
697 // generate methods epilogues if necessary
698
699 if (const std::list<oks::OksMethod*>* mlist = cl->direct_methods()) {
700 for (const auto& i : *mlist) {
701 oks::OksMethodImplementation* mi = find_cpp_method_implementation(i);
702 if (mi && !get_method_header_epilogue(mi).empty()) {
703 cpp_file << " // epilogue of method " << cl->get_name() << "::" << i->get_name() << "()\n";
704 cpp_file << get_method_header_epilogue(mi) << std::endl;
705 }
706 }
707 }
708}
String tokenizer.
Definition defs.hpp:59
std::string get_public_section(oks::OksMethodImplementation *mi)
std::string get_type(oks::OksData::Type oks_type, bool is_cpp)
Definition utils.cpp:95
std::string get_method_header_prologue(oks::OksMethodImplementation *)
std::string get_private_section(oks::OksMethodImplementation *mi)
std::string get_method_header_epilogue(oks::OksMethodImplementation *)
void print_indented(std::ostream &s, const std::string &text, const char *dx)
Definition utils.cpp:82
std::string capitalize_name(const std::string &in)
Definition utils.cpp:45
void print(std::ostream &s, int level) const
void add(const std::string &ns_name, const std::string &class_name)

◆ get_add_algo_1()

bool get_add_algo_1 ( oks::OksMethodImplementation * mi)
extern

◆ get_add_algo_n()

bool get_add_algo_n ( oks::OksMethodImplementation * mi)
extern

◆ get_full_cpp_class_name()

std::string get_full_cpp_class_name ( const oks::OksClass * c,
const ClassInfo::Map & cl_info,
const std::string & cpp_ns_name )
extern

◆ get_include_dir()

std::string get_include_dir ( const oks::OksClass * c,
const ClassInfo::Map & cl_info,
const std::string & cpp_hdr_dir )
extern

◆ get_member_initializer_list()

std::string get_member_initializer_list ( oks::OksMethodImplementation * mi)
extern

◆ get_method_header_epilogue()

std::string get_method_header_epilogue ( oks::OksMethodImplementation * )
extern

◆ get_method_header_prologue()

std::string get_method_header_prologue ( oks::OksMethodImplementation * )
extern

◆ get_method_implementation_body()

std::string get_method_implementation_body ( oks::OksMethodImplementation * mi)
extern

◆ get_private_section()

std::string get_private_section ( oks::OksMethodImplementation * mi)
extern

◆ get_public_section()

std::string get_public_section ( oks::OksMethodImplementation * mi)
extern

◆ get_type()

std::string get_type ( oks::OksData::Type oks_type,
bool is_cpp )
extern

Definition at line 95 of file utils.cpp.

96{
97 switch (oks_type) {
99 return "UNKNOWN";
101 return (is_cpp ? "int8_t" : "char");
103 return (is_cpp ? "uint8_t" : "byte");
105 return (is_cpp ? "int16_t" : "short");
107 return (is_cpp ? "uint16_t" : "short");
109 return (is_cpp ? "int32_t" : "int");
111 return (is_cpp ? "uint32_t" : "int");
113 return (is_cpp ? "int64_t" : "long");
115 return (is_cpp ? "uint64_t" : "long");
117 return "float";
119 return "double";
121 return (is_cpp ? "bool" : "boolean");
122
128 return (is_cpp ? "std::string" : "String");
129
134 return "funnytype";
135 }
136
137 return "invalid";
138}

◆ has_superclass()

bool has_superclass ( const oks::OksClass * tested,
const oks::OksClass * c )
static

The function has_superclass returns true if 'tested' class has class 'c' as a superclass

Definition at line 109 of file oksdalgen.cxx.

110{
111 if (const oks::OksClass::FList* sclasses = tested->all_super_classes()) {
112 for (const auto& i : *sclasses) {
113 if (i == c) {
114 return true;
115 }
116 }
117 }
118
119 return false;
120}
std::list< OksClass *, boost::fast_pool_allocator< OksClass * > > FList
Definition class.hpp:254

◆ int2dx()

std::string int2dx ( int level)
extern

Definition at line 586 of file utils.cpp.

587{
588 return std::string(level * 2, ' ');
589}

◆ load_schemas()

void load_schemas ( oks::OksKernel & kernel,
const std::list< std::string > & file_names,
std::set< oks::OksFile *, std::less< oks::OksFile * > > & file_hs )
static

Definition at line 1209 of file oksdalgen.cxx.

1212{
1213 for (const auto& i : file_names) {
1214 if (oks::OksFile* fh = kernel.load_schema(i)) {
1215 file_hs.insert(fh);
1216 } else {
1217 std::cerr << "ERROR: can not load schema file \"" << i << "\"\n";
1218 exit(EXIT_FAILURE);
1219 }
1220 }
1221}

◆ ltrim()

std::string ltrim ( const std::string & s)

Definition at line 125 of file oksdalgen.cxx.

126{
127 size_t start = s.find_first_not_of(WHITESPACE);
128 return (start == std::string::npos) ? "" : s.substr(start);
129}
const std::string WHITESPACE

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 1270 of file oksdalgen.cxx.

1271{
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;
1276
1277 std::string cpp_dir_name = "."; // directory for c++ implementation files
1278 std::string cpp_hdr_dir = ""; // directory for c++ header files
1279 std::string cpp_ns_name = ""; // c++ namespace
1280 std::string info_file_name = "oksdalgen.info"; // name of info file
1281 bool verbose = false;
1282
1283 parse_arguments(argc,
1284 argv,
1285 class_names,
1286 file_names,
1287 include_dirs,
1288 user_classes,
1289 cpp_dir_name,
1290 cpp_ns_name,
1291 cpp_hdr_dir,
1292 info_file_name,
1293 verbose);
1294
1295 // init OKS
1296
1297 std::set<oks::OksFile*, std::less<oks::OksFile*>> file_hs;
1298
1299 oks::OksKernel kernel(false, false, false, false);
1300
1301 try {
1302 load_schemas(kernel, file_names, file_hs);
1303
1304 // if no user defined classes, generate all
1305
1306 if (class_names.size() == 0) {
1307 if (verbose) {
1308 std::cout << "No explicit classes were provided,\n"
1309 "search for classes which belong to the given schema files:\n";
1310 }
1311
1312 const oks::OksClass::Map& class_list = kernel.classes();
1313
1314 if (!class_list.empty()) {
1315 for (const auto& i : class_list) {
1316 if (verbose) {
1317 std::cout << " * check for class \"" << i.first << "\" ";
1318 }
1319
1320 if (file_hs.find(i.second->get_file()) != file_hs.end()) {
1321 class_names.push_back(i.second->get_name());
1322 if (verbose) {
1323 std::cout << "OK\n";
1324 }
1325 } else {
1326 if (verbose) {
1327 std::cout << "skip\n";
1328 }
1329 }
1330 }
1331 } else {
1332 std::cerr << "No classes in schema file and no user classes specified\n";
1333 exit(EXIT_FAILURE);
1334 }
1335 }
1336
1337 // calculate set of classes which should be mentioned by the generator;
1338 // note, some of classes can come from other DALs
1339
1340 typedef std::set<const oks::OksClass*, std::less<const oks::OksClass*>> Set;
1341 Set generated_classes;
1342 ClassInfo::Map cl_info;
1343
1344 unsigned int error_num = 0;
1345
1346 // build set of classes which are generated
1347
1348 for (const auto& i : class_names) {
1349 if (oks::OksClass* cl = kernel.find_class(i)) {
1350 generated_classes.insert(cl);
1351 } else {
1352 std::cerr << "ERROR: can not find class " << i << std::endl;
1353 error_num++;
1354 }
1355 }
1356
1357 // build set of classes which are external to generated
1358
1359 for (const auto& i : generated_classes) {
1360 if (const std::list<oks::OksRelationship*>* rels = i->direct_relationships()) {
1361 for (const auto& j : *rels) {
1362 const oks::OksClass* rc = j->get_class_type();
1363
1364 if (rc == 0) {
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";
1367 error_num++;
1368 } else if (generated_classes.find(rc) == generated_classes.end()) {
1369 if (process_external_class(cl_info, rc, include_dirs, user_classes, verbose) == false) {
1370 std::cerr << "\nERROR: the class \"" << j->get_type() << "\" is used by the relationship \""
1371 << j->get_name() << "\" of class \"" << i->get_name()
1372 << "\".\n"
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";
1377 error_num++;
1378 }
1379 }
1380 }
1381 }
1382
1383 if (const std::list<std::string*>* sclasses = i->direct_super_classes()) {
1384 for (const auto& j : *sclasses) {
1385 const oks::OksClass* rc = kernel.find_class(*j);
1386
1387 if (rc == 0) {
1388 std::cerr << "\nERROR: the class \"" << *j << "\" (it is direct superclass of class \"" << i->get_name()
1389 << "\") is not defined by the schema.\n";
1390 error_num++;
1391 } else if (generated_classes.find(rc) == generated_classes.end()) {
1392 if (process_external_class(cl_info, rc, include_dirs, user_classes, verbose) == false) {
1393 std::cerr << "\nERROR: the class \"" << rc->get_name() << "\" is direct superclass of class \""
1394 << i->get_name()
1395 << "\".\n"
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";
1400 error_num++;
1401 }
1402 }
1403 }
1404 }
1405 }
1406
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);
1410 }
1411
1412 for (const auto& cl : generated_classes) {
1413 std::string name(alnum_name(cl->get_name()));
1414
1415 std::string cpp_hdr_name = cpp_dir_name + "/" + name + ".hpp";
1416 std::string cpp_src_name = cpp_dir_name + "/" + name + ".cpp";
1417
1418 std::ofstream cpp_hdr_file(cpp_hdr_name.c_str());
1419 std::ofstream cpp_src_file(cpp_src_name.c_str());
1420
1421 if (!cpp_hdr_file) {
1422 std::cerr << "ERROR: can not create file \"" << cpp_hdr_name << "\"\n";
1423 return (EXIT_FAILURE);
1424 }
1425
1426 if (!cpp_src_file) {
1427 std::cerr << "ERROR: can not create file \"" << cpp_src_name << "\"\n";
1428 return (EXIT_FAILURE);
1429 }
1430
1431 gen_cpp_header_prologue(name, cpp_hdr_file, cpp_ns_name, cpp_hdr_dir);
1432 gen_cpp_body_prologue(name, cpp_src_file, cpp_hdr_dir);
1433
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);
1436
1437 gen_cpp_header_epilogue(cpp_hdr_file);
1438 }
1439
1440 // generate dump applications
1441
1442 {
1443 struct ConfigurationImplementations
1444 {
1445 const char* name;
1446 const char* header;
1447 const char* class_name;
1448 const char* header_prologue;
1449 const char* main_function_prologue;
1450 } confs[] = { { 0, "conffwk/Configuration.hpp", 0, "", "" } };
1451
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()) {
1455 dump_name += '_';
1456 dump_name += alnum_name(cpp_ns_name);
1457 }
1458 if (confs[i].name) {
1459 dump_name += '_';
1460 dump_name += confs[i].name;
1461 }
1462 dump_name += ".cpp";
1463
1464 std::ofstream dmp(dump_name.c_str());
1465
1466 dmp.exceptions(std::ostream::failbit | std::ostream::badbit);
1467
1468 if (dmp) {
1469 try {
1471 class_names,
1472 cpp_ns_name,
1473 cpp_hdr_dir,
1474 confs[i].header,
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;
1480 }
1481 } else {
1482 std::cerr << "ERROR: can not create file \"" << dump_name << "\"\n";
1483 return (EXIT_FAILURE);
1484 }
1485 }
1486 }
1487
1488 // generate info file
1489
1490 {
1491 std::ofstream info(info_file_name.c_str());
1492
1493 if (info) {
1494 write_info_file(info, cpp_ns_name, cpp_hdr_dir, generated_classes);
1495 } else {
1496 std::cerr << "ERROR: can not create file \"" << info_file_name << "\"\n";
1497 return (EXIT_FAILURE);
1498 }
1499 }
1500
1501 } catch (oks::exception& ex) {
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);
1507 } catch (...) {
1508 std::cerr << "Caught unknown exception" << std::endl;
1509 return (EXIT_FAILURE);
1510 }
1511
1512 return (EXIT_SUCCESS);
1513}
std::map< const char *, OksClass *, SortStr > Map
Definition class.hpp:252
std::map< const oks::OksClass *, ClassInfo, SortByName > Map
static void load_schemas(oks::OksKernel &kernel, const std::list< std::string > &file_names, std::set< oks::OksFile *, std::less< oks::OksFile * > > &file_hs)
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)
static void gen_cpp_body_prologue(const std::string &file_name, std::ostream &src, const std::string &cpp_hdr_dir)
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 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)
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)
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)
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)
Definition utils.cpp:157
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)

◆ open_cpp_namespace()

int open_cpp_namespace ( std::ostream & s,
const std::string & value )
extern

Definition at line 592 of file utils.cpp.

593{
594 int level = 0;
595 std::string dx;
596
597 if (!value.empty()) {
598 Oks::Tokenizer t(value, ":");
599 std::string token;
600
601 while (!(token = t.next()).empty()) {
602 s << dx << "namespace " << token << " {\n";
603 level++;
604 dx += " ";
605 }
606 }
607
608 return level;
609}

◆ parse_arguments()

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 )
extern

Definition at line 53 of file parse_cmdl.cpp.

64{
65
66 for (int i = 1; i < argc; i++) {
67 const char* cp = argv[i];
68
69 if (!strcmp(cp, "-h") || !strcmp(cp, "--help")) {
70 usage();
71 exit(EXIT_SUCCESS);
72 } else if (!strcmp(cp, "-v") || !strcmp(cp, "--verbose")) {
73 verbose = true;
74 } else if (!strcmp(cp, "-d") || !strcmp(cp, "--c++-dir-name")) {
75 if (++i == argc || argv[i][0] == '-')
76 no_param(cp);
77 else
78 cpp_dir_name = argv[i];
79 } else if (!strcmp(cp, "-n") || !strcmp(cp, "--c++-namespace")) {
80 if (++i == argc || argv[i][0] == '-')
81 no_param(cp);
82 else
83 cpp_ns_name = argv[i];
84 } else if (!strcmp(cp, "-i") || !strcmp(cp, "--c++-headers-dir")) {
85 if (++i == argc || argv[i][0] == '-')
86 no_param(cp);
87 else
88 cpp_hdr_dir = argv[i];
89 } else if (!strcmp(cp, "-f") || !strcmp(cp, "--info-file-name")) {
90 if (++i == argc || argv[i][0] == '-')
91 no_param(cp);
92 else
93 info_file_name = argv[i];
94 } else {
95 std::list<std::string>* slist = ((!strcmp(cp, "-c") || !strcmp(cp, "--classes")) ? &class_names
96 : (!strcmp(cp, "-s") || !strcmp(cp, "--schema-files")) ? &file_names
97 : (!strcmp(cp, "-I") || !strcmp(cp, "--include-dirs")) ? &include_dirs
98 : (!strcmp(cp, "-D") || !strcmp(cp, "--user-defined-classes")) ? &user_classes
99 : nullptr);
100
101 if (slist) {
102 int j = 0;
103 for (; j < argc - i - 1; ++j) {
104 if (argv[i + 1 + j][0] != '-')
105 slist->push_back(argv[i + 1 + j]);
106 else
107 break;
108 }
109 i += j;
110 } else {
111 std::cerr << "ERROR: Unexpected parameter: \"" << cp << "\"\n\n";
112 usage();
113 exit(EXIT_FAILURE);
114 }
115 }
116 }
117
118 if (file_names.size() == 0) {
119 std::cerr << "At least one schema file is required\n";
120 exit(EXIT_FAILURE);
121 }
122
123 if (verbose) {
124 std::cout << "VERBOSE:\n"
125 " Command line parameters:\n"
126 " c++ directory name: \""
127 << cpp_dir_name
128 << "\"\n"
129 " c++ namespace name: \""
130 << cpp_ns_name
131 << "\"\n"
132 " c++ headers directory: \""
133 << cpp_hdr_dir
134 << "\"\n"
135 " classes:";
136
137 if (!class_names.empty()) {
138 std::cout << std::endl;
139
140 for (const auto& i : class_names)
141 std::cout << " - " << i << std::endl;
142 } else {
143 std::cout << " no\n";
144 }
145
146 std::cout << " file names:";
147
148 if (!file_names.empty()) {
149 std::cout << std::endl;
150
151 for (const auto& i : file_names)
152 std::cout << " * " << i << std::endl;
153 } else {
154 std::cout << " no\n";
155 }
156
157 std::cout << " include directories for search:";
158
159 if (!include_dirs.empty()) {
160 std::cout << std::endl;
161
162 for (const auto& i : include_dirs)
163 std::cout << " * " << i << std::endl;
164 } else {
165 std::cout << " no\n";
166 }
167
168 std::cout << " user-defined classes:";
169
170 if (!user_classes.empty()) {
171 std::cout << std::endl;
172
173 for (const auto& i : user_classes)
174 std::cout << " * " << i << std::endl;
175 } else {
176 std::cout << " no\n";
177 }
178 }
179}
static void usage(const char *s)
static void no_param(const char *s)

◆ print_description()

void print_description ( std::ostream & s,
const std::string & text,
const char * dx )
extern

The function print_description() is used for printing of the multi-line text with right alignment.

Definition at line 65 of file utils.cpp.

66{
67 if (!text.empty()) {
68 s << dx << " /**\n";
69
70 Oks::Tokenizer t(text, "\n");
71 std::string token;
72
73 while (!(token = t.next()).empty()) {
74 s << dx << " * " << token << std::endl;
75 }
76
77 s << dx << " */\n\n";
78 }
79}

◆ print_indented()

void print_indented ( std::ostream & s,
const std::string & text,
const char * dx )
extern

Definition at line 82 of file utils.cpp.

83{
84 if (!text.empty()) {
85 Oks::Tokenizer t(text, "\n");
86 std::string token;
87
88 while (!(token = t.next()).empty()) {
89 s << dx << token << std::endl;
90 }
91 }
92}

◆ process_external_class()

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 )
extern

◆ rtrim()

std::string rtrim ( const std::string & s)

Definition at line 132 of file oksdalgen.cxx.

133{
134 size_t end = s.find_last_not_of(WHITESPACE);
135 return (end == std::string::npos) ? "" : s.substr(0, end + 1);
136}

◆ set2out()

void set2out ( std::ostream & out,
const std::set< std::string > & data,
bool & is_first )
static

Definition at line 711 of file oksdalgen.cxx.

712{
713 for (const auto& x : data) {
714 if (is_first)
715 is_first = false;
716 else
717 out << ',';
718 out << '\"' << x << "()\"";
719 }
720}
FELIX Initialization std::string initerror FELIX queue timed out

◆ trim()

std::string trim ( const std::string & s)

Definition at line 139 of file oksdalgen.cxx.

140{
141 return rtrim(ltrim(s));
142}
std::string ltrim(const std::string &s)
std::string rtrim(const std::string &s)

◆ write_info_file()

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 )
extern

Variable Documentation

◆ cpp_method_virtual_specifiers

const std::vector<std::string> cpp_method_virtual_specifiers = { "virtual", "override", "final" }

Definition at line 144 of file oksdalgen.cxx.

◆ WHITESPACE

const std::string WHITESPACE = " \n\r\t\f\v"

Definition at line 122 of file oksdalgen.cxx.