11#include <initializer_list>
28 return (isalnum(c) ? c :
'_');
35 std::transform(s.begin(), s.end(), s.begin(),
cvt_symbol);
48 s[0] = toupper(in[0]);
52 s.insert(s.begin(),
'_');
74 while (!(token = t.
next()).empty())
76 s << dx <<
" * " << token << std::endl;
91 while (!(token = t.
next()).empty())
93 s << dx << token << std::endl;
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");
126 return (is_cpp ?
"bool" :
"boolean");
133 return (is_cpp ?
"std::string" :
"String");
163 std::list<std::string>& class_names,
164 const std::string& cpp_ns_name,
165 const std::string& cpp_hdr_dir,
166 const char * conf_header,
167 const char * conf_name,
168 const char * headres_prologue,
169 const char * main_function_prologue
173 " // *** this file is generated by oksdalgen ***\n"
175 "#include \"conffwk/ConfigObject.hpp\"\n"
176 "#include \"" << conf_header <<
"\"\n\n";
179 for (
const auto& i : class_names)
181 std::string hname(cpp_hdr_dir);
185 s <<
"#include \"" << hname <<
".hpp\"\n";
188 if (headres_prologue && *headres_prologue)
190 s <<
"\n // db implementation-specific headrers prologue\n\n" << headres_prologue <<
"\n";
196 "static void usage(const char * s)\n"
198 " std::cout << s << \" -d db-name -c class-name [-q query | -i object-id] [-t]\\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"
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"
216 "static void no_param(const char * s)\n"
218 " std::cerr << \"ERROR: the required argument for option \\\'\" << s << \"\\\' is missing\\n\\n\";\n"
219 " exit (EXIT_FAILURE);\n"
222 "int main(int argc, char *argv[])\n"
225 if (main_function_prologue && *main_function_prologue)
227 s <<
" // db implementation-specific main function prologue\n\n " << main_function_prologue <<
"\n\n";
231 " // parse parameters\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"
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"
245 " if(!strcmp(cp, \"-t\") || !strcmp(cp, \"--init-children\")) {\n"
246 " init_children = true;\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"
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"
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"
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"
261 " std::cerr << \"ERROR: bad parameter \" << cp << std::endl;\n"
263 " return (EXIT_FAILURE);\n"
267 " if(db_name == nullptr) {\n"
268 " std::cerr << \"ERROR: no database name provided\\n\";\n"
269 " return (EXIT_FAILURE);\n"
272 " if(class_name.empty()) {\n"
273 " std::cerr << \"ERROR: no class name provided\\n\";\n"
274 " return (EXIT_FAILURE);\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"
283 "std::cout << std::boolalpha;\n"
289 " " << conf_name <<
" impl_conf;\n"
292 " dunedaq::conffwk::Configuration conf(db_name, &impl_conf);\n";
298 " dunedaq::conffwk::Configuration conf(db_name);\n";
303 " if(!conf.loaded()) {\n"
304 " std::cerr << \"Can not load database: \" << db_name << std::endl;\n"
305 " return (EXIT_FAILURE);\n"
308 " std::vector< dunedaq::conffwk::ConfigObject > objects;\n"
311 " dunedaq::conffwk::ConfigObject obj;\n"
313 " conf.get(class_name, object_id, obj, 1);\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"
319 " objects.push_back(obj);\n"
323 " conf.get(class_name, objects, query, 1);\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"
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"
337 " std::set< dunedaq::conffwk::ConfigObject *, SortByUId > sorted_objects;\n"
339 " for(auto& i : objects)\n"
340 " sorted_objects.insert(&i);\n"
342 " for(auto& i : sorted_objects) {\n";
344 for (std::list<std::string>::iterator i = class_names.begin(); i != class_names.end(); ++i)
346 const char * op = (i == class_names.begin() ?
"if" :
"else if");
347 std::string cname(cpp_ns_name);
355 " " << op <<
"(class_name == \"" << *i <<
"\") {\n"
356 " std::cout << *conf.get<" << cname <<
">(*i, init_children) << std::endl;\n"
362 " std::cerr << \"ERROR: do not know how to dump object of \" << class_name << \" class\\n\";\n"
363 " return (EXIT_FAILURE);\n"
367 " catch (dunedaq::conffwk::Exception & ex) {\n"
368 " std::cerr << \"Caught \" << ex << std::endl;\n"
369 " return (EXIT_FAILURE);\n"
379 const std::string& cpp_namespace,
380 const std::string& cpp_header_dir,
382 const std::set<
const OksClass *, std::less<const OksClass *> >& classes)
384 std::time_t
now = std::time(
nullptr);
386 s <<
"// the file is generated " << std::put_time(std::localtime(&
now),
"%F %T %Z") <<
" by oksdalgen utility\n"
387 "// *** do not modify the file ***\n"
388 "c++-namespace=" << cpp_namespace <<
"\n"
389 "c++-header-dir-prefix=" << cpp_header_dir <<
"\n"
393 for (
const auto& i : classes)
394 s <<
" " << i->get_name() << std::endl;
407 ClassInfo::Map::const_iterator idx = cl_info.find(c);
409 if (idx != cl_info.end())
410 s = (*idx).second.get_namespace();
428 ClassInfo::Map::const_iterator idx = cl_info.find(c);
430 if (idx != cl_info.end())
432 const std::string include_prefix = (*idx).second.get_include_prefix();
433 if (!include_prefix.empty())
439 else if (!cpp_hdr_dir.empty())
472 const std::list<std::string>& include_dirs,
473 const std::list<std::string>& user_classes,
476 if (cl_info.find(c) != cl_info.end())
481 for (
const auto &s : user_classes)
483 std::string::size_type idx = s.find(
"::");
484 std::string::size_type idx2 = s.find(
"@", idx + 2);
486 std::string cpp_ns_name;
487 std::string class_name;
488 std::string cpp_dir_name;
490 if (idx == std::string::npos)
492 class_name = s.substr(0, idx2);
496 cpp_ns_name = s.substr(0, idx);
497 class_name = s.substr(idx + 2, idx2 - idx - 2);
500 if (idx2 != std::string::npos)
501 cpp_dir_name = s.substr(idx2 + 1);
503 if (class_name == c->get_name())
505 cl_info[c] =
ClassInfo(cpp_ns_name, cpp_dir_name);
508 std::cout <<
" * class " << c->get_name() <<
" is defined by user in ";
510 if (cpp_ns_name.empty())
511 std::cout <<
"global namespace";
513 std::cout <<
"namespace \"" << cpp_ns_name <<
'\"';
515 if (!cpp_dir_name.empty())
516 std::cout <<
" with \"" << cpp_dir_name <<
"\" include prefix";
518 std::cout << std::endl;
528 std::cout <<
"Looking for oksdalgen info files ...\n";
530 bool found_class_declaration =
false;
532 for (
const auto& i : include_dirs)
534 std::string file_name(i);
535 file_name +=
"/oksdalgen.info";
537 std::ifstream f(file_name.c_str());
542 std::cout <<
" *** found file \"" << file_name <<
"\" ***\n";
544 std::string cpp_ns_name;
545 std::string cpp_dir_name;
547 bool is_class =
false;
550 while (std::getline(f, s))
552 if (s.find(
"//") != std::string::npos)
555 std::cout <<
" - skip comment \"" << s <<
"\"\n";
557 else if (s.find(
"classes:") != std::string::npos)
560 std::cout <<
" - found classes keyword\n";
565 const char s1[] =
"c++-namespace=";
566 std::string::size_type idx = s.find(s1);
567 if (idx != std::string::npos)
569 cpp_ns_name = s.substr(
sizeof(s1) - 1);
571 std::cout <<
" - c++ namespace = \"" << cpp_ns_name <<
"\"\n";
575 const char s2[] =
"c++-header-dir-prefix=";
576 std::string::size_type idx = s.find(s2);
577 if (idx != std::string::npos)
579 cpp_dir_name = s.substr(
sizeof(s2) - 1);
581 std::cout <<
" - c++ header dir prefix name = \"" << cpp_dir_name <<
"\"\n";
595 std::string cname = s.substr(2);
596 OksClass * cl = c->get_kernel()->find_class(cname);
597 if (cl && cl_info.find(cl) == cl_info.end())
599 cl_info[cl] =
ClassInfo(cpp_ns_name, cpp_dir_name);
601 std::cout <<
" * class " << cl->
get_name() <<
" is defined by " << file_name <<
" in namespace \"" << cpp_ns_name <<
"\" with include prefix \"" << cpp_dir_name <<
"\"\n";
603 found_class_declaration =
true;
607 std::cout <<
" - skip class \"" << cname <<
"\" declaration\n";
612 std::cerr <<
"Failed to parse line \"" << s <<
"\"\n";
621 std::cout <<
" *** file \"" << file_name <<
"\" does not exist ***\n";
625 return found_class_declaration;
631 return std::string(level * 2,
' ');
645 while (!(token = t.
next()).empty())
647 s << dx <<
"namespace " << token <<
" {\n";
661 std::string dx =
int2dx(--level);
684 std::string::size_type begix_idx = mi->
get_body().find(begin, 0);
685 if (begix_idx == std::string::npos)
687 std::string::size_type end_idx = mi->
get_body().find(end, begix_idx + begin.size());
688 if (end_idx == std::string::npos)
690 return mi->
get_body().substr(begix_idx + begin.size(), end_idx - begix_idx - begin.size());
738 std::string::size_type begix_idx = s.find(begin, 0);
739 if (begix_idx == std::string::npos)
742 std::string::size_type end_idx = (end.empty() ? (begix_idx + begin.size()) : s.find(end, begix_idx + begin.size()));
743 if (end_idx == std::string::npos)
746 end_idx += end.size();
747 while (s[end_idx] ==
'\n')
750 s.erase(begix_idx, end_idx - begix_idx);
765 if(std::all_of(s.begin(),s.end(),isspace))
774 for (
const auto& name : names)
777 if (mi->get_prototype().empty() ==
false)
const std::string & get_name() const noexcept
OKS method implementation class.
const std::string & get_body() const noexcept
OksMethodImplementation * find_implementation(const std::string &language) const
Find method implementation.
std::map< const oks::OksClass *, ClassInfo, SortByName > Map
const std::string end_private_section("END_PRIVATE_SECTION")
std::string get_type(OksData::Type oks_type, bool is_cpp)
static std::string get_method_header_x_logue(OksMethodImplementation *mi, const std::string &begin, const std::string &end)
std::string get_method_header_prologue(OksMethodImplementation *mi)
const std::string end_header_epilogue("END_HEADER_EPILOGUE")
bool get_add_algo_1(OksMethodImplementation *mi)
static void remove_string_section(std::string &s, const std::string &begin, const std::string &end)
const std::string begin_header_epilogue("BEGIN_HEADER_EPILOGUE")
std::string get_public_section(OksMethodImplementation *mi)
void close_cpp_namespace(std::ostream &s, int level)
std::string get_private_section(OksMethodImplementation *mi)
static OksMethodImplementation * find_method_implementation(const OksMethod *method, std::initializer_list< std::string > names)
const std::string begin_member_initializer_list("BEGIN_MEMBER_INITIALIZER_LIST")
const std::string has_add_algo_n("ADD_ALGO_N")
std::string get_full_cpp_class_name(const OksClass *c, const ClassInfo::Map &cl_info, const std::string &cpp_ns_name)
const std::string end_member_initializer_list("END_MEMBER_INITIALIZER_LIST")
const std::string has_add_algo_1("ADD_ALGO_1")
OksMethodImplementation * find_cpp_method_implementation(const OksMethod *method)
const std::string begin_header_prologue("BEGIN_HEADER_PROLOGUE")
int open_cpp_namespace(std::ostream &s, const std::string &value)
std::string get_member_initializer_list(OksMethodImplementation *mi)
const std::string begin_public_section("BEGIN_PUBLIC_SECTION")
const std::string begin_private_section("BEGIN_PRIVATE_SECTION")
std::string get_method_implementation_body(OksMethodImplementation *mi)
void print_indented(std::ostream &s, const std::string &text, const char *dx)
bool process_external_class(ClassInfo::Map &cl_info, const OksClass *c, const std::list< std::string > &include_dirs, const std::list< std::string > &user_classes, bool verbose)
std::string int2dx(int level)
const std::string end_public_section("END_PUBLIC_SECTION")
const std::string end_header_prologue("END_HEADER_PROLOGUE")
std::string get_include_dir(const OksClass *c, const ClassInfo::Map &cl_info, const std::string &cpp_hdr_dir)
std::string alnum_name(const std::string &in)
bool get_add_algo_n(OksMethodImplementation *mi)
std::string get_method_header_epilogue(OksMethodImplementation *mi)
std::string capitalize_name(const std::string &in)
void write_info_file(std::ostream &s, const std::string &cpp_namespace, const std::string &cpp_header_dir, const std::set< const OksClass *, std::less< const OksClass * > > &classes)
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)