LCOV - code coverage report
Current view: top level - include/error/generators - generate_error_t.cpp (source / functions) Coverage Total Hit
Test: mxlib Lines: 0.0 % 210 0
Test Date: 2026-08-30 22:23:37 Functions: 0.0 % 1 0

            Line data    Source code
       1              : /** \file generate_error_t.cpp
       2              :  * \brief Generates error_t.hpp from the configured mxlib error list.
       3              :  * \author Jared Males
       4              :  */
       5              : 
       6              : #include <cerrno>
       7              : #include <cstring>
       8              : #include <fstream>
       9              : #include <iostream>
      10              : #include <vector>
      11              : #include <string>
      12              : #include <format>
      13              : #include <algorithm>
      14              : 
      15              : #include <errno_info.hpp>
      16              : #include <fits_status_info.hpp>
      17              : 
      18              : #ifdef MXLIB_CUDA
      19              : #include <cudaError_info.hpp>
      20              : #endif
      21              : 
      22            0 : int main()
      23              : {
      24            0 :     std::vector<std::string> error_ts, error_t_msgs;
      25              : 
      26            0 :     std::ifstream fin;
      27            0 :     fin.open( "error_t_list.txt" );
      28              : 
      29            0 :     while( fin )
      30              :     {
      31            0 :         std::string line;
      32            0 :         std::getline( fin, line );
      33              : 
      34            0 :         size_t start = line.find_first_not_of( " \t" );
      35              : 
      36            0 :         if( start == std::string::npos )
      37              :         {
      38            0 :             continue;
      39              :         }
      40              : 
      41            0 :         if( line[start] == '#' )
      42              :         {
      43            0 :             continue;
      44              :         }
      45              : 
      46            0 :         size_t space = line.find( ' ', start );
      47              : 
      48            0 :         if( space == std::string::npos )
      49              :         {
      50            0 :             continue;
      51              :         }
      52              : 
      53            0 :         size_t quotest = line.find( '"', space );
      54              : 
      55            0 :         if( quotest == std::string::npos )
      56              :         {
      57            0 :             continue;
      58              :         }
      59              : 
      60            0 :         ++quotest;
      61              : 
      62            0 :         size_t quoteed = line.find( '"', quotest );
      63              : 
      64            0 :         if( quoteed == std::string::npos )
      65              :         {
      66            0 :             continue;
      67              :         }
      68              : 
      69            0 :         error_ts.push_back( line.substr( start, space - start ) );
      70            0 :         error_t_msgs.push_back( line.substr( quotest, quoteed - quotest ) );
      71            0 :     }
      72            0 :     fin.close();
      73              : 
      74            0 :     std::vector<std::string> ERRNOs, errnos, errno_msgs;
      75            0 :     std::vector<int> EVALs;
      76            0 :     errno_info( ERRNOs, EVALs, errnos, errno_msgs );
      77              : 
      78            0 :     std::vector<std::string> fits_codes, fits_vals, fits_msgs;
      79            0 :     fits_status_info( fits_codes, fits_vals, fits_msgs );
      80              : 
      81              :     #ifdef MXLIB_CUDA
      82              :     std::vector<std::string> cuda_codes, cuda_vals, cuda_msgs;
      83              :     cuda_info(cuda_vals, cuda_codes, cuda_msgs);
      84              :     #endif
      85              : 
      86              :     // Get max length of a name for formatting
      87            0 :     int maxlen = 0;
      88            0 :     for( auto &en : error_ts )
      89              :     {
      90            0 :         if( en.length() > maxlen )
      91              :         {
      92            0 :             maxlen = en.length();
      93              :         }
      94              :     }
      95              : 
      96            0 :     for( auto &en : errnos )
      97              :     {
      98            0 :         if( en.length() > maxlen )
      99              :         {
     100            0 :             maxlen = en.length();
     101              :         }
     102              :     }
     103              : 
     104            0 :     for( auto &ft : fits_codes )
     105              :     {
     106            0 :         if( ft.length() > maxlen )
     107              :         {
     108            0 :             maxlen = ft.length();
     109              :         }
     110              :     }
     111              : 
     112              :     #ifdef MXLIB_CUDA
     113              :     for( auto &ct : cuda_codes )
     114              :     {
     115              :         if( ct.length() > maxlen )
     116              :         {
     117              :             maxlen = ct.length();
     118              :         }
     119              :     }
     120              :     #endif
     121              : 
     122            0 :     std::vector<std::string> uniqueERRNOs, uniqueerrnos;
     123            0 :     for( size_t n = 1; n < ERRNOs.size(); ++n )
     124              :     {
     125            0 :         bool unique = true;
     126            0 :         for( size_t m = 0; m < n; ++m )
     127              :         {
     128            0 :             if( EVALs[n] == EVALs[m] )
     129              :             {
     130            0 :                 unique = false;
     131            0 :                 break;
     132              :             }
     133              :         }
     134              : 
     135            0 :         if( unique )
     136              :         {
     137            0 :             uniqueERRNOs.push_back( ERRNOs[n] );
     138            0 :             uniqueerrnos.push_back( errnos[n] );
     139              :         }
     140              :     }
     141              : 
     142            0 :     std::cerr << "Unique ECODES: " << uniqueERRNOs.size() << '/' << ERRNOs.size() << '\n';
     143              : 
     144            0 :     std::ofstream fout;
     145            0 :     fout.open( "../error_t.hpp" );
     146              : 
     147            0 :     fout << "/** \\file error_t.hpp" << '\n';
     148            0 :     fout << " *  \\brief The mxlib error_t type and utilities" << '\n';
     149            0 :     fout << " *  \\ingroup error_handling_files" << '\n';
     150            0 :     fout << " */" << '\n';
     151            0 :     fout << '\n';
     152            0 :     fout << "/* **********  THIS FILE IS GENERATED  ********** */" << '\n';
     153            0 :     fout << "/* ********** DO NOT MODIFY OR COMMIT  ********** */" << '\n';
     154            0 :     fout << '\n';
     155            0 :     fout << "#include <fitsio.h>" << '\n';
     156              :     #ifdef MXLIB_CUDA
     157              :     fout << "\n";
     158              :     fout << "#ifdef MXLIB_CUDA" << '\n';
     159              :     fout << "#include <cuda_runtime.h>" << '\n';
     160              :     fout << "#endif //MXLIB_CUDA\n";
     161              :     #endif
     162            0 :     fout << '\n';
     163            0 :     fout << "#ifndef mx_error_t_hpp" << '\n';
     164            0 :     fout << "#define mx_error_t_hpp" << '\n';
     165            0 :     fout << '\n';
     166            0 :     fout << "namespace mx" << '\n';
     167            0 :     fout << "{\n" << '\n';
     168            0 :     fout << '\n';
     169            0 :     fout << "/// The mxlib error codes" << '\n';
     170            0 :     fout << "/** \\ingroup error_handling_codes" << '\n';
     171            0 :     fout << " */" << '\n';
     172            0 :     fout << "enum class error_t" << '\n';
     173            0 :     fout << "{" << '\n';
     174            0 :     for( size_t n = 0; n < error_ts.size(); ++n )
     175              :     {
     176            0 :         std::string symbol = error_ts[n] + ',';
     177            0 :         fout << std::format( "    {:{}} ///< {}\n", symbol, maxlen + 1, error_t_msgs[n] );
     178            0 :     }
     179              : 
     180            0 :     for( size_t n = 0; n < errnos.size(); ++n )
     181              :     {
     182            0 :         error_ts.push_back( errnos[n] );
     183            0 :         error_t_msgs.push_back( errno_msgs[n] );
     184              : 
     185            0 :         std::string symbol = errnos[n] + ',';
     186            0 :         fout << std::format( "    {:{}} ///< {} ({})\n", symbol, maxlen + 1, errno_msgs[n], ERRNOs[n] );
     187            0 :     }
     188              : 
     189            0 :     for( size_t n = 0; n < fits_codes.size() ; ++n )
     190              :     {
     191            0 :         error_ts.push_back( fits_codes[n] );
     192            0 :         error_t_msgs.push_back( fits_msgs[n] );
     193            0 :         std::string symbol = fits_codes[n] + ',';
     194            0 :         fout << std::format( "    {:{}} ///< {}\n", symbol, maxlen + 1, fits_msgs[n] );
     195            0 :     }
     196              : 
     197              :     #ifdef MXLIB_CUDA
     198              :     for( size_t n = 0; n < cuda_codes.size(); ++n )
     199              :     {
     200              :         error_ts.push_back( cuda_codes[n] );
     201              :         error_t_msgs.push_back( cuda_msgs[n] );
     202              :         std::string symbol = cuda_codes[n] + ',';
     203              :         fout << std::format( "    {:{}} ///< {}\n", symbol, maxlen + 1, cuda_msgs[n] );
     204              :     }
     205              :     #endif
     206            0 :     fout << std::format( "    {:{}} ///< {}\n", "__sentinel", maxlen + 1, "do not use" );
     207              : 
     208              : 
     209            0 :     fout << "}; //enum class error_t" << "\n" << '\n';
     210              : 
     211            0 :     fout << "/// Convert a \\ref error_t code to its name" << '\n';
     212            0 :     fout << "/**" << '\n';
     213            0 :     fout << " * \\returns the name of the \\ref error_t code" << '\n';
     214            0 :     fout << " *" << '\n';
     215            0 :     fout << " * \\ingroup error_handling_codes" << '\n';
     216            0 :     fout << " */" << '\n';
     217              :     fout << "static constexpr const char * errorName( const error_t & errc /**< [in] the error code to convert*/)"
     218            0 :          << '\n';
     219            0 :     fout << "{" << '\n';
     220            0 :     fout << "    switch(errc)" << '\n';
     221            0 :     fout << "    {" << '\n';
     222              : 
     223            0 :     for( size_t n = 0; n < error_ts.size(); ++n )
     224              :     {
     225            0 :         fout << "        case error_t::" << error_ts[n] << ":" << '\n';
     226            0 :         fout << "            return \"" << error_ts[n] << "\";" << '\n';
     227              :     }
     228            0 :     fout << "        default:" << '\n';
     229            0 :     fout << "            return \"unknown error_t (bug)\";" << '\n';
     230            0 :     fout << "    }" << '\n';
     231            0 :     fout << "} //errorName" << '\n';
     232            0 :     fout << '\n';
     233              : 
     234            0 :     fout << "/// Get the descriptive message for a \\ref error_t code." << '\n';
     235            0 :     fout << "/**" << '\n';
     236            0 :     fout << " * \\returns the descriptive message corresponding to the \\ref error_t code" << '\n';
     237            0 :     fout << " *" << '\n';
     238            0 :     fout << " * \\ingroup error_handling_codes" << '\n';
     239            0 :     fout << " */" << '\n';
     240              :     fout << "static constexpr const char * errorMessage( const error_t & errc /**< [in] the error code for which to "
     241              :             "get the message*/)"
     242            0 :          << '\n';
     243            0 :     fout << "{" << '\n';
     244            0 :     fout << "    switch(errc)" << '\n';
     245            0 :     fout << "    {" << '\n';
     246              : 
     247            0 :     for( size_t n = 0; n < error_ts.size(); ++n )
     248              :     {
     249            0 :         fout << "        case error_t::" << error_ts[n] << ":" << '\n';
     250            0 :         fout << "            return \"" << error_t_msgs[n] << "\";" << '\n';
     251              :     }
     252            0 :     fout << "        default:" << '\n';
     253            0 :     fout << "            return \"unknown error_t (bug)\";" << '\n';
     254            0 :     fout << "    }" << '\n';
     255            0 :     fout << "} //errorMessage" << '\n';
     256            0 :     fout << '\n';
     257              : 
     258            0 :     fout << "/// Convert an errno code to \\ref error_t" << '\n';
     259            0 :     fout << "/**" << '\n';
     260            0 :     fout << " * \\returns the \\ref error_t code corresponding to the errno code" << '\n';
     261            0 :     fout << " *" << '\n';
     262            0 :     fout << " * \\ingroup error_handling_codes" << '\n';
     263            0 :     fout << " */" << '\n';
     264            0 :     fout << "static constexpr error_t errno2error_t( const int & err/**< [in] the errno code to convert*/)" << '\n';
     265            0 :     fout << "{" << '\n';
     266            0 :     fout << "    switch(err)" << '\n';
     267            0 :     fout << "    {" << '\n';
     268              : 
     269            0 :     for( size_t n = 0; n < uniqueERRNOs.size(); ++n )
     270              :     {
     271            0 :         fout << "        case " << uniqueERRNOs[n] << ":" << '\n';
     272            0 :         fout << "            return error_t::" << uniqueerrnos[n] << ";" << '\n';
     273              :     }
     274            0 :     fout << "        default:" << '\n';
     275            0 :     fout << "            return error_t::error;" << '\n';
     276            0 :     fout << "    }" << '\n';
     277            0 :     fout << "} //errno2error_t" << '\n';
     278              : 
     279            0 :     fout << '\n';
     280              : 
     281            0 :     fout << "/// Convert a FITS status code to \\ref error_t" << '\n';
     282            0 :     fout << "/**" << '\n';
     283            0 :     fout << " * \\returns the \\ref error_t code corresponding to the FITS status code" << '\n';
     284            0 :     fout << " *" << '\n';
     285            0 :     fout << " * \\ingroup fits_utils" << '\n';
     286            0 :     fout << " */" << '\n';
     287              :     fout << "static constexpr error_t fits_status2error_t( const int & err/**< [in] the fits status code to convert*/)"
     288            0 :          << '\n';
     289            0 :     fout << "{" << '\n';
     290            0 :     fout << "    switch(err)" << '\n';
     291            0 :     fout << "    {" << '\n';
     292            0 :     fout << "        case " << "0" << ":" << '\n'; // this is not specified
     293            0 :     fout << "            return error_t::noerror;" << '\n';
     294              : 
     295            0 :     for( size_t n = 0; n < fits_vals.size(); ++n )
     296              :     {
     297            0 :         fout << "        case " << fits_vals[n] << ":" << '\n';
     298            0 :         fout << "            return error_t::" << fits_codes[n] << ";" << '\n';
     299              :     }
     300            0 :     fout << "        default:" << '\n';
     301            0 :     fout << "            return error_t::error;" << '\n';
     302            0 :     fout << "    }" << '\n';
     303            0 :     fout << "} //fits_status2error_t" << '\n';
     304            0 :     fout << '\n';
     305              : 
     306              :     #ifdef MXLIB_CUDA
     307              :     fout << "#ifdef MXLIB_CUDA\n";
     308              :     fout << "/// Convert a cudaError code to \\ref error_t" << '\n';
     309              :     fout << "/**" << '\n';
     310              :     fout << " * \\returns the \\ref error_t code corresponding to the cudaError code" << '\n';
     311              :     fout << " *" << '\n';
     312              :     fout << " * \\ingroup cuda_utils" << '\n';
     313              :     fout << " */" << '\n';
     314              :     fout << "static constexpr error_t cudaError2error_t( const cudaError_t & err/**< [in] the cudaError code to convert*/)"
     315              :          << '\n';
     316              :     fout << "{" << '\n';
     317              :     fout << "    switch(err)" << '\n';
     318              :     fout << "    {" << '\n';
     319              :     for( size_t n = 0; n < cuda_vals.size(); ++n )
     320              :     {
     321              :         fout << "        case " << cuda_vals[n] << ":" << '\n';
     322              :         fout << "            return error_t::" << cuda_codes[n] << ";" << '\n';
     323              :     }
     324              :     fout << "        default:" << '\n';
     325              :     fout << "            return error_t::error;" << '\n';
     326              :     fout << "    }" << '\n';
     327              :     fout << "} //cudaError2error_t" << '\n';
     328              :     fout << "#endif //MXLIB_CUDA\n";
     329              :     fout << '\n';
     330              :     #endif //MXLIB_CUDA
     331              : 
     332            0 :     fout << "} //namespace mx" << '\n';
     333            0 :     fout << "#endif //mx_error_t_hpp" << '\n';
     334              : 
     335            0 :     fout << "\n\n";
     336            0 :     fout << "#ifdef MXLIBTEST_ERROR_T_TESTS" << '\n';
     337            0 :     fout << "#ifndef MXLIBTEST_ERROR_T_TESTS_INC" << '\n';
     338            0 :     fout << "#define MXLIBTEST_ERROR_T_TESTS_INC" << '\n';
     339            0 :     fout << '\n';
     340            0 :     fout << "namespace mx" << '\n';
     341            0 :     fout << "{" << '\n';
     342            0 :     fout << '\n';
     343            0 :     fout << "void error_t_vector( std::vector<error_t> & errcs )" << '\n';
     344            0 :     fout << '{' << '\n';
     345            0 :     fout << "    errcs = { error_t::" << error_ts[0] << ',' << '\n';
     346            0 :     for( size_t n = 1; n < error_ts.size() - 1; ++n )
     347              :     {
     348            0 :         fout << "              error_t::" << error_ts[n] << ',' << '\n';
     349              :     }
     350            0 :     fout << "              error_t::" << error_ts.back() << "};" << '\n';
     351            0 :     fout << '\n';
     352            0 :     fout << "} //error_t_vector" << '\n';
     353            0 :     fout <<'\n';
     354            0 :     fout << "void errno_vector( std::vector<int> & errnos )" << '\n';
     355            0 :     fout << '{' << '\n';
     356            0 :     fout << "    errnos = { " << uniqueERRNOs[0] << ',' << '\n';
     357            0 :     for( size_t n = 1; n < uniqueERRNOs.size() - 1; ++n )
     358              :     {
     359            0 :         fout << "               " << uniqueERRNOs[n] << ',' << '\n';
     360              :     }
     361            0 :     fout << "               " << uniqueERRNOs.back() << "};" << '\n';
     362            0 :     fout << '\n';
     363            0 :     fout << "} //errno_vector" << '\n';
     364            0 :     fout << "void fitserr_vector( std::vector<int> & fitserrs )" << '\n';
     365            0 :     fout << '{' << '\n';
     366            0 :     fout << "    fitserrs= { " << fits_vals[0] << ',' << '\n';
     367            0 :     for( size_t n = 1; n < fits_vals.size() - 1; ++n )
     368              :     {
     369            0 :         fout << "                " << fits_vals[n] << ',' << '\n';
     370              :     }
     371            0 :     fout << "                " << fits_vals.back() << "};" << '\n';
     372            0 :     fout << '\n';
     373            0 :     fout << "} //fitserr_vector" << '\n';
     374            0 :     fout <<'\n';
     375            0 :     fout << "} //namespace mx" << '\n';
     376            0 :     fout << '\n';
     377            0 :     fout << "#endif //MXLIBTEST_ERROR_T_TESTS_INC" << '\n';
     378            0 :     fout << "#endif //MXLIBTEST_ERROR_T_TESTS" << '\n';
     379            0 :     fout.close();
     380              : 
     381            0 :     return 0;
     382            0 : }
        

Generated by: LCOV version 2.0-1