LCOV - code coverage report
Current view: top level - oksdalgen/apps - utils.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 290 0
Test Date: 2026-10-11 15:05:20 Functions: 0.0 % 26 0

            Line data    Source code
       1              : //
       2              : // DUNE DAQ modification notice:
       3              : // This file has been modified from the original ATLAS genconfig source for the DUNE DAQ project.
       4              : // Fork baseline commit: genconfig-03-10-00 (2021-04-26).
       5              : // Renamed since fork: yes (from src/utils.cpp to apps/utils.cpp).
       6              : //
       7              : 
       8              : #include "class_info.hpp"
       9              : 
      10              : #include "oks/kernel.hpp"
      11              : #include "oks/method.hpp"
      12              : 
      13              : #include <ctype.h>
      14              : 
      15              : #include <algorithm>
      16              : #include <ctime>
      17              : #include <initializer_list>
      18              : #include <iomanip>
      19              : #include <iostream>
      20              : 
      21              : using namespace dunedaq::oks;
      22              : using namespace dunedaq::oksdalgen;
      23              : 
      24              : /**
      25              :  *  The functions cvt_symbol() and alnum_name() are used
      26              :  *  to replace all symbols allowed in names of classes, attributes
      27              :  *  and relationships, but misinterpreted by c++.
      28              :  */
      29              : 
      30              : char
      31            0 : cvt_symbol(char c)
      32              : {
      33            0 :   return (isalnum(c) ? c : '_');
      34              : }
      35              : 
      36              : std::string
      37            0 : alnum_name(const std::string& in)
      38              : {
      39            0 :   std::string s(in);
      40            0 :   std::transform(s.begin(), s.end(), s.begin(), cvt_symbol);
      41            0 :   return s;
      42            0 : }
      43              : 
      44              : std::string
      45            0 : capitalize_name(const std::string& in)
      46              : {
      47            0 :   std::string s(in);
      48            0 :   if (!in.empty()) {
      49            0 :     if (isalpha(in[0])) {
      50            0 :       if (islower(in[0]))
      51            0 :         s[0] = toupper(in[0]);
      52              :     } else {
      53            0 :       s.insert(s.begin(), '_');
      54              :     }
      55              :   }
      56            0 :   return s;
      57            0 : }
      58              : 
      59              : /**
      60              :  *  The function print_description() is used for printing of the
      61              :  *  multi-line text with right alignment.
      62              :  */
      63              : 
      64              : void
      65            0 : print_description(std::ostream& s, const std::string& text, const char* dx)
      66              : {
      67            0 :   if (!text.empty()) {
      68            0 :     s << dx << " /**\n";
      69              : 
      70            0 :     Oks::Tokenizer t(text, "\n");
      71            0 :     std::string token;
      72              : 
      73            0 :     while (!(token = t.next()).empty()) {
      74            0 :       s << dx << "  *  " << token << std::endl;
      75              :     }
      76              : 
      77            0 :     s << dx << "  */\n\n";
      78            0 :   }
      79            0 : }
      80              : 
      81              : void
      82            0 : print_indented(std::ostream& s, const std::string& text, const char* dx)
      83              : {
      84            0 :   if (!text.empty()) {
      85            0 :     Oks::Tokenizer t(text, "\n");
      86            0 :     std::string token;
      87              : 
      88            0 :     while (!(token = t.next()).empty()) {
      89            0 :       s << dx << token << std::endl;
      90              :     }
      91            0 :   }
      92            0 : }
      93              : 
      94              : std::string
      95            0 : get_type(OksData::Type oks_type, bool is_cpp)
      96              : {
      97            0 :   switch (oks_type) {
      98            0 :     case OksData::unknown_type:
      99            0 :       return "UNKNOWN";
     100            0 :     case OksData::s8_int_type:
     101            0 :       return (is_cpp ? "int8_t" : "char");
     102            0 :     case OksData::u8_int_type:
     103            0 :       return (is_cpp ? "uint8_t" : "byte");
     104            0 :     case OksData::s16_int_type:
     105            0 :       return (is_cpp ? "int16_t" : "short");
     106            0 :     case OksData::u16_int_type:
     107            0 :       return (is_cpp ? "uint16_t" : "short");
     108            0 :     case OksData::s32_int_type:
     109            0 :       return (is_cpp ? "int32_t" : "int");
     110            0 :     case OksData::u32_int_type:
     111            0 :       return (is_cpp ? "uint32_t" : "int");
     112            0 :     case OksData::s64_int_type:
     113            0 :       return (is_cpp ? "int64_t" : "long");
     114            0 :     case OksData::u64_int_type:
     115            0 :       return (is_cpp ? "uint64_t" : "long");
     116            0 :     case OksData::float_type:
     117            0 :       return "float";
     118            0 :     case OksData::double_type:
     119            0 :       return "double";
     120            0 :     case OksData::bool_type:
     121            0 :       return (is_cpp ? "bool" : "boolean");
     122              : 
     123            0 :     case OksData::string_type:
     124            0 :     case OksData::enum_type:
     125            0 :     case OksData::date_type:
     126            0 :     case OksData::time_type:
     127            0 :     case OksData::class_type:
     128            0 :       return (is_cpp ? "std::string" : "String");
     129              : 
     130            0 :     case OksData::object_type:
     131            0 :     case OksData::list_type:
     132            0 :     case OksData::uid_type:
     133            0 :     case OksData::uid2_type:
     134            0 :       return "funnytype";
     135              :   }
     136              : 
     137            0 :   return "invalid";
     138              : }
     139              : 
     140              : // std::string
     141              : // get_java_impl_name(const std::string& s)
     142              : // {
     143              : //   std::string str(s);
     144              : //   str += "_Impl";
     145              : //   return str;
     146              : // }
     147              : 
     148              : // std::string
     149              : // get_java_helper_name(const std::string& s)
     150              : // {
     151              : //   std::string str(s);
     152              : //   str += "_Helper";
     153              : //   return str;
     154              : // }
     155              : 
     156              : void
     157            0 : gen_dump_application(std::ostream& s,
     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)
     165              : {
     166            0 :   s << "  // *** this file is generated by oksdalgen ***\n"
     167              :        "\n"
     168              :        "#include \"conffwk/ConfigObject.hpp\"\n"
     169              :        "#include \""
     170            0 :     << conf_header << "\"\n\n";
     171              : 
     172              :   // generate list of includes
     173            0 :   for (const auto& i : class_names) {
     174            0 :     std::string hname(cpp_hdr_dir);
     175            0 :     if (!hname.empty())
     176            0 :       hname += '/';
     177            0 :     hname += i;
     178            0 :     s << "#include \"" << hname << ".hpp\"\n";
     179            0 :   }
     180              : 
     181            0 :   if (headres_prologue && *headres_prologue) {
     182            0 :     s << "\n  // db implementation-specific headrers prologue\n\n" << headres_prologue << "\n";
     183              :   }
     184              : 
     185            0 :   s << "\n"
     186              :        "\n"
     187              :        "static void usage(const char * s)\n"
     188              :        "{\n"
     189              :        "  std::cout << s << \" -d db-name -c class-name [-q query | -i object-id] [-t]\\n\"\n"
     190              :        "    \"\\n\"\n"
     191              :        "    \"Options/Arguments:\\n\"\n"
     192              :        "    \"  -d | --data db-name            mandatory name of the database\\n\"\n"
     193              :        "    \"  -c | --class-name class-name   mandatory name of class\\n\"\n"
     194              :        "    \"  -q | --query query             optional query to select class objects\\n\"\n"
     195              :        "    \"  -i | --object-id object-id     optional identity to select one object\\n\"\n"
     196              :        "    \"  -t | --init-children           all referenced objects are initialized (is used\\n\"\n"
     197              :        "    \"                                 for debug purposes and performance measurements)\\n\"\n"
     198              :        "    \"  -h | --help                    print this message\\n\"\n"
     199              :        "    \"\\n\"\n"
     200              :        "    \"Description:\\n\"\n"
     201              :        "    \"  The program prints out object(s) of given class.\\n\"\n"
     202              :        "    \"  If no query or object id is provided, all objects of the class are printed.\\n\"\n"
     203              :        "    \"  It is automatically generated by oksdalgen utility.\\n\"\n"
     204              :        "    \"\\n\";\n"
     205              :        "}\n"
     206              :        "\n"
     207              :        "static void no_param(const char * s)\n"
     208              :        "{\n"
     209              :        "  std::cerr << \"ERROR: the required argument for option \\\'\" << s << \"\\\' is missing\\n\\n\";\n"
     210              :        "  exit (EXIT_FAILURE);\n"
     211              :        "}\n"
     212              :        "\n"
     213              :        "int main(int argc, char *argv[])\n"
     214            0 :        "{\n";
     215              : 
     216            0 :   if (main_function_prologue && *main_function_prologue) {
     217            0 :     s << "    // db implementation-specific main function prologue\n\n  " << main_function_prologue << "\n\n";
     218              :   }
     219              : 
     220            0 :   s << "    // parse parameters\n"
     221              :        "\n"
     222              :        "  const char * db_name = nullptr;\n"
     223              :        "  const char * object_id = nullptr;\n"
     224              :        "  const char * query = \"\";\n"
     225              :        "  std::string class_name;\n"
     226              :        "  bool init_children = false;\n"
     227              :        "\n"
     228              :        "  for(int i = 1; i < argc; i++) {\n"
     229              :        "    const char * cp = argv[i];\n"
     230              :        "    if(!strcmp(cp, \"-h\") || !strcmp(cp, \"--help\")) {\n"
     231              :        "      usage(argv[0]);\n"
     232              :        "      return 0;\n"
     233              :        "    }\n"
     234              :        "    if(!strcmp(cp, \"-t\") || !strcmp(cp, \"--init-children\")) {\n"
     235              :        "      init_children = true;\n"
     236              :        "    }\n"
     237              :        "    else if(!strcmp(cp, \"-d\") || !strcmp(cp, \"--data\")) {\n"
     238              :        "      if(++i == argc || argv[i][0] == '-') { no_param(cp); } else { db_name = argv[i]; }\n"
     239              :        "    }\n"
     240              :        "    else if(!strcmp(cp, \"-c\") || !strcmp(cp, \"--class-name\")) {\n"
     241              :        "      if(++i == argc || argv[i][0] == '-') { no_param(cp); } else { class_name = argv[i]; }\n"
     242              :        "    }\n"
     243              :        "    else if(!strcmp(cp, \"-i\") || !strcmp(cp, \"--object-id\")) {\n"
     244              :        "      if(++i == argc || argv[i][0] == '-') { no_param(cp); } else { object_id = argv[i]; }\n"
     245              :        "    }\n"
     246              :        "    else if(!strcmp(cp, \"-q\") || !strcmp(cp, \"--query\")) {\n"
     247              :        "      if(++i == argc || argv[i][0] == '-') { no_param(cp); } else { query = argv[i]; }\n"
     248              :        "    }\n"
     249              :        "    else {\n"
     250              :        "      std::cerr << \"ERROR: bad parameter \" << cp << std::endl;\n"
     251              :        "      usage(argv[0]);\n"
     252              :        "      return (EXIT_FAILURE);\n"
     253              :        "    }\n"
     254              :        "  }\n"
     255              :        "\n"
     256              :        "  if(db_name == nullptr) {\n"
     257              :        "    std::cerr << \"ERROR: no database name provided\\n\";\n"
     258              :        "    return (EXIT_FAILURE);\n"
     259              :        "  }\n"
     260              :        "\n"
     261              :        "  if(class_name.empty()) {\n"
     262              :        "    std::cerr << \"ERROR: no class name provided\\n\";\n"
     263              :        "    return (EXIT_FAILURE);\n"
     264              :        "  }\n"
     265              :        "\n"
     266              :        "  if(*query != 0 && object_id != nullptr) {\n"
     267              :        "    std::cerr << \"ERROR: only one parameter -i or -q can be provided\\n\";\n"
     268              :        "    return (EXIT_FAILURE);\n"
     269              :        "  }\n"
     270              :        "\n"
     271              :        "\n"
     272              :        "std::cout << std::boolalpha;\n"
     273            0 :        "\n";
     274              : 
     275            0 :   if (conf_name) {
     276            0 :     s << "  " << conf_name
     277              :       << " impl_conf;\n"
     278              :          "\n"
     279              :          "  {\n"
     280            0 :          "    dunedaq::conffwk::Configuration conf(db_name, &impl_conf);\n";
     281              :   } else {
     282            0 :     s << "  try {\n"
     283            0 :          "    dunedaq::conffwk::Configuration conf(db_name);\n";
     284              :   }
     285              : 
     286            0 :   s << "\n"
     287              :        "    if(!conf.loaded()) {\n"
     288              :        "      std::cerr << \"Can not load database: \" << db_name << std::endl;\n"
     289              :        "      return (EXIT_FAILURE);\n"
     290              :        "    }\n"
     291              :        "    \n"
     292              :        "    std::vector< dunedaq::conffwk::ConfigObject > objects;\n"
     293              :        "    \n"
     294              :        "    if(object_id) {\n"
     295              :        "      dunedaq::conffwk::ConfigObject obj;\n"
     296              :        "      try {\n"
     297              :        "        conf.get(class_name, object_id, obj, 1);\n"
     298              :        "      }\n"
     299              :        "      catch (dunedaq::conffwk::NotFound & ex) {\n"
     300              :        "        std::cerr << \"Can not get object \\'\" << object_id << \"\\' of class \\'\" << class_name << "
     301              :        "\"\\':\\n\" << ex << std::endl;\n"
     302              :        "        return (EXIT_FAILURE);\n"
     303              :        "      }\n"
     304              :        "      objects.push_back(obj);\n"
     305              :        "    }\n"
     306              :        "    else {\n"
     307              :        "      try {\n"
     308              :        "        conf.get(class_name, objects, query, 1);\n"
     309              :        "      }\n"
     310              :        "      catch (dunedaq::conffwk::NotFound & ex) {\n"
     311              :        "        std::cerr << \"Can not get objects of class \\'\" << class_name << \"\\':\\n\" << ex << std::endl;\n"
     312              :        "        return (EXIT_FAILURE);\n"
     313              :        "      }\n"
     314              :        "    }\n"
     315              :        "    \n"
     316              :        "    struct SortByUId {\n"
     317              :        "      bool operator() (const dunedaq::conffwk::ConfigObject * o1, const dunedaq::conffwk::ConfigObject * o2) "
     318              :        "const {\n"
     319              :        "        return (o1->UID() < o2->UID());\n"
     320              :        "      };\n"
     321              :        "    };\n"
     322              :        "    \n"
     323              :        "    std::set< dunedaq::conffwk::ConfigObject *, SortByUId > sorted_objects;\n"
     324              :        "    \n"
     325              :        "    for(auto& i : objects)\n"
     326              :        "      sorted_objects.insert(&i);\n"
     327              :        "    \n"
     328            0 :        "    for(auto& i : sorted_objects) {\n";
     329              : 
     330            0 :   for (std::list<std::string>::iterator i = class_names.begin(); i != class_names.end(); ++i) {
     331            0 :     const char* op = (i == class_names.begin() ? "if" : "else if");
     332            0 :     std::string cname(cpp_ns_name);
     333              : 
     334            0 :     if (!cname.empty())
     335            0 :       cname += "::";
     336              : 
     337            0 :     cname += *i;
     338              : 
     339            0 :     s << "      " << op << "(class_name == \"" << *i
     340              :       << "\") {\n"
     341              :          "        std::cout << *conf.get<"
     342              :       << cname
     343              :       << ">(*i, init_children) << std::endl;\n"
     344            0 :          "      }\n";
     345            0 :   }
     346              : 
     347            0 :   s << "      else {\n"
     348              :        "        std::cerr << \"ERROR: do not know how to dump object of \" << class_name << \" class\\n\";\n"
     349              :        "        return (EXIT_FAILURE);\n"
     350              :        "      }\n"
     351              :        "    }\n"
     352              :        "  }\n"
     353              :        "  catch (dunedaq::conffwk::Exception & ex) {\n"
     354              :        "    std::cerr << \"Caught \" << ex << std::endl;\n"
     355              :        "    return (EXIT_FAILURE);\n"
     356              :        "  }\n"
     357              :        "\n"
     358              :        "  return 0;\n"
     359            0 :        "}\n";
     360            0 : }
     361              : 
     362              : void
     363            0 : write_info_file(std::ostream& s,
     364              :                 const std::string& cpp_namespace,
     365              :                 const std::string& cpp_header_dir,
     366              :                 // const std::string& java_pname,
     367              :                 const std::set<const OksClass*, std::less<const OksClass*>>& classes)
     368              : {
     369            0 :   std::time_t now = std::time(nullptr);
     370              : 
     371            0 :   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"
     374              :        "c++-namespace="
     375              :     << cpp_namespace
     376              :     << "\n"
     377              :        "c++-header-dir-prefix="
     378              :     << cpp_header_dir
     379              :     << "\n"
     380              :        // "java-package-name=" << java_pname << "\n"
     381            0 :        "classes:\n";
     382              : 
     383            0 :   for (const auto& i : classes)
     384            0 :     s << "  " << i->get_name() << std::endl;
     385            0 : }
     386              : 
     387              : /**
     388              :  *  The function get_full_cpp_class_name() returns name of class
     389              :  *  with it's namespace (e.g. "NAMESPACE_A::CLASS_X")
     390              :  */
     391              : 
     392              : std::string
     393            0 : get_full_cpp_class_name(const OksClass* c, const ClassInfo::Map& cl_info, const std::string& cpp_ns_name)
     394              : {
     395            0 :   std::string s;
     396            0 :   ClassInfo::Map::const_iterator idx = cl_info.find(c);
     397              : 
     398            0 :   if (idx != cl_info.end())
     399            0 :     s = (*idx).second.get_namespace();
     400              :   else
     401            0 :     s = cpp_ns_name;
     402              : 
     403            0 :   if (!s.empty())
     404            0 :     s += "::";
     405              : 
     406            0 :   s += alnum_name(c->get_name());
     407              : 
     408            0 :   return s;
     409            0 : }
     410              : 
     411              : std::string
     412            0 : get_include_dir(const OksClass* c, const ClassInfo::Map& cl_info, const std::string& cpp_hdr_dir)
     413              : {
     414            0 :   std::string s;
     415              : 
     416            0 :   ClassInfo::Map::const_iterator idx = cl_info.find(c);
     417              : 
     418            0 :   if (idx != cl_info.end()) {
     419            0 :     const std::string include_prefix = (*idx).second.get_include_prefix();
     420            0 :     if (!include_prefix.empty()) {
     421            0 :       s = include_prefix;
     422            0 :       s += '/';
     423              :     }
     424            0 :   } else if (!cpp_hdr_dir.empty()) {
     425            0 :     s = cpp_hdr_dir;
     426            0 :     s += '/';
     427              :   }
     428              : 
     429            0 :   s += alnum_name(c->get_name());
     430              : 
     431            0 :   return s;
     432            0 : }
     433              : 
     434              : // const std::string&
     435              : // get_package_name(const OksClass * c, const ClassInfo::Map& cl_info, const std::string& java_p_name)
     436              : // {
     437              : //   std::string s;
     438              : 
     439              : //   ClassInfo::Map::const_iterator idx = cl_info.find(c);
     440              : 
     441              : //   if (idx != cl_info.end())
     442              : //     {
     443              : //       return (*idx).second.get_package_name();
     444              : //     }
     445              : //   else
     446              : //     {
     447              : //       return java_p_name;
     448              : //     }
     449              : // }
     450              : 
     451              : bool
     452            0 : process_external_class(ClassInfo::Map& cl_info,
     453              :                        const OksClass* c,
     454              :                        const std::list<std::string>& include_dirs,
     455              :                        const std::list<std::string>& user_classes,
     456              :                        bool verbose)
     457              : {
     458            0 :   if (cl_info.find(c) != cl_info.end())
     459              :     return true;
     460              : 
     461              :   // process list of user-defined classes first
     462              : 
     463            0 :   for (const auto& s : user_classes) {
     464            0 :     std::string::size_type idx = s.find("::");
     465            0 :     std::string::size_type idx2 = s.find("@", idx + 2);
     466              : 
     467            0 :     std::string cpp_ns_name;
     468            0 :     std::string class_name;
     469            0 :     std::string cpp_dir_name;
     470              : 
     471            0 :     if (idx == std::string::npos) {
     472            0 :       class_name = s.substr(0, idx2);
     473              :     } else {
     474            0 :       cpp_ns_name = s.substr(0, idx);
     475            0 :       class_name = s.substr(idx + 2, idx2 - idx - 2);
     476              :     }
     477              : 
     478            0 :     if (idx2 != std::string::npos)
     479            0 :       cpp_dir_name = s.substr(idx2 + 1);
     480              : 
     481            0 :     if (class_name == c->get_name()) {
     482            0 :       cl_info[c] = ClassInfo(cpp_ns_name, cpp_dir_name);
     483            0 :       if (verbose) {
     484            0 :         std::cout << " * class " << c->get_name() << " is defined by user in ";
     485              : 
     486            0 :         if (cpp_ns_name.empty())
     487            0 :           std::cout << "global namespace";
     488              :         else
     489            0 :           std::cout << "namespace \"" << cpp_ns_name << '\"';
     490              : 
     491            0 :         if (!cpp_dir_name.empty())
     492            0 :           std::cout << " with \"" << cpp_dir_name << "\" include prefix";
     493              : 
     494            0 :         std::cout << std::endl;
     495              :       }
     496              : 
     497            0 :       return true;
     498              :     }
     499            0 :   }
     500              : 
     501              :   // process oksdalgen files
     502              : 
     503            0 :   if (verbose)
     504            0 :     std::cout << "Looking for oksdalgen info files ...\n";
     505              : 
     506            0 :   bool found_class_declaration = false;
     507              : 
     508            0 :   for (const auto& i : include_dirs) {
     509            0 :     std::string file_name(i);
     510            0 :     file_name += "/oksdalgen.info";
     511              : 
     512            0 :     std::ifstream f(file_name.c_str());
     513              : 
     514            0 :     if (f) {
     515            0 :       if (verbose)
     516            0 :         std::cout << " *** found file \"" << file_name << "\" ***\n";
     517              : 
     518            0 :       std::string cpp_ns_name;
     519            0 :       std::string cpp_dir_name;
     520              :       // std::string java_pname;
     521            0 :       bool is_class = false;
     522              : 
     523            0 :       std::string s;
     524            0 :       while (std::getline(f, s)) {
     525            0 :         if (s.find("//") != std::string::npos) {
     526            0 :           if (verbose)
     527            0 :             std::cout << " - skip comment \"" << s << "\"\n";
     528            0 :         } else if (s.find("classes:") != std::string::npos) {
     529            0 :           if (verbose)
     530            0 :             std::cout << " - found classes keyword\n";
     531              :           is_class = true;
     532              :         } else {
     533            0 :           const char s1[] = "c++-namespace=";
     534            0 :           std::string::size_type idx = s.find(s1);
     535            0 :           if (idx != std::string::npos) {
     536            0 :             cpp_ns_name = s.substr(sizeof(s1) - 1);
     537            0 :             if (verbose)
     538            0 :               std::cout << " - c++ namespace = \"" << cpp_ns_name << "\"\n";
     539              :           } else {
     540            0 :             const char s2[] = "c++-header-dir-prefix=";
     541            0 :             std::string::size_type idx = s.find(s2);
     542            0 :             if (idx != std::string::npos) {
     543            0 :               cpp_dir_name = s.substr(sizeof(s2) - 1);
     544            0 :               if (verbose)
     545            0 :                 std::cout << " - c++ header dir prefix name = \"" << cpp_dir_name << "\"\n";
     546              :             }
     547              :             // else
     548              :             // {
     549              :             //   const char s3[] = "java-package-name=";
     550              :             //   std::string::size_type idx = s.find(s3);
     551              :             //   if (idx != std::string::npos)
     552              :             //     {
     553              :             //       java_pname = s.substr(sizeof(s3) - 1);
     554              :             //       if (verbose)
     555              :             //         std::cout << " - java package name = \"" << java_pname << "\"\n";
     556              :             //     }
     557            0 :             else if (is_class) {
     558            0 :               std::string cname = s.substr(2);
     559            0 :               OksClass* cl = c->get_kernel()->find_class(cname);
     560            0 :               if (cl && cl_info.find(cl) == cl_info.end()) {
     561            0 :                 cl_info[cl] = ClassInfo(cpp_ns_name, cpp_dir_name);
     562            0 :                 if (verbose)
     563            0 :                   std::cout << " * class " << cl->get_name() << " is defined by " << file_name << " in namespace \""
     564            0 :                             << cpp_ns_name << "\" with include prefix \"" << cpp_dir_name << "\"\n";
     565            0 :                 if (cl == c)
     566            0 :                   found_class_declaration = true;
     567            0 :               } else if (verbose) {
     568            0 :                 std::cout << " - skip class \"" << cname << "\" declaration\n";
     569              :               }
     570            0 :             } else {
     571            0 :               std::cerr << "Failed to parse line \"" << s << "\"\n";
     572              :             }
     573              :             // }
     574              :           }
     575              :         }
     576              :       }
     577            0 :     } else if (verbose) {
     578            0 :       std::cout << " *** file \"" << file_name << "\" does not exist ***\n";
     579              :     }
     580            0 :   }
     581              : 
     582            0 :   return found_class_declaration;
     583              : }
     584              : 
     585              : std::string
     586            0 : int2dx(int level)
     587              : {
     588            0 :   return std::string(level * 2, ' ');
     589              : }
     590              : 
     591              : int
     592            0 : open_cpp_namespace(std::ostream& s, const std::string& value)
     593              : {
     594            0 :   int level = 0;
     595            0 :   std::string dx;
     596              : 
     597            0 :   if (!value.empty()) {
     598            0 :     Oks::Tokenizer t(value, ":");
     599            0 :     std::string token;
     600              : 
     601            0 :     while (!(token = t.next()).empty()) {
     602            0 :       s << dx << "namespace " << token << " {\n";
     603            0 :       level++;
     604            0 :       dx += "  ";
     605              :     }
     606            0 :   }
     607              : 
     608            0 :   return level;
     609            0 : }
     610              : 
     611              : void
     612            0 : close_cpp_namespace(std::ostream& s, int level)
     613              : {
     614            0 :   while (level > 0) {
     615            0 :     std::string dx = int2dx(--level);
     616            0 :     s << dx << "}\n";
     617            0 :   }
     618            0 : }
     619              : 
     620              : const std::string begin_header_prologue("BEGIN_HEADER_PROLOGUE");
     621              : const std::string end_header_prologue("END_HEADER_PROLOGUE");
     622              : const std::string begin_header_epilogue("BEGIN_HEADER_EPILOGUE");
     623              : const std::string end_header_epilogue("END_HEADER_EPILOGUE");
     624              : const std::string begin_public_section("BEGIN_PUBLIC_SECTION"); // => java interface
     625              : const std::string end_public_section("END_PUBLIC_SECTION");
     626              : const std::string begin_private_section("BEGIN_PRIVATE_SECTION"); // => c++ and java
     627              : const std::string end_private_section("END_PRIVATE_SECTION");
     628              : const std::string begin_member_initializer_list("BEGIN_MEMBER_INITIALIZER_LIST");
     629              : const std::string end_member_initializer_list("END_MEMBER_INITIALIZER_LIST");
     630              : const std::string has_add_algo_1("ADD_ALGO_1");
     631              : const std::string has_add_algo_n("ADD_ALGO_N");
     632              : 
     633              : static std::string
     634            0 : get_method_header_x_logue(OksMethodImplementation* mi, const std::string& begin, const std::string& end)
     635              : {
     636            0 :   std::string::size_type begix_idx = mi->get_body().find(begin, 0);
     637            0 :   if (begix_idx == std::string::npos)
     638            0 :     return "";
     639            0 :   std::string::size_type end_idx = mi->get_body().find(end, begix_idx + begin.size());
     640            0 :   if (end_idx == std::string::npos)
     641            0 :     return "";
     642            0 :   return mi->get_body().substr(begix_idx + begin.size(), end_idx - begix_idx - begin.size());
     643              : }
     644              : 
     645              : std::string
     646            0 : get_method_header_prologue(OksMethodImplementation* mi)
     647              : {
     648            0 :   return get_method_header_x_logue(mi, begin_header_prologue, end_header_prologue);
     649              : }
     650              : 
     651              : std::string
     652            0 : get_method_header_epilogue(OksMethodImplementation* mi)
     653              : {
     654            0 :   return get_method_header_x_logue(mi, begin_header_epilogue, end_header_epilogue);
     655              : }
     656              : 
     657              : std::string
     658            0 : get_public_section(OksMethodImplementation* mi)
     659              : {
     660            0 :   return get_method_header_x_logue(mi, begin_public_section, end_public_section);
     661              : }
     662              : 
     663              : std::string
     664            0 : get_private_section(OksMethodImplementation* mi)
     665              : {
     666            0 :   return get_method_header_x_logue(mi, begin_private_section, end_private_section);
     667              : }
     668              : 
     669              : std::string
     670            0 : get_member_initializer_list(OksMethodImplementation* mi)
     671              : {
     672            0 :   return get_method_header_x_logue(mi, begin_member_initializer_list, end_member_initializer_list);
     673              : }
     674              : 
     675              : bool
     676            0 : get_add_algo_1(OksMethodImplementation* mi)
     677              : {
     678            0 :   return (mi->get_body().find(has_add_algo_1, 0) != std::string::npos);
     679              : }
     680              : 
     681              : bool
     682            0 : get_add_algo_n(OksMethodImplementation* mi)
     683              : {
     684            0 :   return (mi->get_body().find(has_add_algo_n, 0) != std::string::npos);
     685              : }
     686              : 
     687              : static void
     688            0 : remove_string_section(std::string& s, const std::string& begin, const std::string& end)
     689              : {
     690            0 :   std::string::size_type begix_idx = s.find(begin, 0);
     691            0 :   if (begix_idx == std::string::npos)
     692              :     return;
     693              : 
     694            0 :   std::string::size_type end_idx = (end.empty() ? (begix_idx + begin.size()) : s.find(end, begix_idx + begin.size()));
     695            0 :   if (end_idx == std::string::npos)
     696              :     return;
     697              : 
     698            0 :   end_idx += end.size();
     699            0 :   while (s[end_idx] == '\n')
     700            0 :     end_idx++;
     701              : 
     702            0 :   s.erase(begix_idx, end_idx - begix_idx);
     703              : }
     704              : 
     705              : std::string
     706            0 : get_method_implementation_body(OksMethodImplementation* mi)
     707              : {
     708            0 :   std::string s = mi->get_body();
     709            0 :   remove_string_section(s, begin_header_prologue, end_header_prologue);
     710            0 :   remove_string_section(s, begin_header_epilogue, end_header_epilogue);
     711            0 :   remove_string_section(s, begin_public_section, end_public_section);
     712            0 :   remove_string_section(s, begin_private_section, end_private_section);
     713            0 :   remove_string_section(s, begin_member_initializer_list, end_member_initializer_list);
     714            0 :   remove_string_section(s, has_add_algo_1, "");
     715            0 :   remove_string_section(s, has_add_algo_n, "");
     716              : 
     717            0 :   if (std::all_of(s.begin(), s.end(), isspace))
     718            0 :     return "";
     719              :   else
     720            0 :     return s;
     721            0 : }
     722              : 
     723              : static OksMethodImplementation*
     724            0 : find_method_implementation(const OksMethod* method, std::initializer_list<std::string> names)
     725              : {
     726            0 :   for (const auto& name : names) {
     727            0 :     if (OksMethodImplementation* mi = method->find_implementation(name))
     728            0 :       if (mi->get_prototype().empty() == false)
     729              :         return mi;
     730              :   }
     731              : 
     732              :   return nullptr;
     733              : }
     734              : 
     735              : OksMethodImplementation*
     736            0 : find_cpp_method_implementation(const OksMethod* method)
     737              : {
     738            0 :   return find_method_implementation(method, { "c++", "C++" });
     739            0 : }
        

Generated by: LCOV version 2.0-1