LCOV - code coverage report
Current view: top level - util - CGMFileOptions.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 94 145 64.8 %
Date: 2020-06-30 00:58:45 Functions: 12 16 75.0 %
Branches: 73 156 46.8 %

           Branch data     Line data    Source code
       1                 :            : /**\file CGMFileOptions.cpp
       2                 :            :  *\ copied from MOAB
       3                 :            :  *\date 2009-06-11
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "CGMFileOptions.hpp"
       7                 :            : 
       8                 :            : #include <ctype.h>
       9                 :            : #include <stdlib.h>
      10                 :            : #include <string.h>
      11                 :            : 
      12                 :            : const char DEFAULT_SEPARATOR = ';';
      13                 :            : 
      14                 :      10670 : static inline bool strempty( const char* s ) { return !*s; }
      15                 :            : 
      16                 :         55 : CGMFileOptions::CGMFileOptions( const char* str )
      17                 :         55 :   : mData(0)
      18                 :            : {
      19                 :            :     // if option string is null, just return
      20         [ +  + ]:         55 :   if (!str)
      21                 :         55 :     return;
      22                 :            :   
      23                 :            :     // check if alternate separator is specified
      24                 :         44 :   char separator[2] = { DEFAULT_SEPARATOR, '\0' };
      25         [ +  + ]:         44 :   if (*str == DEFAULT_SEPARATOR) {
      26                 :         33 :     ++str;
      27         [ -  + ]:         33 :     if (strempty(str))
      28                 :          0 :       return;
      29                 :         33 :     separator[0] = *str;
      30                 :         33 :     ++str;
      31                 :            :   }
      32                 :            :   
      33                 :            :     // don't bother allocating copy of input string if
      34                 :            :     // input string is empty.
      35         [ +  + ]:         44 :   if (!strempty(str))
      36                 :            :   {
      37                 :            :        // tokenize at separator character
      38                 :         33 :     mData = strdup( str );
      39         [ +  + ]:        198 :     for (char* i = strtok( mData, separator ); i; i = strtok( 0, separator )) 
      40         [ +  - ]:        154 :       if (!strempty(i)) // skip empty strings
      41         [ +  - ]:        154 :         mOptions.push_back( i );
      42                 :            :   }
      43                 :            : }
      44                 :            : 
      45                 :         33 : CGMFileOptions::CGMFileOptions( const CGMFileOptions& copy ) :
      46 [ +  - ][ +  - ]:         33 :   mData(0), mOptions( copy.mOptions.size() )
      47                 :            : {
      48 [ +  - ][ +  + ]:         33 :   if (!copy.mOptions.empty()) {
      49         [ +  - ]:         22 :     const char* last = copy.mOptions.back();
      50                 :         22 :     const char* endptr = last + strlen(last) + 1;
      51                 :         22 :     size_t len = endptr - copy.mData;
      52                 :         22 :     mData = (char*)malloc( len );
      53                 :         22 :     memcpy( mData, copy.mData, len );
      54 [ +  - ][ +  + ]:         66 :     for (size_t i = 0; i < mOptions.size(); ++i)
      55 [ +  - ][ +  - ]:         44 :       mOptions[i] = mData + (copy.mOptions[i] - copy.mData);
      56                 :            :   }
      57                 :         33 : }
      58                 :            : 
      59                 :         11 : CGMFileOptions& CGMFileOptions::operator=( const CGMFileOptions& copy )
      60                 :            : {
      61                 :         11 :   free( mData );
      62                 :         11 :   mData = 0;
      63                 :         11 :   mOptions.resize( copy.mOptions.size() );
      64                 :            : 
      65         [ +  - ]:         11 :   if (!copy.mOptions.empty()) {
      66                 :         11 :     const char* last = copy.mOptions.back();
      67                 :         11 :     const char* endptr = last + strlen(last) + 1;
      68                 :         11 :     size_t len = endptr - copy.mData;
      69                 :         11 :     mData = (char*)malloc( len );
      70                 :         11 :     memcpy( mData, copy.mData, len );
      71         [ +  + ]:        143 :     for (size_t i = 0; i < mOptions.size(); ++i)
      72                 :        132 :       mOptions[i] = mData + (copy.mOptions[i] - copy.mData);
      73                 :            :   }
      74                 :            :     
      75                 :         11 :   return *this;
      76                 :            : }
      77                 :            : 
      78                 :        176 : CGMFileOptions::~CGMFileOptions()
      79                 :            : {
      80                 :         88 :   free( mData );
      81                 :         88 : }
      82                 :            : 
      83                 :         22 : CGMFOErrorCode CGMFileOptions::get_null_option( const char* name ) const
      84                 :            : {
      85                 :            :   const char* s;
      86         [ +  - ]:         22 :   CGMFOErrorCode rval = get_option( name, s );
      87         [ -  + ]:         22 :   if (FO_SUCCESS != rval)
      88                 :          0 :     return rval;
      89         [ +  + ]:         22 :   return strempty(s) ? FO_SUCCESS : FO_TYPE_OUT_OF_RANGE;
      90                 :            : }
      91                 :            : 
      92                 :         44 : CGMFOErrorCode CGMFileOptions::get_int_option( const char* name, int& value ) const
      93                 :            : {
      94                 :            :   const char* s;
      95         [ +  - ]:         44 :   CGMFOErrorCode rval = get_option( name, s );
      96         [ -  + ]:         44 :   if (FO_SUCCESS != rval)
      97                 :          0 :     return rval;
      98                 :            :   
      99                 :            :     // empty string
     100         [ +  + ]:         44 :   if (strempty(s))
     101                 :         11 :     return FO_TYPE_OUT_OF_RANGE;
     102                 :            :   
     103                 :            :     // parse value
     104                 :            :   char* endptr;
     105                 :         33 :   long int pval = strtol( s, &endptr, 0 );
     106         [ +  + ]:         33 :   if (!strempty(endptr)) // syntax error
     107                 :         11 :     return FO_TYPE_OUT_OF_RANGE;
     108                 :            :   
     109                 :            :     // check for overflow (parsing long int, returning int)
     110                 :         22 :   value = pval;
     111         [ -  + ]:         22 :   if (pval != (long int)value)
     112                 :          0 :     return FO_TYPE_OUT_OF_RANGE;
     113                 :            :   
     114                 :         44 :   return FO_SUCCESS;
     115                 :            : }
     116                 :            : 
     117                 :          0 : CGMFOErrorCode CGMFileOptions::get_ints_option( const char* name, 
     118                 :            :                                           std::vector<int>& values) const
     119                 :            : {
     120                 :            :   const char* s;
     121         [ #  # ]:          0 :   CGMFOErrorCode rval = get_option( name, s );
     122         [ #  # ]:          0 :   if (FO_SUCCESS != rval)
     123                 :          0 :     return rval;
     124                 :            :   
     125                 :            :     // empty string
     126         [ #  # ]:          0 :   if (strempty(s))
     127                 :          0 :     return FO_TYPE_OUT_OF_RANGE;
     128                 :            :   
     129                 :            :     // parse values
     130         [ #  # ]:          0 :   while (!strempty(s)) {
     131                 :            :     char* endptr;
     132                 :          0 :     long int sval = strtol( s, &endptr, 0 );
     133                 :            : 
     134                 :            : #define EATSPACE(a) while ((!strncmp(a, " ", 1) ||    \
     135                 :            :                             !strncmp(a, ",", 1)) && !strempty(a)) a++;
     136                 :            :     //EATSPACE(endptr);
     137                 :            : 
     138 [ #  # ][ #  # ]:          0 :     while ((!strncmp(endptr, " ", 1) ||
     139 [ #  # ][ #  # ]:          0 :             !strncmp(endptr, ",", 1)) && !strempty(endptr)) {
     140                 :          0 :       endptr++;
     141                 :            :     }
     142                 :            : 
     143                 :          0 :     long int eval = sval;
     144         [ #  # ]:          0 :     if (!strcmp(endptr, "-")) {
     145                 :          0 :       endptr++;
     146                 :          0 :       s = endptr;
     147                 :          0 :       eval = strtol(s, &endptr, 0);
     148 [ #  # ][ #  # ]:          0 :       EATSPACE(endptr);
         [ #  # ][ #  # ]
     149                 :            :     }
     150                 :            :   
     151                 :            :       // check for overflow (parsing long int, returning int)
     152                 :          0 :     int value = sval;
     153         [ #  # ]:          0 :     if (sval != (long int)value)
     154                 :          0 :       return FO_TYPE_OUT_OF_RANGE;
     155                 :          0 :     value = eval;
     156         [ #  # ]:          0 :     if (eval != (long int)value)
     157                 :          0 :       return FO_TYPE_OUT_OF_RANGE;
     158                 :            :   
     159         [ #  # ]:          0 :     for (int i = sval; i <= eval; i++)
     160         [ #  # ]:          0 :       values.push_back(i);
     161                 :            : 
     162                 :          0 :     s = endptr;
     163                 :            :   }
     164                 :            :   
     165                 :          0 :   return FO_SUCCESS;
     166                 :            : }
     167                 :            : 
     168                 :         55 : CGMFOErrorCode CGMFileOptions::get_real_option ( const char* name, double& value ) const
     169                 :            : {
     170                 :            :   const char* s;
     171         [ +  - ]:         55 :   CGMFOErrorCode rval = get_option( name, s );
     172         [ -  + ]:         55 :   if (FO_SUCCESS != rval)
     173                 :          0 :     return rval;
     174                 :            :   
     175                 :            :     // empty string
     176         [ +  + ]:         55 :   if (strempty(s))
     177                 :         11 :     return FO_TYPE_OUT_OF_RANGE;
     178                 :            :   
     179                 :            :     // parse value
     180                 :            :   char* endptr;
     181                 :         44 :   value = strtod( s, &endptr );
     182         [ +  + ]:         44 :   if (!strempty(endptr)) // syntax error
     183                 :         11 :     return FO_TYPE_OUT_OF_RANGE;
     184                 :            :   
     185                 :         55 :   return FO_SUCCESS;
     186                 :            : }
     187                 :            : 
     188                 :         33 : CGMFOErrorCode CGMFileOptions::get_str_option( const char* name, std::string& value ) const
     189                 :            : {
     190                 :            :   const char* s;
     191         [ +  - ]:         33 :   CGMFOErrorCode rval = get_option( name, s );
     192         [ -  + ]:         33 :   if (FO_SUCCESS != rval)
     193                 :          0 :     return rval;
     194         [ +  + ]:         33 :   if (strempty(s))
     195                 :         11 :     return FO_TYPE_OUT_OF_RANGE;
     196         [ +  - ]:         22 :   value = s;
     197                 :         33 :   return FO_SUCCESS;
     198                 :            : }
     199                 :            : 
     200                 :         99 : CGMFOErrorCode CGMFileOptions::get_option( const char* name, std::string& value ) const
     201                 :            : {
     202                 :            :   const char* s;
     203         [ +  - ]:         99 :   CGMFOErrorCode rval = get_option( name, s );
     204         [ -  + ]:         99 :   if (FO_SUCCESS != rval)
     205                 :          0 :     return rval;
     206                 :            :   
     207         [ +  - ]:         99 :   value = s;
     208                 :         99 :   return FO_SUCCESS;
     209                 :            : }  
     210                 :            : 
     211                 :        253 : CGMFOErrorCode CGMFileOptions::get_option( const char* name, const char*& value ) const
     212                 :            : {
     213         [ +  - ]:        253 :   std::vector<const char*>::const_iterator i;
     214 [ +  - ][ +  - ]:       1441 :   for (i = mOptions.begin(); i != mOptions.end(); ++i) {
         [ +  - ][ +  - ]
                 [ +  - ]
     215         [ +  - ]:       1441 :     const char* opt = *i;
     216 [ +  - ][ +  + ]:       1441 :     if (compare( name, opt )) {
     217                 :        253 :       value = opt + strlen(name);
     218                 :            :         // if compare returned true, next char after option
     219                 :            :         // name must be either the null char or an equals symbol.
     220         [ +  + ]:        253 :       if (*value == '=') 
     221                 :        187 :         ++value;
     222                 :            :         
     223                 :        253 :       return FO_SUCCESS;
     224                 :            :     }
     225                 :            :   }
     226                 :            :   
     227                 :        253 :   return FO_ENTITY_NOT_FOUND;
     228                 :            : }
     229                 :            : 
     230                 :          0 : CGMFOErrorCode CGMFileOptions::match_option( const char* name, 
     231                 :            :                                        const char* value ) const
     232                 :            : {
     233                 :            :   int idx;
     234                 :          0 :   const char* array[] = { value, NULL };
     235         [ #  # ]:          0 :   return match_option( name, array, idx );
     236                 :            : }
     237                 :            : 
     238                 :          0 : CGMFOErrorCode CGMFileOptions::match_option( const char* name, 
     239                 :            :                                        const char* const* values, 
     240                 :            :                                        int& index ) const
     241                 :            : {
     242                 :            :   const char* optval;
     243         [ #  # ]:          0 :   CGMFOErrorCode rval = get_option( name, optval );
     244         [ #  # ]:          0 :   if (FO_SUCCESS != rval)
     245                 :          0 :     return rval;
     246                 :            :   
     247         [ #  # ]:          0 :   for (index = 0; values[index]; ++index)
     248 [ #  # ][ #  # ]:          0 :     if (compare( optval, values[index] ))
     249                 :          0 :       return FO_SUCCESS;
     250                 :            :   
     251                 :          0 :   index = -1;
     252                 :          0 :   return FO_FAILURE;
     253                 :            : }
     254                 :            : 
     255                 :            : 
     256                 :       1441 : bool CGMFileOptions::compare( const char* name, const char* option )
     257                 :            : {
     258 [ +  + ][ +  + ]:       3179 :   while (!strempty(name) && toupper(*name) == toupper(*option)) {
                 [ +  + ]
     259                 :       1738 :     ++name;
     260                 :       1738 :     ++option;
     261                 :            :   }
     262                 :            :    // match if name matched option for length of name,
     263                 :            :    // and option either matched entirely or matches up to
     264                 :            :    // and equals sign.
     265 [ +  + ][ +  + ]:       1441 :   return strempty(name) && (strempty(option) || *option == '=');
                 [ +  - ]
     266                 :            : }
     267                 :            : 
     268                 :          0 : void CGMFileOptions::get_options( std::vector<std::string>& list ) const
     269                 :            : {
     270                 :          0 :   list.clear();
     271 [ #  # ][ #  # ]:          0 :   list.resize( mOptions.size() );
     272                 :          0 :   std::copy( mOptions.begin(), mOptions.end(), list.begin() );
     273                 :          0 : }
     274                 :            : 

Generated by: LCOV version 1.11