DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
oksdalgen.cxx File Reference
#include "class_info.hpp"
#include "oks/kernel.hpp"
#include "oks/class.hpp"
#include "oks/attribute.hpp"
#include "oks/relationship.hpp"
#include "oks/method.hpp"
#include <stdlib.h>
#include <ctype.h>
#include <algorithm>
#include <string>
#include <list>
#include <set>
#include <iostream>
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

Function Documentation

◆ alnum_name()

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

Definition at line 39 of file utils.cpp.

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

◆ capitalize_name()

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

Definition at line 47 of file utils.cpp.

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

◆ close_cpp_namespace()

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

Definition at line 664 of file utils.cpp.

665{
666 while (level > 0)
667 {
668 std::string dx = int2dx(--level);
669 s << dx << "}\n";
670 }
671}
std::string int2dx(int level)
Definition utils.cpp:636

◆ 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 761 of file oksdalgen.cxx.

762{
763 cpp_s << "#include \"logging/Logging.hpp\"\n\n";
764
765 const std::string name(alnum_name(cl->get_name()));
766
767 std::set<oks::OksClass *> rclasses;
768
769 // for each relationship, include the header file
770
771 if (const std::list<oks::OksRelationship*> * rlist = cl->direct_relationships())
772 {
773 for (const auto& i : *rlist)
774 {
775 oks::OksClass * c = i->get_class_type();
776 if (has_superclass(cl, c) == false && cl != c)
777 {
778 rclasses.insert(c);
779 }
780 }
781 }
782
783 if (const std::list<oks::OksMethod*> * mlist = cl->direct_methods())
784 {
785 for (const auto& i : *mlist)
786 {
787 if (oks::OksMethodImplementation * mi = find_cpp_method_implementation(i))
788 {
789 std::string prototype(mi->get_prototype());
790 std::string::size_type idx = prototype.find('(');
791
792 if (get_add_algo_n(mi) || get_add_algo_1(mi))
793 {
794
795 if (idx != std::string::npos)
796 {
797 idx--;
798
799 // skip spaces between method name and ()
800 while (isspace(prototype[idx]) && idx > 0)
801 idx--;
802
803 // find beginning of the method name
804 while (!isspace(prototype[idx]) && idx > 0)
805 idx--;
806
807 // remove method name and arguments
808 prototype.erase(idx + 1);
809
810 // remove spaces
811 prototype.erase(std::remove_if(prototype.begin(), prototype.end(), [](unsigned char x)
812 { return std::isspace(x);}), prototype.end());
813
814 if (prototype.empty() == false)
815 {
816 idx = prototype.find('*');
817 prototype.erase(idx--);
818
819 if (idx != std::string::npos)
820 {
821 while (isalnum(prototype[idx]) && idx > 0)
822 idx--;
823
824 if(idx == 0 && get_add_algo_1(mi) && prototype.find("const") == 0)
825 prototype.erase(0, 5);
826 else
827 prototype.erase(0, idx+1);
828
829 if (oks::OksClass * c = cl->get_kernel()->find_class(prototype))
830 rclasses.insert(c);
831 }
832 }
833 }
834 }
835 }
836 }
837 }
838
839 if (!rclasses.empty())
840 {
841 cpp_s << " // include files for classes used in relationships and algorithms\n\n";
842
843 for (const auto& j : rclasses)
844 {
845 cpp_s << "#include \"" << get_include_dir(j, cl_info, cpp_hdr_dir) << ".hpp\"\n";
846 }
847
848 cpp_s << std::endl << std::endl;
849 }
850
851
852 // open namespace
853
854 int ns_level = open_cpp_namespace(cpp_s, cpp_ns_name);
855 std::string ns_dx = int2dx(ns_level);
856 std::string ns_dx2 = ns_dx + " ";
857
858 const char * dx = ns_dx.c_str(); // are used for alignment
859 const char * dx2 = ns_dx2.c_str();
860
861
862 // static objects
863
864 cpp_s << dx << "const std::string& " << name << "::s_class_name(dunedaq::conffwk::DalFactory::instance().get_known_class_name_ref(\"" << name << "\"));\n\n";
865
866 std::set<std::string> algo_n_set, algo_1_set;
867
868 if (const std::list<oks::OksMethod*> * mlist = cl->direct_methods())
869 {
870 for (const auto& i : *mlist)
871 {
872 if(oks::OksMethodImplementation * mi = find_cpp_method_implementation(i))
873 {
874 std::string prototype(mi->get_prototype());
875 std::string::size_type idx = prototype.find('(');
876
877 if (idx != std::string::npos)
878 {
879 idx--;
880
881 // skip spaces between method name and ()
882 while (isspace(prototype[idx]) && idx > 0)
883 idx--;
884
885 // remove method arguments
886 prototype.erase(idx+1);
887
888 // find beginning of the method name
889 while (!isspace(prototype[idx]) && idx > 0)
890 idx--;
891
892 if (idx > 0)
893 {
894 prototype.erase(0, idx+1);
895
896 if (get_add_algo_n(mi))
897 {
898 algo_n_set.insert(prototype);
899 }
900 else if (get_add_algo_1(mi))
901 {
902 algo_1_set.insert(prototype);
903 }
904 }
905 }
906 }
907 }
908 }
909
910
911 if ( !cl->get_is_abstract() ) {
912 cpp_s
913 << dx << " // the factory initializer\n\n"
914 << dx << "static struct __" << name << "_Registrator\n"
915 << dx << " {\n"
916 << dx << " __" << name << "_Registrator()\n"
917 << dx << " {\n"
918 << dx << " dunedaq::conffwk::DalFactory::instance().register_dal_class<" << name << ">(\"" << cl->get_name() << "\");\n"
919 << dx << " }\n"
920 << dx << " } registrator;\n\n\n";
921 }
922
923 // the constructor
924
925 cpp_s
926 << dx << " // the constructor\n\n"
927 << dx << name << "::" << name << "(conffwk::DalRegistry& db, const conffwk::ConfigObject& o) noexcept :\n"
928 << dx << " " << "dunedaq::conffwk::DalObject(db, o)";
929
930
931 // fill member initializer list, if any
932
933 std::list<std::string> initializer_list;
934
935 if(const std::list<std::string*> * slist = cl->direct_super_classes())
936 {
937 for(auto & i : *slist)
938 {
939 initializer_list.push_back(get_full_cpp_class_name(cl->get_kernel()->find_class(*i), cl_info, "") + "(db, o)");
940 }
941 }
942
943 if (const std::list<oks::OksRelationship *> *rlist = cl->direct_relationships())
944 {
945 for (std::list<oks::OksRelationship*>::const_iterator i = rlist->begin(); i != rlist->end(); ++i)
946 {
947 if ((*i)->get_high_cardinality_constraint() != oks::OksRelationship::Many)
948 {
949 initializer_list.push_back(std::string("m_") + alnum_name((*i)->get_name()) + " (nullptr)");
950 }
951 }
952 }
953
954
955 if(const std::list<oks::OksMethod*> * mlist = cl->direct_methods())
956 {
957 for (std::list<oks::OksMethod*>::const_iterator i = mlist->begin(); i != mlist->end(); ++i)
958 {
959 if (oks::OksMethodImplementation * mi = find_cpp_method_implementation(*i))
960 {
961 std::string member_initializer = get_member_initializer_list(mi);
962 member_initializer.erase(remove(member_initializer.begin(), member_initializer.end(), '\n'), member_initializer.end());
963
964 if (!member_initializer.empty())
965 {
966 initializer_list.push_back(member_initializer);
967 }
968 }
969 }
970 }
971
972 if (initializer_list.empty() == false)
973 {
974 for (auto & i : initializer_list)
975 {
976 cpp_s << ",\n" << dx << " " << i;
977 }
978
979 cpp_s << std::endl;
980 }
981
982 cpp_s << "\n"
983 << dx << "{\n"
984 << dx << " ;\n"
985 << dx << "}\n\n\n";
986
987
988 // print method
989
990 cpp_s
991 << dx << "void " << name << "::print(unsigned int indent, bool print_header, std::ostream& s) const\n"
992 << dx << "{\n"
993 << dx << " check_init();\n\n"
994 << dx << " try {\n";
995
996 if (cl->direct_attributes() || cl->direct_relationships())
997 cpp_s << dx << " const std::string str(indent+2, ' ');\n";
998
999 cpp_s
1000 << '\n'
1001 << dx << " if (print_header)\n"
1002 << dx << " p_hdr(s, indent, s_class_name";
1003
1004 if(!cpp_ns_name.empty()) {
1005 cpp_s << ", \"" << cpp_ns_name << '\"';
1006 }
1007
1008 cpp_s << ");\n";
1009
1010
1011 if (const std::list<std::string*> * slist = cl->direct_super_classes())
1012 {
1013 cpp_s << "\n\n" << dx << " // print direct super-classes\n\n";
1014
1015 for (const auto& i : *slist)
1016 cpp_s << dx << " " << get_full_cpp_class_name(cl->get_kernel()->find_class(*i), cl_info, cpp_ns_name) << "::print(indent, false, s);\n";
1017 }
1018
1019 if(const std::list<oks::OksAttribute*> * alist = cl->direct_attributes()) {
1020 cpp_s << "\n\n" << dx << " // print direct attributes\n\n";
1021
1022 for(const auto& i : *alist) {
1023 const std::string aname(alnum_name(i->get_name()));
1024 std::string abase = (i->get_format() == oks::OksAttribute::Hex) ? "<dunedaq::conffwk::hex>" : (i->get_format() == oks::OksAttribute::Oct) ? "<dunedaq::conffwk::oct>" : "";
1025
1026 if (i->get_is_multi_values())
1027 cpp_s << dx << " dunedaq::conffwk::p_mv_attr" << abase << "(s, str, s_" << aname << ", m_" << aname << ");\n";
1028 else
1029 cpp_s << dx << " dunedaq::conffwk::p_sv_attr" << abase << "(s, str, s_" << aname << ", m_" << aname << ");\n";
1030 }
1031 }
1032
1033 if (const std::list<oks::OksRelationship*> * rlist = cl->direct_relationships())
1034 {
1035 cpp_s << "\n\n" << dx << " // print direct relationships\n\n";
1036
1037 for (const auto& i : *rlist)
1038 {
1039 const std::string rname(alnum_name(i->get_name()));
1040
1041 if (i->get_high_cardinality_constraint() == oks::OksRelationship::Many)
1042 {
1043 if (i->get_is_composite())
1044 cpp_s << dx << " dunedaq::conffwk::p_mv_rel(s, str, indent, s_" << rname << ", m_" << rname << ");\n";
1045 else
1046 cpp_s << dx << " dunedaq::conffwk::p_mv_rel(s, str, s_" << rname << ", m_" << rname << ");\n";
1047 }
1048 else
1049 {
1050 if (i->get_is_composite())
1051 cpp_s << dx <<" dunedaq::conffwk::p_sv_rel(s, str, indent, s_" << rname << ", m_" << rname << ");\n";
1052 else
1053 cpp_s << dx <<" dunedaq::conffwk::p_sv_rel(s, str, s_" << rname << ", m_" << rname << ");\n";
1054 }
1055 }
1056 }
1057
1058 cpp_s << dx << " }\n"
1059 << dx << " catch (dunedaq::conffwk::Exception & ex) {\n"
1060 << dx << " dunedaq::conffwk::DalObject::p_error(s, ex);\n"
1061 << dx << " }\n"
1062 << dx << "}\n\n\n";
1063
1064
1065 // init method
1066
1067 {
1068 const char * ic_value = (
1069 ( cl->direct_relationships() && cl->direct_relationships()->size() ) ||
1070 ( cl->direct_super_classes() && cl->direct_super_classes()->size() )
1071 ? "init_children"
1072 : "/* init_children */"
1073 );
1074
1075 cpp_s
1076 << dx << "void " << name << "::init(bool " << ic_value << ")\n"
1077 << dx << "{\n";
1078 }
1079
1080 if (cl->direct_super_classes() == nullptr)
1081 {
1082 cpp_s
1083 << dx << " p_was_read = true;\n"
1084 << dx << " increment_read();\n";
1085 }
1086
1087 // generate initialization for super classes
1088
1089 if (const std::list<std::string*> * slist = cl->direct_super_classes())
1090 {
1091 for (const auto& i : *slist)
1092 {
1093 cpp_s << dx << " " << alnum_name(*i) << "::init(init_children);\n";
1094 }
1095 if (!slist->empty())
1096 cpp_s << std::endl;
1097 }
1098
1099 cpp_s << dx << " TLOG_DEBUG(5) << \"read object \" << this << \" (class \" << s_class_name << \')\';\n";
1100
1101 // put try / catch only if there are attributes or relationships to be initialized
1102 const std::list<oks::OksAttribute*> *alist = cl->direct_attributes();
1103 const std::list<oks::OksRelationship*> *rlist = cl->direct_relationships();
1104
1105 if ((alist && !alist->empty()) || (rlist && !rlist->empty()))
1106 {
1107 cpp_s << std::endl << dx << " try {\n";
1108
1109
1110 // generate initialization for attributes
1111 if (alist)
1112 {
1113 for (const auto& i : *alist)
1114 {
1115 const std::string cpp_name = alnum_name(i->get_name());
1116 cpp_s << dx << " p_obj.get(s_" << cpp_name << ", m_" << cpp_name << ");\n";
1117 }
1118 }
1119
1120
1121 // generate initialization for relationships
1122 if (rlist)
1123 {
1124 for (const auto& i : *rlist)
1125 {
1126 const std::string& rname = i->get_name();
1127 std::string cpp_name = alnum_name(rname);
1128 std::string rcname = get_full_cpp_class_name(i->get_class_type(), cl_info, cpp_ns_name);
1129 if (i->get_high_cardinality_constraint() == oks::OksRelationship::Many)
1130 {
1131 cpp_s << dx << " p_registry._ref<" << rcname << ">(p_obj, s_" << cpp_name << ", " << "m_" << cpp_name << ", init_children);\n";
1132 }
1133 else
1134 {
1135 cpp_s << dx << " m_" << cpp_name << " = p_registry._ref<" << rcname << ">(p_obj, s_" << cpp_name << ", init_children);\n";
1136 }
1137 }
1138 }
1139
1140 cpp_s
1141 << dx << " }\n"
1142 << dx << " catch (dunedaq::conffwk::Exception & ex) {\n"
1143 << dx << " throw_init_ex(ex);\n"
1144 << dx << " }\n";
1145
1146 }
1147
1148 cpp_s << dx << "}\n\n";
1149
1150
1151 // destructor
1152
1153 cpp_s
1154 << dx << name << "::~" << name << "() noexcept\n"
1155 << dx << "{\n"
1156 << dx << "}\n\n";
1157
1158 cpp_s
1159 << dx << "std::vector<const dunedaq::conffwk::DalObject *> " << name << "::get(const std::string& name, bool upcast_unregistered) const\n"
1160 << dx << "{\n"
1161 << dx << " std::vector<const dunedaq::conffwk::DalObject *> vec;\n\n"
1162 << dx << " if (!get(name, vec, upcast_unregistered, true))\n"
1163 << dx << " throw_get_ex(name, s_class_name, this);\n\n"
1164 << dx << " return vec;\n"
1165 << dx << "}\n\n";
1166
1167 cpp_s
1168 << dx << "bool " << name << "::get(const std::string& name, std::vector<const dunedaq::conffwk::DalObject *>& vec, bool upcast_unregistered, bool first_call) const\n"
1169 << dx << "{\n"
1170 << dx << " if (first_call)\n"
1171 << dx << " {\n"
1172 << dx << " std::lock_guard scoped_lock(m_mutex);\n\n"
1173 << dx << " check();\n"
1174 << dx << " check_init();\n\n"
1175 << dx << " if (get_rel_objects(name, upcast_unregistered, vec))\n"
1176 << dx << " return true;\n"
1177 << dx << " }\n\n";
1178
1179
1180 for (const auto &prototype : algo_n_set)
1181 cpp_s
1182 << dx << " if (name == \"" << prototype << "()\")\n"
1183 << dx << " {\n"
1184 << dx << " p_registry.downcast_dal_objects(" << prototype << "(), upcast_unregistered, vec);\n"
1185 << dx << " return true;\n"
1186 << dx << " }\n\n";
1187
1188 for (const auto &prototype : algo_1_set)
1189 cpp_s
1190 << dx << " if (name == \"" << prototype << "()\")\n"
1191 << dx << " {\n"
1192 << dx << " p_registry.downcast_dal_object(" << prototype << "(), upcast_unregistered, vec);\n"
1193 << dx << " return true;\n"
1194 << dx << " }\n\n";
1195
1196
1197 if (const std::list<std::string*> * slist = cl->direct_super_classes())
1198 {
1199 for (const auto& i : *slist)
1200 {
1201 cpp_s << dx << " if (" << alnum_name(*i) << "::get(name, vec, upcast_unregistered, false)) return true;\n";
1202 }
1203
1204 cpp_s << "\n";
1205 }
1206
1207 cpp_s
1208 << dx << " if (first_call)\n"
1209 << dx << " return get_algo_objects(name, vec);\n\n"
1210 << dx << " return false;\n"
1211 << dx << "}\n\n";
1212
1213
1214 // generate relationship set methods
1215
1216 if (const std::list<oks::OksRelationship*> *rlist = cl->direct_relationships())
1217 {
1218 for (const auto& i : *rlist)
1219 {
1220 const std::string rname(alnum_name(i->get_name()));
1221 std::string full_cpp_class_name = get_full_cpp_class_name(i->get_class_type(), cl_info, cpp_ns_name);
1222
1223 cpp_s << dx << "void " << name << "::set_" << rname << "(const ";
1224
1225 if (i->get_high_cardinality_constraint() == oks::OksRelationship::Many)
1226 {
1227 cpp_s
1228 << "std::vector<const " << full_cpp_class_name << "*>& value)\n"
1229 << dx << "{\n"
1230 << dx << " _set_objects(s_" << rname << ", value);\n"
1231 << dx << "}\n\n";
1232 }
1233 else
1234 {
1235 cpp_s
1236 << full_cpp_class_name << " * value)\n"
1237 << dx << "{\n"
1238 << dx << " _set_object(s_" << rname << ", value);\n"
1239 << dx << "}\n\n";
1240 }
1241 }
1242 }
1243
1244
1245 // generate methods for c++
1246
1247 if (const std::list<oks::OksMethod*> * mlist = cl->direct_methods())
1248 {
1249 bool comment_is_printed = false;
1250 for (const auto& i : *mlist)
1251 {
1252 oks::OksMethodImplementation * mi = find_cpp_method_implementation(i);
1253
1254 if (mi && !get_method_implementation_body(mi).empty())
1255 {
1256 if (comment_is_printed == false)
1257 {
1258 cpp_s << dx << " // user-defined algorithms\n\n";
1259 comment_is_printed = true;
1260 }
1261
1262 // generate description
1263
1264 print_description(cpp_s, i->get_description(), dx2);
1265
1266 // generate prototype
1267
1268 std::string prototype(mi->get_prototype());
1269 std::string::size_type idx = prototype.find('(');
1270
1271 if (idx != std::string::npos)
1272 {
1273 idx--;
1274
1275 // skip spaces between method name and ()
1276
1277 while (isspace(prototype[idx]) && idx > 0)
1278 idx--;
1279
1280 // find beginning of the method name
1281
1282 while ((isalnum(prototype[idx]) || prototype[idx] == '_') && idx > 0)
1283 idx--;
1284
1285 prototype[idx] = '\n';
1286 std::string s(dx);
1287 s += alnum_name(name);
1288 s += "::";
1289 prototype.insert(idx + 1, s);
1290 }
1291
1292 // Second pass
1293 std::string::size_type idx_open_bracket = prototype.find('(');
1294 std::string::size_type idx_space = prototype.rfind(' ', idx_open_bracket);
1295 std::string::size_type idx_close_bracket = prototype.rfind(')');
1296
1297 auto prototype_attrs = prototype.substr(0,idx_space+1);
1298 auto prototype_head = prototype.substr(idx_space+1,idx_close_bracket-idx_space);
1299 auto prototype_specs = prototype.substr(idx_close_bracket+1);
1300
1301 for ( const auto& spec : cpp_method_virtual_specifiers ) {
1302 idx = prototype_attrs.find(spec);
1303 if ( idx != std::string::npos) {
1304 prototype_attrs.erase(idx,spec.size());
1305 }
1306 prototype_attrs = trim(prototype_attrs);
1307
1308 idx = prototype_specs.find(spec);
1309 if ( idx != std::string::npos) {
1310 prototype_specs.erase(idx,spec.size());
1311 }
1312 prototype_specs = trim(prototype_specs);
1313 }
1314
1315 prototype = prototype_attrs + ' ' + prototype_head + ' ' + prototype_specs;
1316
1317 cpp_s
1318 << dx << prototype << std::endl
1319 << dx << "{\n"
1320 << get_method_implementation_body(mi) << std::endl
1321 << dx << "}\n\n";
1322 }
1323 }
1324 }
1325
1326
1327 // close namespace
1328
1329 close_cpp_namespace(cpp_s, ns_level);
1330}
void print_description()
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)
Definition oksdalgen.cxx:93
std::string get_member_initializer_list(oks::OksMethodImplementation *mi)
static bool has_superclass(const oks::OksClass *tested, const oks::OksClass *c)
Definition oksdalgen.cxx:63
void close_cpp_namespace(std::ostream &s, int level)
Definition utils.cpp:664
bool get_add_algo_1(oks::OksMethodImplementation *mi)
const std::vector< std::string > cpp_method_virtual_specifiers
Definition oksdalgen.cxx:97
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:642
std::string int2dx(int level)
Definition utils.cpp:636
bool get_add_algo_n(oks::OksMethodImplementation *mi)
std::string alnum_name(const std::string &in)
Definition utils.cpp:39
std::string get_method_implementation_body(oks::OksMethodImplementation *mi)

◆ 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 1381 of file oksdalgen.cxx.

1384{
1385 src <<
1386 "#include \"conffwk/ConfigObject.hpp\"\n"
1387 "#include \"conffwk/DalFactory.hpp\"\n"
1388 "#include \"conffwk/DalObjectPrint.hpp\"\n"
1389 "#include \"conffwk/Errors.hpp\"\n"
1390 "#include \"";
1391 if(cpp_hdr_dir != "") {
1392 src << cpp_hdr_dir << "/";
1393 }
1394 src << file_name << ".hpp\"\n\n";
1395}

◆ gen_cpp_header_epilogue()

void gen_cpp_header_epilogue ( std::ostream & s)
static

Definition at line 1374 of file oksdalgen.cxx.

1375{
1376 s << "\n#endif\n";
1377}

◆ 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 1350 of file oksdalgen.cxx.

1354{
1355 s <<
1356 "// *** this file is generated by oksdalgen, do not modify it ***\n\n"
1357
1358 "#ifndef _" << alnum_name(file_name) << "_0_" << alnum_name(cpp_ns_name) << "_0_" << alnum_name(cpp_hdr_dir) << "_H_\n"
1359 "#define _" << alnum_name(file_name) << "_0_" << alnum_name(cpp_ns_name) << "_0_" << alnum_name(cpp_hdr_dir) << "_H_\n\n"
1360
1361 "#include <stdint.h> // to define 64 bits types\n"
1362 "#include <iostream>\n"
1363 "#include <sstream>\n"
1364 "#include <string>\n"
1365 "#include <map>\n"
1366 "#include <vector>\n\n"
1367
1368 "#include \"conffwk/Configuration.hpp\"\n"
1369 "#include \"conffwk/DalObject.hpp\"\n\n";
1370}

◆ 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 169 of file utils.cpp.

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

◆ 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 104 of file oksdalgen.cxx.

109{
110 const std::string name(alnum_name(cl->get_name()));
111
112
113 // get includes for super classes if necessary
114
115 if (const std::list<std::string*> * super_list = cl->direct_super_classes())
116 {
117 cpp_file << " // include files for classes used in inheritance hierarchy\n\n";
118
119 for (const auto& i : *super_list)
120 {
121 oks::OksClass * c = cl->get_kernel()->find_class(*i);
122 cpp_file << "#include \"" << get_include_dir(c, cl_info, cpp_hdr_dir) << ".hpp\"\n";
123 }
124 }
125
126 cpp_file << std::endl;
127
128
129 // generate forward declarations if necessary
130 {
131 // create set of classes to avoid multiple forward declarations of the same class
132 std::set<oks::OksClass*> rclasses;
133
134 // check direct relationships (c++)
135 if (cl->direct_relationships() && !cl->direct_relationships()->empty())
136 for (const auto &i : *cl->direct_relationships())
137 rclasses.insert(i->get_class_type());
138
139 // check methods
140 if (const std::list<oks::OksMethod*> *mlist = cl->direct_methods())
141 {
142 for (const auto &i : *mlist)
143 {
144 if (oks::OksMethodImplementation *mi = find_cpp_method_implementation(i))
145 {
146 const std::string mp(mi->get_prototype());
147 for (const auto &j : cl->get_kernel()->classes())
148 {
149 const std::string s(j.second->get_name());
150 std::string::size_type idx = mp.find(s);
151 if (idx != std::string::npos && (idx == 0 || !isalnum(mp[idx - 1])) && !isalnum(mp[idx + s.size()]))
152 rclasses.insert(j.second);
153 }
154 }
155 }
156 }
157
158 NameSpaceInfo ns_info;
159
160 for (const auto &c : rclasses)
161 {
162 // check if the class' header is not already included
163 if (has_superclass(cl, c) || cl == c)
164 continue;
165
166 ClassInfo::Map::const_iterator idx = cl_info.find(c);
167 ns_info.add((idx != cl_info.end() ? (*idx).second.get_namespace() : cpp_ns_name), alnum_name(c->get_name()));
168 }
169
170 if (!ns_info.empty())
171 {
172 cpp_file << " // forward declaration for classes used in relationships and algorithms\n\n";
173 ns_info.print(cpp_file, 0);
174 cpp_file << "\n\n";
175 }
176 }
177
178 // generate methods prologues if necessary
179
180 if (const std::list<oks::OksMethod*> *mlist = cl->direct_methods())
181 for (const auto &i : *mlist)
182 if (oks::OksMethodImplementation *mi = find_cpp_method_implementation(i))
183 if (!get_method_header_prologue(mi).empty())
184 {
185 cpp_file << " // prologue of method " << cl->get_name() << "::" << i->get_name() << "()\n";
186 cpp_file << get_method_header_prologue(mi) << std::endl;
187 }
188
189
190 // open namespace
191
192 int ns_level = open_cpp_namespace(cpp_file, cpp_ns_name);
193 std::string ns_dx = int2dx(ns_level);
194 std::string ns_dx2 = ns_dx + " ";
195
196 const char * dx = ns_dx.c_str(); // are used for alignment
197 const char * dx2 = ns_dx2.c_str();
198
199
200 // generate description
201
202 {
203 std::string txt("Declares methods to get and put values of attributes / relationships, to print and to destroy object.\n");
204
205 txt +=
206 "<p>\n"
207 "The methods can throw several exceptions:\n"
208 "<ul>\n"
209 " <li><code>conffwk.NotFoundException</code> - in case of wrong attribute or relationship name (e.g. in case of database schema modification)\n"
210 " <li><code>conffwk.SystemException</code> - in case of system problems (communication or implementation database failure, schema modification, object destruction, etc.)\n"
211 "</ul>\n"
212 "<p>\n"
213 "In addition the methods modifying database (set value, destroy object) can throw <code>conffwk.NotAllowedException</code> "
214 "exception in case, if there are no write access rights or database is already locked by other process.\n";
215
216 if (!cl->get_description().empty())
217 {
218 txt += "\n<p>\n";
219 txt += cl->get_description();
220 txt += "\n";
221 }
222
223 txt += "@author oksdalgen\n";
224
225 cpp_file << std::endl;
226 print_description(cpp_file, cl->get_description(), dx);
227 }
228
229 // generate class declaration itself
230
231 cpp_file << dx << "class " << name << " : ";
232
233 // generate inheritance list
234
235 if (const std::list<std::string*> * super_list = cl->direct_super_classes())
236 {
237 for (std::list<std::string*>::const_iterator i = super_list->begin(); i != super_list->end();)
238 {
239 const oks::OksClass * c = cl->get_kernel()->find_class(**i);
240 cpp_file << "public " << get_full_cpp_class_name(c, cl_info, cpp_ns_name);
241 if (++i != super_list->end())
242 cpp_file << ", ";
243 }
244 }
245 else
246 {
247 cpp_file << "public virtual dunedaq::conffwk::DalObject";
248 }
249
250 cpp_file << " {\n\n";
251
252 // generate standard methods
253
254 cpp_file
255 << dx << " friend class conffwk::Configuration;\n"
256 << dx << " friend class conffwk::DalObject;\n"
257 << dx << " friend class conffwk::DalFactory;\n"
258 << dx << " friend class conffwk::DalRegistry;\n\n"
259 << dx << " protected:\n\n"
260 << dx << " " << name << "(conffwk::DalRegistry& db, const conffwk::ConfigObject& obj) noexcept;\n"
261 << dx << " virtual ~" << name << "() noexcept;\n"
262 << dx << " virtual void init(bool init_children);\n\n"
263 << dx << " public:\n\n"
264 << dx << " /** The name of the configuration class. */\n\n"
265 << dx << " static const std::string& s_class_name;\n\n\n"
266 << dx << " /**\n"
267 << dx << " * \\brief Print details of the " << name << " object.\n"
268 << dx << " *\n"
269 << dx << " * Parameters are:\n"
270 << dx << " * \\param offset number of spaces to shift object right (useful to print nested objects)\n"
271 << dx << " * \\param print_header if false, do not print object header (to print attributes of base classes)\n"
272 << dx << " * \\param s output stream\n"
273 << dx << " */\n\n"
274 << dx << " virtual void print(unsigned int offset, bool print_header, std::ostream& s) const;\n\n\n"
275 << dx << " /**\n"
276 << dx << " * \\brief Get values of relationships and results of some algorithms as a vector of dunedaq::conffwk::DalObject pointers.\n"
277 << dx << " *\n"
278 << dx << " * Parameters are:\n"
279 << dx << " * \\param name name of the relationship or algorithm\n"
280 << dx << " * \\return value of relationship or result of algorithm\n"
281 << dx << " * \\throw std::exception if there is no relationship or algorithm with such name in this and base classes\n"
282 << dx << " */\n\n"
283 << dx << " virtual std::vector<const dunedaq::conffwk::DalObject *> get(const std::string& name, bool upcast_unregistered = true) const;\n\n\n"
284 << dx << " protected:\n\n"
285 << dx << " bool get(const std::string& name, std::vector<const dunedaq::conffwk::DalObject *>& vec, bool upcast_unregistered, bool first_call) const;\n\n\n";
286
287
288 // generate class attributes and relationships in accordance with
289 // database schema
290
291 if (cl->direct_attributes() || cl->direct_relationships() || cl->direct_methods())
292 {
293 cpp_file << dx << " private:\n\n";
294
295 // generate attributes:
296 // - for single attributes this is a normal member variable.
297 // - for multiple values this is a std::vector<T>.
298
299 if (const std::list<oks::OksAttribute*> * alist = cl->direct_attributes())
300 {
301 for (const auto& i : *alist)
302 {
303 const std::string aname(alnum_name(i->get_name()));
304 std::string cpp_type = get_type(i->get_data_type(), true);
305
306 if (i->get_is_multi_values())
307 cpp_file << dx << " std::vector<" << cpp_type << "> m_" << aname << ";\n";
308 else
309 cpp_file << dx << " " << cpp_type << " m_" << aname << ";\n";
310 }
311 }
312
313
314 // generate relationships:
315 // - for single values this is just a pointer.
316 // - for multiple values this is a vector of pointers.
317
318 if (const std::list<oks::OksRelationship*> *rlist = cl->direct_relationships())
319 {
320 for (const auto& i : *rlist)
321 {
322 const std::string rname(alnum_name(i->get_name()));
323 const std::string full_class_name(get_full_cpp_class_name(i->get_class_type(), cl_info, cpp_ns_name));
324 if (i->get_high_cardinality_constraint() == oks::OksRelationship::Many)
325 cpp_file << dx << " std::vector<const " << full_class_name << "*> m_" << rname << ";\n";
326 else
327 cpp_file << dx << " const " << full_class_name << "* m_" << rname << ";\n";
328 }
329 }
330
331
332 // generate methods extension if any
333
334 if (const std::list<oks::OksMethod*> * mlist = cl->direct_methods())
335 {
336 for (const auto& i : *mlist)
337 {
338 if (oks::OksMethodImplementation * mi = find_cpp_method_implementation(i))
339 {
340 std::string method_extension = get_private_section(mi);
341 if (!method_extension.empty())
342 {
343 cpp_file << "\n" << dx << " // extension of method " << cl->get_name() << "::" << i->get_name() << "()\n";
344 print_indented(cpp_file, method_extension, dx2);
345 }
346 }
347 }
348 }
349
350
351 cpp_file << std::endl << std::endl << dx << " public:\n\n";
352
353
354 // generate attribute accessors:
355 // 1. for each attribute generate static std::string with it's name
356 // 2a. for single values this is just:
357 // - attribute_type attribute_name() const { return m_attribute; }
358 // 2b. for multiple values this is:
359 // - const std::vector<attribute_type>& attribute_name() const { return m_attribute; }
360
361 if (const std::list<oks::OksAttribute*> *alist = cl->direct_attributes())
362 {
363
364 cpp_file << dx << " // attribute names\n\n";
365
366 for (const auto& i : *alist)
367 {
368 const std::string& aname(i->get_name());
369 cpp_file << dx << " inline static const std::string s_" << alnum_name(aname) << " = \"" << aname << "\";\n";
370 }
371
372 cpp_file << "\n";
373
374 for (const auto& i : *alist)
375 {
376 const std::string& cpp_aname(alnum_name(i->get_name()));
377 cpp_file << dx << " static const std::string& __get_" << cpp_aname << "_str() noexcept { return s_" << cpp_aname << "; }\n";
378 }
379
380 cpp_file << std::endl << std::endl;
381
382 for (const auto& i : *alist)
383 {
384 const std::string aname(alnum_name(i->get_name()));
385
386 // generate enum values
387
388 if (i->get_data_type() == oks::OksData::enum_type && !i->get_range().empty())
389 {
390 std::string description("Valid enumeration values to compare with value returned by get_");
391 description += aname;
392 description += "() and to pass value to set_";
393 description += aname;
394 description += "() methods.";
395
396 print_description(cpp_file, description, dx2);
397
398 description += "\nUse toString() method to compare and to pass the values. Do not use name() method.";
399
400 cpp_file << dx << " struct " << capitalize_name(aname) << " {\n";
401
402 oks::Oks::Tokenizer t(i->get_range(), ",");
403 std::string token;
404 while (!(token = t.next()).empty())
405 {
406 cpp_file << dx << " inline static const std::string " << capitalize_name(alnum_name(token)) << " = \"" << token << "\";\n";
407 }
408
409 cpp_file << dx << " };\n\n";
410 }
411
412 // generate get method description
413
414 {
415
416 std::string description("Get \"");
417 description += i->get_name();
418 description += "\" attribute value.\n\n";
419 description += i->get_description();
420
421 std::string description2("\\brief ");
422 description2 += description;
423 description2 += "\n\\return the attribute value\n";
424 description2 += "\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
425
426 print_description(cpp_file, description2, dx2);
427 }
428
429 // generate method body
430
431 cpp_file << dx << " ";
432
433 std::string cpp_type = get_type(i->get_data_type(), true);
434
435 if (i->get_is_multi_values())
436 {
437 cpp_file << "const std::vector<" << cpp_type << ">&";
438 }
439 else
440 {
441 if (cpp_type == "std::string")
442 cpp_file << "const std::string&";
443 else
444 cpp_file << cpp_type;
445 }
446
447 cpp_file << '\n'
448 << dx << " get_" << aname << "() const\n"
449 << dx << " {\n"
450 << dx << " std::lock_guard scoped_lock(m_mutex);\n"
451 << dx << " check();\n"
452 << dx << " check_init();\n"
453 << dx << " return m_" << aname << ";\n"
454 << dx << " }\n\n";
455
456 // generate set method description
457
458 {
459 std::string description("Set \"");
460 description += i->get_name();
461 description += "\" attribute value.\n\n";
462 description += i->get_description();
463
464 std::string description2("\\brief ");
465 description2 += description;
466 description2 += "\n\\param value new attribute value\n";
467 description2 += "\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
468
469 print_description(cpp_file, description2, dx2);
470 }
471
472 // generate set method
473
474 cpp_file << dx << " void\n" << dx << " set_" << aname << '(';
475
476 if (i->get_is_multi_values())
477 {
478 cpp_file << "const std::vector<" << cpp_type << ">&";
479 }
480 else
481 {
482 if (cpp_type == "std::string")
483 {
484 cpp_file << "const std::string&";
485 }
486 else
487 {
488 cpp_file << cpp_type;
489 }
490 }
491
492 cpp_file << " value)\n"
493 << dx << " {\n"
494 << dx << " std::lock_guard scoped_lock(m_mutex);\n"
495 << dx << " check();\n"
496 << dx << " clear();\n"
497 << dx << " p_obj.";
498
499 if (i->get_data_type() == oks::OksData::string_type && i->get_is_multi_values() == false)
500 {
501 cpp_file << "set_by_ref";
502 }
503 else if (i->get_data_type() == oks::OksData::enum_type)
504 {
505 cpp_file << "set_enum";
506 }
507 else if (i->get_data_type() == oks::OksData::class_type)
508 {
509 cpp_file << "set_class";
510 }
511 else if (i->get_data_type() == oks::OksData::date_type)
512 {
513 cpp_file << "set_date";
514 }
515 else if (i->get_data_type() == oks::OksData::time_type)
516 {
517 cpp_file << "set_time";
518 }
519 else
520 {
521 cpp_file << "set_by_val";
522 }
523
524 cpp_file << "(s_" << aname << ", value);\n"
525 << dx << " }\n\n\n";
526 }
527 }
528
529
530 // generate relationship accessors.
531 // 1. for each relationship generate static std::string with it's name
532 // 2a. for single values this is just:
533 // - const relation_type * relation() const { return m_relation; }
534 // 2b. for multiple values this is:
535 // - const std::vector<const relation_type*>& relation() const { return m_relation; }
536
537 if (const std::list<oks::OksRelationship*> *rlist = cl->direct_relationships())
538 {
539
540 cpp_file << dx << " // relationship names\n\n";
541
542 for (const auto& i : *rlist)
543 {
544 const std::string& rname(i->get_name());
545 cpp_file << dx << " inline static const std::string s_" << alnum_name(rname) << " = \"" << rname << "\";\n";
546 }
547
548 cpp_file << "\n";
549
550 for (const auto& i : *rlist)
551 {
552 const std::string& cpp_rname(alnum_name(i->get_name()));
553 cpp_file << dx << " static const std::string& __get_" << cpp_rname << "_str() noexcept { return s_" << cpp_rname << "; }\n";
554 }
555
556 cpp_file << std::endl << std::endl;
557
558 for (const auto& i : *rlist)
559 {
560
561 // generate description
562
563 {
564 std::string description("Get \"");
565 description += i->get_name();
566 description += "\" relationship value.\n\n";
567 description += i->get_description();
568
569 std::string description2("\\brief ");
570 description2 += description;
571 description2 += "\n\\return the relationship value\n";
572 description2 += "\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
573
574 print_description(cpp_file, description2, dx2);
575 }
576
577 // generate method body
578
579 cpp_file << dx << " const ";
580
581 const std::string rname(alnum_name(i->get_name()));
582 std::string full_cpp_class_name = get_full_cpp_class_name(i->get_class_type(), cl_info, cpp_ns_name);
583
584 if (i->get_high_cardinality_constraint() == oks::OksRelationship::Many)
585 {
586 cpp_file << "std::vector<const " << full_cpp_class_name << "*>&";
587 }
588 else
589 {
590 cpp_file << full_cpp_class_name << " *";
591 }
592
593 cpp_file << "\n"
594 << dx << " get_" << rname << "() const\n"
595 << dx << " {\n"
596 << dx << " std::lock_guard scoped_lock(m_mutex);\n"
597 << dx << " check();\n"
598 << dx << " check_init();\n";
599
600 if (i->get_low_cardinality_constraint() == oks::OksRelationship::One)
601 {
602 if (i->get_high_cardinality_constraint() == oks::OksRelationship::One)
603 {
604 cpp_file
605 << dx << " if (!m_" << rname << ")\n"
606 << dx << " {\n"
607 << dx << " std::ostringstream text;\n"
608 << dx << " text << \"relationship \\\"\" << s_" << rname << " << \"\\\" of object \" << this << \" is not set\";\n"
609 << dx << " throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());\n"
610 << dx << " }\n";
611 }
612 else
613 {
614 cpp_file
615 << dx << " if (m_" << rname << ".empty())\n"
616 << dx << " {\n"
617 << dx << " std::ostringstream text;\n"
618 << dx << " text << \"relationship \\\"\" << s_" << rname << " << \"\\\" of object \" << this << \" is empty\";\n"
619 << dx << " throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());\n"
620 << dx << " }\n";
621 }
622 }
623
624 cpp_file
625 << dx << " return m_" << rname << ";\n"
626 << dx << " }\n\n\n";
627
628 // generate set method
629
630 {
631 std::string description("Set \"");
632 description += i->get_name();
633 description += "\" relationship value.\n\n";
634 description += i->get_description();
635
636 std::string description2("\\brief ");
637 description2 += description;
638 description2 += "\n\\param value new relationship value\n";
639 description2 += "\\throw dunedaq::conffwk::Generic, dunedaq::conffwk::DeletedObject\n";
640
641 print_description(cpp_file, description2, dx2);
642 }
643
644 cpp_file << dx << " void\n" << dx << " set_" << rname << "(const ";
645
646 if (i->get_high_cardinality_constraint() == oks::OksRelationship::Many)
647 {
648 cpp_file << "std::vector<const " << full_cpp_class_name << "*>&";
649 }
650 else
651 {
652 cpp_file << full_cpp_class_name << " *";
653 }
654
655 cpp_file << " value);\n\n";
656 }
657 }
658 }
659
660
661 // generate methods
662
663 if (const std::list<oks::OksMethod*> *mlist = cl->direct_methods())
664 {
665 bool cpp_comment_is_printed = false;
666
667 for (const auto& i : *mlist)
668 {
669
670 // C++ algorithms
671
672 if (oks::OksMethodImplementation * mi = find_cpp_method_implementation(i))
673 {
674 if (cpp_comment_is_printed == false)
675 {
676 cpp_file << std::endl << dx << " public:\n\n" << dx << " // user-defined algorithms\n\n";
677 cpp_comment_is_printed = true;
678 }
679 else
680 {
681 cpp_file << "\n\n";
682 }
683
684 // generate description
685
686 print_description(cpp_file, i->get_description(), dx2);
687
688 // generate prototype
689
690 cpp_file << dx << " " << mi->get_prototype() << ";\n";
691
692
693 // generate public section extension
694
695 std::string public_method_extension = get_public_section(mi);
696 if (!public_method_extension.empty())
697 {
698 cpp_file << "\n" << " // extension of method " << cl->get_name() << "::" << i->get_name() << "()\n";
699 print_indented(cpp_file, public_method_extension, " ");
700 }
701 }
702
703 }
704 }
705
706
707 // class finished
708
709 cpp_file << dx << "};\n\n";
710
711
712 // generate ostream operators and typedef for iterator
713
714 cpp_file
715 << dx << " // out stream operator\n\n"
716 << dx << "inline std::ostream& operator<<(std::ostream& s, const " << name << "& obj)\n"
717 << dx << " {\n"
718 << dx << " return obj.print_object(s);\n"
719 << dx << " }\n\n"
720 << dx << "typedef std::vector<const " << name << "*>::const_iterator " << name << "Iterator;\n\n";
721
722
723 // close namespace
724
725 close_cpp_namespace(cpp_file, ns_level);
726
727
728 // generate methods epilogues if necessary
729
730 if (const std::list<oks::OksMethod*> * mlist = cl->direct_methods())
731 {
732 for (const auto & i : *mlist)
733 {
734 oks::OksMethodImplementation * mi = find_cpp_method_implementation(i);
735 if (mi && !get_method_header_epilogue(mi).empty())
736 {
737 cpp_file << " // epilogue of method " << cl->get_name() << "::" << i->get_name() << "()\n";
738 cpp_file << get_method_header_epilogue(mi) << std::endl;
739 }
740 }
741 }
742
743}
String tokenizer.
Definition defs.hpp:63
std::string get_public_section(oks::OksMethodImplementation *mi)
std::string get_type(oks::OksData::Type oks_type, bool is_cpp)
Definition utils.cpp:106
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:91
std::string capitalize_name(const std::string &in)
Definition utils.cpp:47
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 106 of file utils.cpp.

107{
108 switch (oks_type)
109 {
111 return "UNKNOWN";
113 return (is_cpp ? "int8_t" : "char");
115 return (is_cpp ? "uint8_t" : "byte");
117 return (is_cpp ? "int16_t" : "short");
119 return (is_cpp ? "uint16_t" : "short");
121 return (is_cpp ? "int32_t" : "int");
123 return (is_cpp ? "uint32_t" : "int");
125 return (is_cpp ? "int64_t" : "long");
127 return (is_cpp ? "uint64_t" : "long");
129 return "float";
131 return "double";
133 return (is_cpp ? "bool" : "boolean");
134
140 return (is_cpp ? "std::string" : "String");
141
146 return "funnytype";
147 }
148
149 return "invalid";
150}

◆ 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 63 of file oksdalgen.cxx.

64{
65 if (const oks::OksClass::FList * sclasses = tested->all_super_classes())
66 {
67 for (const auto& i : *sclasses)
68 {
69 if (i == c)
70 {
71 return true;
72 }
73 }
74 }
75
76 return false;
77}
std::list< OksClass *, boost::fast_pool_allocator< OksClass * > > FList
Definition class.hpp:240

◆ int2dx()

std::string int2dx ( int level)
extern

Definition at line 636 of file utils.cpp.

637{
638 return std::string(level * 2, ' ');
639}

◆ 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 1333 of file oksdalgen.cxx.

1334{
1335 for (const auto& i : file_names)
1336 {
1337 if (oks::OksFile * fh = kernel.load_schema(i))
1338 {
1339 file_hs.insert(fh);
1340 }
1341 else
1342 {
1343 std::cerr << "ERROR: can not load schema file \"" << i << "\"\n";
1344 exit(EXIT_FAILURE);
1345 }
1346 }
1347}

◆ ltrim()

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

Definition at line 81 of file oksdalgen.cxx.

82{
83 size_t start = s.find_first_not_of(WHITESPACE);
84 return (start == std::string::npos) ? "" : s.substr(start);
85}
const std::string WHITESPACE
Definition oksdalgen.cxx:79

◆ main()

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

Definition at line 1399 of file oksdalgen.cxx.

1400{
1401 std::list<std::string> class_names;
1402 std::list<std::string> file_names;
1403 std::list<std::string> include_dirs;
1404 std::list<std::string> user_classes;
1405
1406 std::string cpp_dir_name = "."; // directory for c++ implementation files
1407 std::string cpp_hdr_dir = ""; // directory for c++ header files
1408 std::string cpp_ns_name = ""; // c++ namespace
1409 std::string info_file_name = "oksdalgen.info"; // name of info file
1410 bool verbose = false;
1411
1412 parse_arguments(argc, argv, class_names, file_names, include_dirs, user_classes, cpp_dir_name, cpp_ns_name, cpp_hdr_dir, info_file_name, verbose);
1413
1414 // init OKS
1415
1416 std::set<oks::OksFile *, std::less<oks::OksFile *> > file_hs;
1417
1418 oks::OksKernel kernel(false, false, false, false);
1419
1420 try
1421 {
1422 load_schemas(kernel, file_names, file_hs);
1423
1424 // if no user defined classes, generate all
1425
1426 if (class_names.size() == 0)
1427 {
1428 if (verbose)
1429 {
1430 std::cout << "No explicit classes were provided,\n"
1431 "search for classes which belong to the given schema files:\n";
1432 }
1433
1434 const oks::OksClass::Map& class_list = kernel.classes();
1435
1436 if (!class_list.empty())
1437 {
1438 for (const auto& i : class_list)
1439 {
1440 if (verbose)
1441 {
1442 std::cout << " * check for class \"" << i.first << "\" ";
1443 }
1444
1445 if (file_hs.find(i.second->get_file()) != file_hs.end())
1446 {
1447 class_names.push_back(i.second->get_name());
1448 if (verbose)
1449 {
1450 std::cout << "OK\n";
1451 }
1452 }
1453 else
1454 {
1455 if (verbose)
1456 {
1457 std::cout << "skip\n";
1458 }
1459 }
1460 }
1461 }
1462 else
1463 {
1464 std::cerr << "No classes in schema file and no user classes specified\n";
1465 exit(EXIT_FAILURE);
1466 }
1467 }
1468
1469 // calculate set of classes which should be mentioned by the generator;
1470 // note, some of classes can come from other DALs
1471
1472 typedef std::set<const oks::OksClass *, std::less<const oks::OksClass *> > Set;
1473 Set generated_classes;
1474 ClassInfo::Map cl_info;
1475
1476 unsigned int error_num = 0;
1477
1478 // build set of classes which are generated
1479
1480 for (const auto& i : class_names)
1481 {
1482 if (oks::OksClass *cl = kernel.find_class(i))
1483 {
1484 generated_classes.insert(cl);
1485 }
1486 else
1487 {
1488 std::cerr << "ERROR: can not find class " << i << std::endl;
1489 error_num++;
1490 }
1491 }
1492
1493 // build set of classes which are external to generated
1494
1495 for (const auto& i : generated_classes)
1496 {
1497 if (const std::list<oks::OksRelationship *> * rels = i->direct_relationships())
1498 {
1499 for (const auto& j : *rels)
1500 {
1501 const oks::OksClass * rc = j->get_class_type();
1502
1503 if (rc == 0)
1504 {
1505 std::cerr << "\nERROR: the class \"" << j->get_type() << "\" (it is used by the relationship \"" << j->get_name() << "\" of class \"" << i->get_name() << "\") is not defined by the schema.\n";
1506 error_num++;
1507 }
1508 else if (generated_classes.find(rc) == generated_classes.end())
1509 {
1510 if (process_external_class(cl_info, rc, include_dirs, user_classes, verbose) == false)
1511 {
1512 std::cerr << "\nERROR: the class \"" << j->get_type() << "\" is used by the relationship \"" << j->get_name() << "\" of class \"" << i->get_name() << "\".\n"
1513 " The class is not in the list of generated classes, "
1514 "it was not found among already generated headers "
1515 "(search list is defined by the -I | --include-dirs parameter) and "
1516 "it is not defined by user via -D | --user-defined-classes.\n";
1517 error_num++;
1518 }
1519 }
1520 }
1521 }
1522
1523 if (const std::list<std::string *> * sclasses = i->direct_super_classes())
1524 {
1525 for (const auto& j : *sclasses)
1526 {
1527 const oks::OksClass * rc = kernel.find_class(*j);
1528
1529 if (rc == 0)
1530 {
1531 std::cerr << "\nERROR: the class \"" << *j << "\" (it is direct superclass of class \"" << i->get_name() << "\") is not defined by the schema.\n";
1532 error_num++;
1533 }
1534 else if (generated_classes.find(rc) == generated_classes.end())
1535 {
1536 if (process_external_class(cl_info, rc, include_dirs, user_classes, verbose) == false)
1537 {
1538 std::cerr << "\nERROR: the class \"" << rc->get_name() << "\" is direct superclass of class \"" << i->get_name() << "\".\n"
1539 " The class is not in the list of generated classes, "
1540 "it was not found among already generated headers "
1541 "(search list is defined by the -I | --include-dirs parameter) and "
1542 "it is not defined by user via -D | --user-defined-classes.\n";
1543 error_num++;
1544 }
1545 }
1546 }
1547 }
1548 }
1549
1550 if (error_num != 0)
1551 {
1552 std::cerr << "\n*** " << error_num << (error_num == 1 ? " error was" : " errors were") << " found.\n\n";
1553 return (EXIT_FAILURE);
1554 }
1555
1556 for (const auto& cl : generated_classes)
1557 {
1558 std::string name(alnum_name(cl->get_name()));
1559
1560 std::string cpp_hdr_name = cpp_dir_name + "/" + name + ".hpp";
1561 std::string cpp_src_name = cpp_dir_name + "/" + name + ".cpp";
1562
1563 std::ofstream cpp_hdr_file(cpp_hdr_name.c_str());
1564 std::ofstream cpp_src_file(cpp_src_name.c_str());
1565
1566 if (!cpp_hdr_file)
1567 {
1568 std::cerr << "ERROR: can not create file \"" << cpp_hdr_name << "\"\n";
1569 return (EXIT_FAILURE);
1570 }
1571
1572 if (!cpp_src_file)
1573 {
1574 std::cerr << "ERROR: can not create file \"" << cpp_src_name << "\"\n";
1575 return (EXIT_FAILURE);
1576 }
1577
1578 gen_cpp_header_prologue(name, cpp_hdr_file, cpp_ns_name, cpp_hdr_dir);
1579 gen_cpp_body_prologue(name, cpp_src_file, cpp_hdr_dir);
1580
1581 gen_header(cl, cpp_hdr_file, cpp_ns_name, cpp_hdr_dir, cl_info);
1582 gen_cpp_body(cl, cpp_src_file, cpp_ns_name, cpp_hdr_dir, cl_info);
1583
1584 gen_cpp_header_epilogue(cpp_hdr_file);
1585 }
1586
1587 // generate dump applications
1588
1589 {
1590 struct ConfigurationImplementations
1591 {
1592 const char * name;
1593 const char * header;
1594 const char * class_name;
1595 const char * header_prologue;
1596 const char * main_function_prologue;
1597 } confs[] =
1598 {
1599 { 0, "conffwk/Configuration.hpp", 0, "", "" } };
1600
1601 for (unsigned int i = 0; i < sizeof(confs) / sizeof(ConfigurationImplementations); ++i)
1602 {
1603 std::string dump_name = cpp_dir_name + "/dump";
1604 if (!cpp_ns_name.empty())
1605 {
1606 dump_name += '_';
1607 dump_name += alnum_name(cpp_ns_name);
1608 }
1609 if (confs[i].name)
1610 {
1611 dump_name += '_';
1612 dump_name += confs[i].name;
1613 }
1614 dump_name += ".cpp";
1615
1616 std::ofstream dmp(dump_name.c_str());
1617
1618 dmp.exceptions(std::ostream::failbit | std::ostream::badbit);
1619
1620 if (dmp)
1621 {
1622 try
1623 {
1624 gen_dump_application(dmp, class_names, cpp_ns_name, cpp_hdr_dir, confs[i].header, confs[i].class_name, confs[i].header_prologue, confs[i].main_function_prologue);
1625 }
1626 catch (std::exception& ex)
1627 {
1628 std::cerr << "ERROR: can not create file \"" << dump_name << "\": " << ex.what() << std::endl;
1629 }
1630 }
1631 else
1632 {
1633 std::cerr << "ERROR: can not create file \"" << dump_name << "\"\n";
1634 return (EXIT_FAILURE);
1635 }
1636 }
1637 }
1638
1639 // generate info file
1640
1641 {
1642 std::ofstream info(info_file_name.c_str());
1643
1644 if (info)
1645 {
1646 write_info_file(info, cpp_ns_name, cpp_hdr_dir, generated_classes);
1647 }
1648 else
1649 {
1650 std::cerr << "ERROR: can not create file \"" << info_file_name << "\"\n";
1651 return (EXIT_FAILURE);
1652 }
1653 }
1654
1655 }
1656 catch (oks::exception & ex)
1657 {
1658 std::cerr << "Caught oks exception:\n" << ex << std::endl;
1659 return (EXIT_FAILURE);
1660 }
1661 catch (std::exception & e)
1662 {
1663 std::cerr << "Caught standard C++ exception: " << e.what() << std::endl;
1664 return (EXIT_FAILURE);
1665 }
1666 catch (...)
1667 {
1668 std::cerr << "Caught unknown exception" << std::endl;
1669 return (EXIT_FAILURE);
1670 }
1671
1672 return (EXIT_SUCCESS);
1673}
std::map< const char *, OksClass *, SortStr > Map
Definition class.hpp:238
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:169
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 642 of file utils.cpp.

643{
644 int level = 0;
645 std::string dx;
646
647 if (!value.empty())
648 {
649 Oks::Tokenizer t(value, ":");
650 std::string token;
651
652 while (!(token = t.next()).empty())
653 {
654 s << dx << "namespace " << token << " {\n";
655 level++;
656 dx += " ";
657 }
658 }
659
660 return level;
661}

◆ 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 55 of file parse_cmdl.cpp.

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

73{
74 if (!text.empty())
75 {
76 s << dx << " /**\n";
77
78 Oks::Tokenizer t(text, "\n");
79 std::string token;
80
81 while (!(token = t.next()).empty())
82 {
83 s << dx << " * " << token << std::endl;
84 }
85
86 s << dx << " */\n\n";
87 }
88}

◆ print_indented()

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

Definition at line 91 of file utils.cpp.

92{
93 if (!text.empty())
94 {
95 Oks::Tokenizer t(text, "\n");
96 std::string token;
97
98 while (!(token = t.next()).empty())
99 {
100 s << dx << token << std::endl;
101 }
102 }
103}

◆ 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 87 of file oksdalgen.cxx.

88{
89 size_t end = s.find_last_not_of(WHITESPACE);
90 return (end == std::string::npos) ? "" : s.substr(0, end + 1);
91}

◆ set2out()

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

Definition at line 747 of file oksdalgen.cxx.

748{
749 for (const auto& x : data)
750 {
751 if (is_first)
752 is_first = false;
753 else
754 out << ',';
755 out << '\"' << x << "()\"";
756 }
757}
FELIX Initialization std::string initerror FELIX queue timed out

◆ trim()

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

Definition at line 93 of file oksdalgen.cxx.

93 {
94 return rtrim(ltrim(s));
95}
std::string ltrim(const std::string &s)
Definition oksdalgen.cxx:81
std::string rtrim(const std::string &s)
Definition oksdalgen.cxx:87

◆ 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
Initial value:
= {
"virtual",
"override",
"final"
}

Definition at line 97 of file oksdalgen.cxx.

97 {
98 "virtual",
99 "override",
100 "final"
101};

◆ WHITESPACE

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

Definition at line 79 of file oksdalgen.cxx.