17#include <initializer_list>
33 return (isalnum(c) ? c :
'_');
40 std::transform(s.begin(), s.end(), s.begin(),
cvt_symbol);
51 s[0] = toupper(in[0]);
53 s.insert(s.begin(),
'_');
73 while (!(token = t.
next()).empty()) {
74 s << dx <<
" * " << token << std::endl;
88 while (!(token = t.
next()).empty()) {
89 s << dx << token << std::endl;
101 return (is_cpp ?
"int8_t" :
"char");
103 return (is_cpp ?
"uint8_t" :
"byte");
105 return (is_cpp ?
"int16_t" :
"short");
107 return (is_cpp ?
"uint16_t" :
"short");
109 return (is_cpp ?
"int32_t" :
"int");
111 return (is_cpp ?
"uint32_t" :
"int");
113 return (is_cpp ?
"int64_t" :
"long");
115 return (is_cpp ?
"uint64_t" :
"long");
121 return (is_cpp ?
"bool" :
"boolean");
128 return (is_cpp ?
"std::string" :
"String");
158 std::list<std::string>& class_names,
159 const std::string& cpp_ns_name,
160 const std::string& cpp_hdr_dir,
161 const char* conf_header,
162 const char* conf_name,
163 const char* headres_prologue,
164 const char* main_function_prologue)
166 s <<
" // *** this file is generated by oksdalgen ***\n"
168 "#include \"conffwk/ConfigObject.hpp\"\n"
170 << conf_header <<
"\"\n\n";
173 for (
const auto& i : class_names) {
174 std::string hname(cpp_hdr_dir);
178 s <<
"#include \"" << hname <<
".hpp\"\n";
181 if (headres_prologue && *headres_prologue) {
182 s <<
"\n // db implementation-specific headrers prologue\n\n" << headres_prologue <<
"\n";
187 "static void usage(const char * s)\n"
189 " std::cout << s << \" -d db-name -c class-name [-q query | -i object-id] [-t]\\n\"\n"
191 " \"Options/Arguments:\\n\"\n"
192 " \" -d | --data db-name mandatory name of the database\\n\"\n"
193 " \" -c | --class-name class-name mandatory name of class\\n\"\n"
194 " \" -q | --query query optional query to select class objects\\n\"\n"
195 " \" -i | --object-id object-id optional identity to select one object\\n\"\n"
196 " \" -t | --init-children all referenced objects are initialized (is used\\n\"\n"
197 " \" for debug purposes and performance measurements)\\n\"\n"
198 " \" -h | --help print this message\\n\"\n"
200 " \"Description:\\n\"\n"
201 " \" The program prints out object(s) of given class.\\n\"\n"
202 " \" If no query or object id is provided, all objects of the class are printed.\\n\"\n"
203 " \" It is automatically generated by oksdalgen utility.\\n\"\n"
207 "static void no_param(const char * s)\n"
209 " std::cerr << \"ERROR: the required argument for option \\\'\" << s << \"\\\' is missing\\n\\n\";\n"
210 " exit (EXIT_FAILURE);\n"
213 "int main(int argc, char *argv[])\n"
216 if (main_function_prologue && *main_function_prologue) {
217 s <<
" // db implementation-specific main function prologue\n\n " << main_function_prologue <<
"\n\n";
220 s <<
" // parse parameters\n"
222 " const char * db_name = nullptr;\n"
223 " const char * object_id = nullptr;\n"
224 " const char * query = \"\";\n"
225 " std::string class_name;\n"
226 " bool init_children = false;\n"
228 " for(int i = 1; i < argc; i++) {\n"
229 " const char * cp = argv[i];\n"
230 " if(!strcmp(cp, \"-h\") || !strcmp(cp, \"--help\")) {\n"
234 " if(!strcmp(cp, \"-t\") || !strcmp(cp, \"--init-children\")) {\n"
235 " init_children = true;\n"
237 " else if(!strcmp(cp, \"-d\") || !strcmp(cp, \"--data\")) {\n"
238 " if(++i == argc || argv[i][0] == '-') { no_param(cp); } else { db_name = argv[i]; }\n"
240 " else if(!strcmp(cp, \"-c\") || !strcmp(cp, \"--class-name\")) {\n"
241 " if(++i == argc || argv[i][0] == '-') { no_param(cp); } else { class_name = argv[i]; }\n"
243 " else if(!strcmp(cp, \"-i\") || !strcmp(cp, \"--object-id\")) {\n"
244 " if(++i == argc || argv[i][0] == '-') { no_param(cp); } else { object_id = argv[i]; }\n"
246 " else if(!strcmp(cp, \"-q\") || !strcmp(cp, \"--query\")) {\n"
247 " if(++i == argc || argv[i][0] == '-') { no_param(cp); } else { query = argv[i]; }\n"
250 " std::cerr << \"ERROR: bad parameter \" << cp << std::endl;\n"
252 " return (EXIT_FAILURE);\n"
256 " if(db_name == nullptr) {\n"
257 " std::cerr << \"ERROR: no database name provided\\n\";\n"
258 " return (EXIT_FAILURE);\n"
261 " if(class_name.empty()) {\n"
262 " std::cerr << \"ERROR: no class name provided\\n\";\n"
263 " return (EXIT_FAILURE);\n"
266 " if(*query != 0 && object_id != nullptr) {\n"
267 " std::cerr << \"ERROR: only one parameter -i or -q can be provided\\n\";\n"
268 " return (EXIT_FAILURE);\n"
272 "std::cout << std::boolalpha;\n"
276 s <<
" " << conf_name
280 " dunedaq::conffwk::Configuration conf(db_name, &impl_conf);\n";
283 " dunedaq::conffwk::Configuration conf(db_name);\n";
287 " if(!conf.loaded()) {\n"
288 " std::cerr << \"Can not load database: \" << db_name << std::endl;\n"
289 " return (EXIT_FAILURE);\n"
292 " std::vector< dunedaq::conffwk::ConfigObject > objects;\n"
295 " dunedaq::conffwk::ConfigObject obj;\n"
297 " conf.get(class_name, object_id, obj, 1);\n"
299 " catch (dunedaq::conffwk::NotFound & ex) {\n"
300 " std::cerr << \"Can not get object \\'\" << object_id << \"\\' of class \\'\" << class_name << "
301 "\"\\':\\n\" << ex << std::endl;\n"
302 " return (EXIT_FAILURE);\n"
304 " objects.push_back(obj);\n"
308 " conf.get(class_name, objects, query, 1);\n"
310 " catch (dunedaq::conffwk::NotFound & ex) {\n"
311 " std::cerr << \"Can not get objects of class \\'\" << class_name << \"\\':\\n\" << ex << std::endl;\n"
312 " return (EXIT_FAILURE);\n"
316 " struct SortByUId {\n"
317 " bool operator() (const dunedaq::conffwk::ConfigObject * o1, const dunedaq::conffwk::ConfigObject * o2) "
319 " return (o1->UID() < o2->UID());\n"
323 " std::set< dunedaq::conffwk::ConfigObject *, SortByUId > sorted_objects;\n"
325 " for(auto& i : objects)\n"
326 " sorted_objects.insert(&i);\n"
328 " for(auto& i : sorted_objects) {\n";
330 for (std::list<std::string>::iterator i = class_names.begin(); i != class_names.end(); ++i) {
331 const char* op = (i == class_names.begin() ?
"if" :
"else if");
332 std::string cname(cpp_ns_name);
339 s <<
" " << op <<
"(class_name == \"" << *i
341 " std::cout << *conf.get<"
343 <<
">(*i, init_children) << std::endl;\n"
348 " std::cerr << \"ERROR: do not know how to dump object of \" << class_name << \" class\\n\";\n"
349 " return (EXIT_FAILURE);\n"
353 " catch (dunedaq::conffwk::Exception & ex) {\n"
354 " std::cerr << \"Caught \" << ex << std::endl;\n"
355 " return (EXIT_FAILURE);\n"
364 const std::string& cpp_namespace,
365 const std::string& cpp_header_dir,
367 const std::set<
const OksClass*, std::less<const OksClass*>>& classes)
369 std::time_t now = std::time(
nullptr);
371 s <<
"// the file is generated " << std::put_time(std::localtime(&now),
"%F %T %Z")
372 <<
" by oksdalgen utility\n"
373 "// *** do not modify the file ***\n"
377 "c++-header-dir-prefix="
383 for (
const auto& i : classes)
384 s <<
" " << i->get_name() << std::endl;
396 ClassInfo::Map::const_iterator idx = cl_info.find(c);
398 if (idx != cl_info.end())
399 s = (*idx).second.get_namespace();
416 ClassInfo::Map::const_iterator idx = cl_info.find(c);
418 if (idx != cl_info.end()) {
419 const std::string include_prefix = (*idx).second.get_include_prefix();
420 if (!include_prefix.empty()) {
424 }
else if (!cpp_hdr_dir.empty()) {
454 const std::list<std::string>& include_dirs,
455 const std::list<std::string>& user_classes,
458 if (cl_info.find(c) != cl_info.end())
463 for (
const auto& s : user_classes) {
464 std::string::size_type idx = s.find(
"::");
465 std::string::size_type idx2 = s.find(
"@", idx + 2);
467 std::string cpp_ns_name;
468 std::string class_name;
469 std::string cpp_dir_name;
471 if (idx == std::string::npos) {
472 class_name = s.substr(0, idx2);
474 cpp_ns_name = s.substr(0, idx);
475 class_name = s.substr(idx + 2, idx2 - idx - 2);
478 if (idx2 != std::string::npos)
479 cpp_dir_name = s.substr(idx2 + 1);
481 if (class_name == c->get_name()) {
482 cl_info[c] =
ClassInfo(cpp_ns_name, cpp_dir_name);
484 std::cout <<
" * class " << c->get_name() <<
" is defined by user in ";
486 if (cpp_ns_name.empty())
487 std::cout <<
"global namespace";
489 std::cout <<
"namespace \"" << cpp_ns_name <<
'\"';
491 if (!cpp_dir_name.empty())
492 std::cout <<
" with \"" << cpp_dir_name <<
"\" include prefix";
494 std::cout << std::endl;
504 std::cout <<
"Looking for oksdalgen info files ...\n";
506 bool found_class_declaration =
false;
508 for (
const auto& i : include_dirs) {
509 std::string file_name(i);
510 file_name +=
"/oksdalgen.info";
512 std::ifstream f(file_name.c_str());
516 std::cout <<
" *** found file \"" << file_name <<
"\" ***\n";
518 std::string cpp_ns_name;
519 std::string cpp_dir_name;
521 bool is_class =
false;
524 while (std::getline(f, s)) {
525 if (s.find(
"//") != std::string::npos) {
527 std::cout <<
" - skip comment \"" << s <<
"\"\n";
528 }
else if (s.find(
"classes:") != std::string::npos) {
530 std::cout <<
" - found classes keyword\n";
533 const char s1[] =
"c++-namespace=";
534 std::string::size_type idx = s.find(s1);
535 if (idx != std::string::npos) {
536 cpp_ns_name = s.substr(
sizeof(s1) - 1);
538 std::cout <<
" - c++ namespace = \"" << cpp_ns_name <<
"\"\n";
540 const char s2[] =
"c++-header-dir-prefix=";
541 std::string::size_type idx = s.find(s2);
542 if (idx != std::string::npos) {
543 cpp_dir_name = s.substr(
sizeof(s2) - 1);
545 std::cout <<
" - c++ header dir prefix name = \"" << cpp_dir_name <<
"\"\n";
558 std::string cname = s.substr(2);
559 OksClass* cl = c->get_kernel()->find_class(cname);
560 if (cl && cl_info.find(cl) == cl_info.end()) {
561 cl_info[cl] =
ClassInfo(cpp_ns_name, cpp_dir_name);
563 std::cout <<
" * class " << cl->
get_name() <<
" is defined by " << file_name <<
" in namespace \""
564 << cpp_ns_name <<
"\" with include prefix \"" << cpp_dir_name <<
"\"\n";
566 found_class_declaration =
true;
567 }
else if (verbose) {
568 std::cout <<
" - skip class \"" << cname <<
"\" declaration\n";
571 std::cerr <<
"Failed to parse line \"" << s <<
"\"\n";
577 }
else if (verbose) {
578 std::cout <<
" *** file \"" << file_name <<
"\" does not exist ***\n";
582 return found_class_declaration;
588 return std::string(level * 2,
' ');
597 if (!value.empty()) {
601 while (!(token = t.
next()).empty()) {
602 s << dx <<
"namespace " << token <<
" {\n";
615 std::string dx =
int2dx(--level);
636 std::string::size_type begix_idx = mi->
get_body().find(begin, 0);
637 if (begix_idx == std::string::npos)
639 std::string::size_type end_idx = mi->
get_body().find(end, begix_idx + begin.size());
640 if (end_idx == std::string::npos)
642 return mi->
get_body().substr(begix_idx + begin.size(), end_idx - begix_idx - begin.size());
690 std::string::size_type begix_idx = s.find(begin, 0);
691 if (begix_idx == std::string::npos)
694 std::string::size_type end_idx = (end.empty() ? (begix_idx + begin.size()) : s.find(end, begix_idx + begin.size()));
695 if (end_idx == std::string::npos)
698 end_idx += end.size();
699 while (s[end_idx] ==
'\n')
702 s.erase(begix_idx, end_idx - begix_idx);
717 if (std::all_of(s.begin(), s.end(), isspace))
726 for (
const auto& name : names) {
728 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
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 get_member_initializer_list(oks::OksMethodImplementation *mi)
std::string get_public_section(oks::OksMethodImplementation *mi)
void close_cpp_namespace(std::ostream &s, int level)
bool get_add_algo_1(oks::OksMethodImplementation *mi)
std::string get_include_dir(const oks::OksClass *c, const ClassInfo::Map &cl_info, const std::string &cpp_hdr_dir)
std::string get_type(oks::OksData::Type oks_type, bool is_cpp)
std::string get_method_header_prologue(oks::OksMethodImplementation *)
std::string get_private_section(oks::OksMethodImplementation *mi)
int open_cpp_namespace(std::ostream &s, const std::string &value)
std::string get_method_header_epilogue(oks::OksMethodImplementation *)
bool process_external_class(ClassInfo::Map &cl_info, const oks::OksClass *c, const std::list< std::string > &include_dirs, const std::list< std::string > &user_classes, bool verbose)
void print_indented(std::ostream &s, const std::string &text, const char *dx)
std::string int2dx(int level)
bool get_add_algo_n(oks::OksMethodImplementation *mi)
std::string alnum_name(const std::string &in)
std::string get_method_implementation_body(oks::OksMethodImplementation *mi)
std::string capitalize_name(const std::string &in)
void print_description(std::ostream &s, const std::string &text, const char *dx)
void write_info_file(std::ostream &s, const std::string &cpp_namespace, const std::string &cpp_header_dir, const std::set< const oks::OksClass *, std::less< const oks::OksClass * > > &class_names)
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)
const std::string end_private_section("END_PRIVATE_SECTION")
static std::string get_method_header_x_logue(OksMethodImplementation *mi, const std::string &begin, const std::string &end)
const std::string end_header_epilogue("END_HEADER_EPILOGUE")
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")
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")
const std::string end_member_initializer_list("END_MEMBER_INITIALIZER_LIST")
const std::string has_add_algo_1("ADD_ALGO_1")
const std::string begin_header_prologue("BEGIN_HEADER_PROLOGUE")
const std::string begin_public_section("BEGIN_PUBLIC_SECTION")
const std::string begin_private_section("BEGIN_PRIVATE_SECTION")
const std::string end_public_section("END_PUBLIC_SECTION")
const std::string end_header_prologue("END_HEADER_PROLOGUE")