LCOV - code coverage report
Current view: top level - conffwk/apps - config_export_data.cxx (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 87 0
Test Date: 2025-12-21 13:07:08 Functions: 0.0 % 2 0

            Line data    Source code
       1              : #include <stdlib.h>
       2              : 
       3              : #include <iostream>
       4              : 
       5              : #include <boost/program_options.hpp>
       6              : 
       7              : #include <boost/property_tree/info_parser.hpp>
       8              : #include <boost/property_tree/json_parser.hpp>
       9              : #include <boost/property_tree/xml_parser.hpp>
      10              : 
      11              : #include "conffwk/Configuration.hpp"
      12              : 
      13              : using namespace dunedaq::conffwk;
      14              : 
      15              : int
      16            0 : main(int argc, char *argv[])
      17              : {
      18            0 :   std::string output_file, db_name, classes, objects, files, format("json");
      19            0 :   bool apply_fix(false);
      20              : 
      21            0 :   boost::program_options::options_description desc("Export config data using boost property tree.\n\nOptions/Arguments");
      22              : 
      23            0 :   try
      24              :     {
      25            0 :       desc.add_options()
      26            0 :         (
      27              :           "database,d",
      28            0 :           boost::program_options::value<std::string>(&db_name)->required(),
      29              :           "database specification in format plugin-name:parameters"
      30              :         )
      31            0 :         (
      32              :           "classes,c",
      33            0 :           boost::program_options::value<std::string>(&classes),
      34              :           "regex defining class names; ignore if empty"
      35              :         )
      36            0 :         (
      37              :           "objects,i",
      38            0 :           boost::program_options::value<std::string>(&objects),
      39              :           "regex defining object IDs; ignore if empty"
      40              :         )
      41            0 :         (
      42              :           "files,f",
      43            0 :           boost::program_options::value<std::string>(&files),
      44              :           "regex defining data files; ignore if empty"
      45              :         )
      46            0 :         (
      47              :           "output,o",
      48            0 :           boost::program_options::value<std::string>(&output_file),
      49              :           "output file name; print to standard out, if not defined"
      50              :         )
      51            0 :         (
      52              :           "format,t",
      53            0 :           boost::program_options::value<std::string>(&format)->default_value(format),
      54              :           "output format (\"json\", \"xml\" or \"info\")"
      55              :         )
      56            0 :         (
      57              :           "fix,x",
      58              :           "fix arrays output format:\n* enforce empty arrays for json;\n* remove unnamed xml tags"
      59              :         )
      60            0 :         (
      61              :           "help,h",
      62              :           "Print help message"
      63              :         );
      64              : 
      65            0 :       boost::program_options::variables_map vm;
      66            0 :       boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
      67              : 
      68            0 :       if (vm.count("help"))
      69              :         {
      70            0 :           std::cout << desc << std::endl;
      71            0 :           return EXIT_SUCCESS;
      72              :         }
      73              : 
      74            0 :       boost::program_options::notify(vm);
      75              : 
      76            0 :       if (vm.count("fix"))
      77            0 :         apply_fix = true;
      78              : 
      79            0 :       auto valid_formats = {"json", "xml", "info"};
      80            0 :       if (std::none_of(valid_formats.begin(), valid_formats.end(), [&format](auto p){ return p == format; }))
      81            0 :         throw std::runtime_error("unsupported format \"" + format + '\"');
      82            0 :     }
      83            0 :   catch (std::exception& ex)
      84              :     {
      85            0 :       std::cerr << "command line error: " << ex.what() << std::endl;
      86            0 :       return EXIT_FAILURE;
      87            0 :     }
      88              : 
      89            0 :   try
      90              :     {
      91            0 :       Configuration db(db_name);
      92              : 
      93            0 :       boost::property_tree::ptree pt;
      94            0 :       std::string fix_empty_arrays((apply_fix && format == "json") ? "<-- empty-p3-element -->" : "");
      95              : 
      96            0 :       db.export_data(pt, classes, objects, files, fix_empty_arrays);
      97              : 
      98            0 :       std::string in, out;
      99              : 
     100            0 :         {
     101            0 :           std::ostringstream buf;
     102            0 :           if  (format == "json")
     103            0 :             boost::property_tree::json_parser::write_json(buf, pt);
     104            0 :           else if (format == "xml")
     105            0 :             boost::property_tree::xml_parser::write_xml(buf, pt, boost::property_tree::xml_writer_make_settings<std::string>(' ', 4));
     106              :           else
     107            0 :             boost::property_tree::info_parser::write_info(buf, pt, boost::property_tree::info_writer_make_settings(' ', 4));
     108              : 
     109            0 :           in = buf.str();
     110            0 :         }
     111              : 
     112            0 :       if (!apply_fix || format == "info")
     113            0 :         out = std::move(in);
     114              :       else
     115              :         {
     116            0 :           out.reserve(in.size());
     117            0 :           std::string::size_type pos = 0, fix_pos;
     118              : 
     119            0 :           if (format == "json")
     120              :             {
     121            0 :               while ((fix_pos = in.find(fix_empty_arrays, pos)) != std::string::npos)
     122              :                 {
     123            0 :                   std::string::size_type start = in.rfind('[', fix_pos);
     124            0 :                   std::string::size_type end = in.find(']', fix_pos);
     125              : 
     126            0 :                   if (start != std::string::npos && end != std::string::npos)
     127              :                     {
     128            0 :                       out.append(in, pos, start + 1 - pos);
     129              :                       pos = end;
     130              :                     }
     131              :                   else
     132              :                     break;
     133              :                 }
     134              :             }
     135              :           else
     136              :             {
     137              :               // remove unnamed xml tags: replace "<>FOO</>" by "FOO"
     138            0 :               while ((fix_pos = in.find("<>", pos)) != std::string::npos)
     139              :                 {
     140            0 :                   std::string::size_type next = in.find("</>", fix_pos);
     141              : 
     142            0 :                   if (next != std::string::npos)
     143              :                     {
     144            0 :                       out.append(in, pos, fix_pos - pos);
     145            0 :                       out.append(in, fix_pos+2, next - fix_pos - 2);
     146            0 :                       pos = next + 3;
     147              :                     }
     148              :                   else
     149              :                     break;
     150              :                 }
     151              :             }
     152              : 
     153            0 :           out.append(in, pos);
     154              :         }
     155              : 
     156            0 :       if (!output_file.empty())
     157              :         {
     158            0 :           std::ofstream f(output_file);
     159            0 :           f.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
     160            0 :           f << out;
     161            0 :           f.close();
     162            0 :         }
     163              :       else
     164            0 :         std::cout << out;
     165              : 
     166            0 :       return EXIT_SUCCESS;
     167            0 :     }
     168            0 :   catch (const dunedaq::conffwk::Exception &ex)
     169              :     {
     170            0 :       std::cout << "config error: " << ex << std::endl;
     171            0 :     }
     172            0 :   catch (const boost::property_tree::json_parser_error &ex)
     173              :     {
     174            0 :       std::cout << "ptree json error: " << ex.what() << std::endl;
     175            0 :     }
     176            0 :   catch (const std::exception &ex)
     177              :     {
     178            0 :       std::cout << "error: " << ex.what() << std::endl;
     179            0 :     }
     180              : 
     181              :   return EXIT_FAILURE;
     182            0 : }
        

Generated by: LCOV version 2.0-1