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

33{
34 std::string s(in);
35 std::transform(s.begin(), s.end(), s.begin(), cvt_symbol);
36 return s;
37}
char cvt_symbol(char c)
Definition utils.cpp:26

◆ capitalize_name()

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

Definition at line 40 of file utils.cpp.

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

◆ close_cpp_namespace()

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

Definition at line 657 of file utils.cpp.

658{
659 while (level > 0)
660 {
661 std::string dx = int2dx(--level);
662 s << dx << "}\n";
663 }
664}
std::string int2dx(int level)
Definition utils.cpp:629

◆ find_cpp_method_implementation()

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

◆ gen_cpp_body()

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

Definition at line 753 of file oksdalgen.cxx.

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

◆ gen_cpp_body_prologue()

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

Definition at line 1373 of file oksdalgen.cxx.

1376{
1377 src <<
1378 "#include \"conffwk/ConfigObject.hpp\"\n"
1379 "#include \"conffwk/DalFactory.hpp\"\n"
1380 "#include \"conffwk/DalObjectPrint.hpp\"\n"
1381 "#include \"conffwk/Errors.hpp\"\n"
1382 "#include \"";
1383 if(cpp_hdr_dir != "") {
1384 src << cpp_hdr_dir << "/";
1385 }
1386 src << file_name << ".hpp\"\n\n";
1387}

◆ gen_cpp_header_epilogue()

static void gen_cpp_header_epilogue ( std::ostream & s)
static

Definition at line 1366 of file oksdalgen.cxx.

1367{
1368 s << "\n#endif\n";
1369}

◆ gen_cpp_header_prologue()

static void gen_cpp_header_prologue ( const std::string & file_name,
std::ostream & s,
const std::string & cpp_ns_name,
const std::string & cpp_hdr_dir )
static

Definition at line 1342 of file oksdalgen.cxx.

1346{
1347 s <<
1348 "// *** this file is generated by oksdalgen, do not modify it ***\n\n"
1349
1350 "#ifndef _" << alnum_name(file_name) << "_0_" << alnum_name(cpp_ns_name) << "_0_" << alnum_name(cpp_hdr_dir) << "_H_\n"
1351 "#define _" << alnum_name(file_name) << "_0_" << alnum_name(cpp_ns_name) << "_0_" << alnum_name(cpp_hdr_dir) << "_H_\n\n"
1352
1353 "#include <stdint.h> // to define 64 bits types\n"
1354 "#include <iostream>\n"
1355 "#include <sstream>\n"
1356 "#include <string>\n"
1357 "#include <map>\n"
1358 "#include <vector>\n\n"
1359
1360 "#include \"conffwk/Configuration.hpp\"\n"
1361 "#include \"conffwk/DalObject.hpp\"\n\n";
1362}

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

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

◆ gen_header()

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

Definition at line 96 of file oksdalgen.cxx.

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

100{
101 switch (oks_type)
102 {
104 return "UNKNOWN";
106 return (is_cpp ? "int8_t" : "char");
108 return (is_cpp ? "uint8_t" : "byte");
110 return (is_cpp ? "int16_t" : "short");
112 return (is_cpp ? "uint16_t" : "short");
114 return (is_cpp ? "int32_t" : "int");
116 return (is_cpp ? "uint32_t" : "int");
118 return (is_cpp ? "int64_t" : "long");
120 return (is_cpp ? "uint64_t" : "long");
122 return "float";
124 return "double";
126 return (is_cpp ? "bool" : "boolean");
127
133 return (is_cpp ? "std::string" : "String");
134
139 return "funnytype";
140 }
141
142 return "invalid";
143}

◆ has_superclass()

static 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 55 of file oksdalgen.cxx.

56{
57 if (const oks::OksClass::FList * sclasses = tested->all_super_classes())
58 {
59 for (const auto& i : *sclasses)
60 {
61 if (i == c)
62 {
63 return true;
64 }
65 }
66 }
67
68 return false;
69}
std::list< OksClass *, boost::fast_pool_allocator< OksClass * > > FList
Definition class.hpp:235

◆ int2dx()

std::string int2dx ( int level)
extern

Definition at line 629 of file utils.cpp.

630{
631 return std::string(level * 2, ' ');
632}

◆ load_schemas()

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

Definition at line 1325 of file oksdalgen.cxx.

1326{
1327 for (const auto& i : file_names)
1328 {
1329 if (oks::OksFile * fh = kernel.load_schema(i))
1330 {
1331 file_hs.insert(fh);
1332 }
1333 else
1334 {
1335 std::cerr << "ERROR: can not load schema file \"" << i << "\"\n";
1336 exit(EXIT_FAILURE);
1337 }
1338 }
1339}

◆ ltrim()

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

Definition at line 73 of file oksdalgen.cxx.

74{
75 size_t start = s.find_first_not_of(WHITESPACE);
76 return (start == std::string::npos) ? "" : s.substr(start);
77}
const std::string WHITESPACE
Definition oksdalgen.cxx:71

◆ main()

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

Definition at line 1391 of file oksdalgen.cxx.

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

636{
637 int level = 0;
638 std::string dx;
639
640 if (!value.empty())
641 {
642 Oks::Tokenizer t(value, ":");
643 std::string token;
644
645 while (!(token = t.next()).empty())
646 {
647 s << dx << "namespace " << token << " {\n";
648 level++;
649 dx += " ";
650 }
651 }
652
653 return level;
654}

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

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

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

◆ print_indented()

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

Definition at line 84 of file utils.cpp.

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

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

80{
81 size_t end = s.find_last_not_of(WHITESPACE);
82 return (end == std::string::npos) ? "" : s.substr(0, end + 1);
83}

◆ set2out()

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

Definition at line 739 of file oksdalgen.cxx.

740{
741 for (const auto& x : data)
742 {
743 if (is_first)
744 is_first = false;
745 else
746 out << ',';
747 out << '\"' << x << "()\"";
748 }
749}
FELIX Initialization std::string initerror FELIX queue timed out

◆ trim()

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

Definition at line 85 of file oksdalgen.cxx.

85 {
86 return rtrim(ltrim(s));
87}
std::string ltrim(const std::string &s)
Definition oksdalgen.cxx:73
std::string rtrim(const std::string &s)
Definition oksdalgen.cxx:79

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

89 {
90 "virtual",
91 "override",
92 "final"
93};

◆ WHITESPACE

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

Definition at line 71 of file oksdalgen.cxx.