LCOV - code coverage report
Current view: top level - src/interfaces/ecpg/ecpglib - data.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 60.4 % 457 276
Test Date: 2026-07-26 08:15:28 Functions: 100.0 % 12 12
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 57.4 % 338 194

             Branch data     Line data    Source code
       1                 :             : /* src/interfaces/ecpg/ecpglib/data.c */
       2                 :             : 
       3                 :             : #define POSTGRES_ECPG_INTERNAL
       4                 :             : #include "postgres_fe.h"
       5                 :             : 
       6                 :             : #include <math.h>
       7                 :             : 
       8                 :             : #include "ecpgerrno.h"
       9                 :             : #include "ecpglib.h"
      10                 :             : #include "ecpglib_extern.h"
      11                 :             : #include "ecpgtype.h"
      12                 :             : #include "pgtypes_date.h"
      13                 :             : #include "pgtypes_interval.h"
      14                 :             : #include "pgtypes_numeric.h"
      15                 :             : #include "pgtypes_timestamp.h"
      16                 :             : #include "sqlca.h"
      17                 :             : 
      18                 :             : /* returns true if character c is a delimiter for the given array type */
      19                 :             : static bool
      20                 :         222 : array_delimiter(enum ARRAY_TYPE isarray, char c)
      21                 :             : {
      22   [ +  -  +  + ]:         222 :     if (isarray == ECPG_ARRAY_ARRAY && c == ',')
      23                 :         198 :         return true;
      24                 :             : 
      25   [ -  +  -  - ]:          24 :     if (isarray == ECPG_ARRAY_VECTOR && c == ' ')
      26                 :           0 :         return true;
      27                 :             : 
      28                 :          24 :     return false;
      29                 :             : }
      30                 :             : 
      31                 :             : /* returns true if character c marks the boundary for the given array type */
      32                 :             : static bool
      33                 :         112 : array_boundary(enum ARRAY_TYPE isarray, char c)
      34                 :             : {
      35   [ +  -  +  + ]:         112 :     if (isarray == ECPG_ARRAY_ARRAY && c == '}')
      36                 :          22 :         return true;
      37                 :             : 
      38   [ -  +  -  - ]:          90 :     if (isarray == ECPG_ARRAY_VECTOR && c == '\0')
      39                 :           0 :         return true;
      40                 :             : 
      41                 :          90 :     return false;
      42                 :             : }
      43                 :             : 
      44                 :             : /* returns true if some garbage is found at the end of the scanned string */
      45                 :             : static bool
      46                 :         586 : garbage_left(enum ARRAY_TYPE isarray, char **scan_length, enum COMPAT_MODE compat)
      47                 :             : {
      48                 :             :     /*
      49                 :             :      * INFORMIX allows for selecting a numeric into an int, the result is
      50                 :             :      * truncated
      51                 :             :      */
      52         [ +  + ]:         586 :     if (isarray == ECPG_ARRAY_NONE)
      53                 :             :     {
      54   [ +  +  -  +  :         566 :         if (INFORMIX_MODE(compat) && **scan_length == '.')
                   -  + ]
      55                 :             :         {
      56                 :             :             /* skip invalid characters */
      57                 :             :             do
      58                 :             :             {
      59                 :           0 :                 (*scan_length)++;
      60         [ #  # ]:           0 :             } while (isdigit((unsigned char) **scan_length));
      61                 :             :         }
      62                 :             : 
      63   [ +  -  -  + ]:         566 :         if (**scan_length != ' ' && **scan_length != '\0')
      64                 :           0 :             return true;
      65                 :             :     }
      66   [ -  +  -  -  :          20 :     else if (ECPG_IS_ARRAY(isarray) && !array_delimiter(isarray, **scan_length) && !array_boundary(isarray, **scan_length))
             +  +  -  + ]
      67                 :           0 :         return true;
      68                 :             : 
      69                 :         586 :     return false;
      70                 :             : }
      71                 :             : 
      72                 :             : 
      73                 :             : /*
      74                 :             :  * Portability wrappers borrowed from src/include/utils/float.h
      75                 :             :  */
      76                 :             : static double
      77                 :          16 : get_float8_infinity(void)
      78                 :             : {
      79                 :          16 :     return (double) INFINITY;
      80                 :             : }
      81                 :             : 
      82                 :             : static double
      83                 :           8 : get_float8_nan(void)
      84                 :             : {
      85                 :           8 :     return (double) NAN;
      86                 :             : }
      87                 :             : 
      88                 :             : 
      89                 :             : static bool
      90                 :          90 : check_special_value(char *ptr, double *retval, char **endptr)
      91                 :             : {
      92         [ +  + ]:          90 :     if (pg_strncasecmp(ptr, "NaN", 3) == 0)
      93                 :             :     {
      94                 :           8 :         *retval = get_float8_nan();
      95                 :           8 :         *endptr = ptr + 3;
      96                 :           8 :         return true;
      97                 :             :     }
      98         [ +  + ]:          82 :     else if (pg_strncasecmp(ptr, "Infinity", 8) == 0)
      99                 :             :     {
     100                 :           8 :         *retval = get_float8_infinity();
     101                 :           8 :         *endptr = ptr + 8;
     102                 :           8 :         return true;
     103                 :             :     }
     104         [ +  + ]:          74 :     else if (pg_strncasecmp(ptr, "-Infinity", 9) == 0)
     105                 :             :     {
     106                 :           8 :         *retval = -get_float8_infinity();
     107                 :           8 :         *endptr = ptr + 9;
     108                 :           8 :         return true;
     109                 :             :     }
     110                 :             : 
     111                 :          66 :     return false;
     112                 :             : }
     113                 :             : 
     114                 :             : /* imported from src/backend/utils/adt/encode.c */
     115                 :             : 
     116                 :             : unsigned
     117                 :          70 : ecpg_hex_enc_len(unsigned srclen)
     118                 :             : {
     119                 :          70 :     return srclen << 1;
     120                 :             : }
     121                 :             : 
     122                 :             : unsigned
     123                 :           6 : ecpg_hex_dec_len(unsigned srclen)
     124                 :             : {
     125                 :           6 :     return srclen >> 1;
     126                 :             : }
     127                 :             : 
     128                 :             : static inline char
     129                 :       18276 : get_hex(char c)
     130                 :             : {
     131                 :             :     static const int8 hexlookup[128] = {
     132                 :             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     133                 :             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     134                 :             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     135                 :             :         0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
     136                 :             :         -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     137                 :             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     138                 :             :         -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     139                 :             :         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     140                 :             :     };
     141                 :       18276 :     int         res = -1;
     142                 :             : 
     143   [ +  -  +  - ]:       18276 :     if (c > 0 && c < 127)
     144                 :       18276 :         res = hexlookup[(unsigned char) c];
     145                 :             : 
     146                 :       18276 :     return (char) res;
     147                 :             : }
     148                 :             : 
     149                 :             : static unsigned
     150                 :          18 : hex_decode(const char *src, unsigned len, char *dst)
     151                 :             : {
     152                 :             :     const char *s,
     153                 :             :                *srcend;
     154                 :             :     char        v1,
     155                 :             :                 v2,
     156                 :             :                *p;
     157                 :             : 
     158                 :          18 :     srcend = src + len;
     159                 :          18 :     s = src;
     160                 :          18 :     p = dst;
     161         [ +  + ]:        9156 :     while (s < srcend)
     162                 :             :     {
     163   [ +  -  +  -  :        9138 :         if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '\r')
             +  -  -  + ]
     164                 :             :         {
     165                 :           0 :             s++;
     166                 :           0 :             continue;
     167                 :             :         }
     168                 :        9138 :         v1 = get_hex(*s++) << 4;
     169         [ -  + ]:        9138 :         if (s >= srcend)
     170                 :           0 :             return -1;
     171                 :             : 
     172                 :        9138 :         v2 = get_hex(*s++);
     173                 :        9138 :         *p++ = v1 | v2;
     174                 :             :     }
     175                 :             : 
     176                 :          18 :     return p - dst;
     177                 :             : }
     178                 :             : 
     179                 :             : unsigned
     180                 :          26 : ecpg_hex_encode(const char *src, unsigned len, char *dst)
     181                 :             : {
     182                 :             :     static const char hextbl[] = "0123456789abcdef";
     183                 :          26 :     const char *end = src + len;
     184                 :             : 
     185         [ +  + ]:       13338 :     while (src < end)
     186                 :             :     {
     187                 :       13312 :         *dst++ = hextbl[(*src >> 4) & 0xF];
     188                 :       13312 :         *dst++ = hextbl[*src & 0xF];
     189                 :       13312 :         src++;
     190                 :             :     }
     191                 :          26 :     return len * 2;
     192                 :             : }
     193                 :             : 
     194                 :             : bool
     195                 :        2882 : ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
     196                 :             :               enum ECPGttype type, enum ECPGttype ind_type,
     197                 :             :               char *var, char *ind, long varcharsize, long offset,
     198                 :             :               long ind_offset, enum ARRAY_TYPE isarray, enum COMPAT_MODE compat, bool force_indicator)
     199                 :             : {
     200                 :        2882 :     struct sqlca_t *sqlca = ECPGget_sqlca();
     201                 :        2882 :     char       *pval = (char *) PQgetvalue(results, act_tuple, act_field);
     202                 :        2882 :     int         binary = PQfformat(results, act_field);
     203                 :        2882 :     int         size = PQgetlength(results, act_tuple, act_field);
     204                 :        2882 :     int         value_for_indicator = 0;
     205                 :             :     long        log_offset;
     206                 :             : 
     207         [ -  + ]:        2882 :     if (sqlca == NULL)
     208                 :             :     {
     209                 :           0 :         ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
     210                 :             :                    ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
     211                 :           0 :         return false;
     212                 :             :     }
     213                 :             : 
     214                 :             :     /*
     215                 :             :      * If we are running in a regression test, do not log the offset variable,
     216                 :             :      * it depends on the machine's alignment.
     217                 :             :      */
     218         [ +  + ]:        2882 :     if (ecpg_internal_regression_mode)
     219                 :        1210 :         log_offset = -1;
     220                 :             :     else
     221                 :        1672 :         log_offset = offset;
     222                 :             : 
     223   [ +  +  -  +  :        2882 :     ecpg_log("ecpg_get_data on line %d: RESULT: %s offset: %ld; array: %s\n", lineno, pval ? (binary ? "BINARY" : pval) : "EMPTY", log_offset, ECPG_IS_ARRAY(isarray) ? "yes" : "no");
             +  -  +  + ]
     224                 :             : 
     225                 :             :     /* pval is a pointer to the value */
     226         [ -  + ]:        2882 :     if (!pval)
     227                 :             :     {
     228                 :             :         /*
     229                 :             :          * This should never happen because we already checked that we found
     230                 :             :          * at least one tuple, but let's play it safe.
     231                 :             :          */
     232                 :           0 :         ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
     233                 :           0 :         return false;
     234                 :             :     }
     235                 :             : 
     236                 :             :     /* We will have to decode the value */
     237                 :             : 
     238                 :             :     /*
     239                 :             :      * check for null value and set indicator accordingly, i.e. -1 if NULL and
     240                 :             :      * 0 if not
     241                 :             :      */
     242         [ +  + ]:        2882 :     if (PQgetisnull(results, act_tuple, act_field))
     243                 :          96 :         value_for_indicator = -1;
     244                 :             : 
     245   [ +  +  +  -  :        2882 :     switch (ind_type)
                   +  - ]
     246                 :             :     {
     247                 :         100 :         case ECPGt_short:
     248                 :             :         case ECPGt_unsigned_short:
     249                 :         100 :             *((short *) (ind + ind_offset * act_tuple)) = value_for_indicator;
     250                 :         100 :             break;
     251                 :         160 :         case ECPGt_int:
     252                 :             :         case ECPGt_unsigned_int:
     253                 :         160 :             *((int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
     254                 :         160 :             break;
     255                 :          20 :         case ECPGt_long:
     256                 :             :         case ECPGt_unsigned_long:
     257                 :          20 :             *((long *) (ind + ind_offset * act_tuple)) = value_for_indicator;
     258                 :          20 :             break;
     259                 :           0 :         case ECPGt_long_long:
     260                 :             :         case ECPGt_unsigned_long_long:
     261                 :           0 :             *((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator;
     262                 :           0 :             break;
     263                 :        2602 :         case ECPGt_NO_INDICATOR:
     264         [ +  + ]:        2602 :             if (value_for_indicator == -1)
     265                 :             :             {
     266         [ +  + ]:          36 :                 if (force_indicator == false)
     267                 :             :                 {
     268                 :             :                     /*
     269                 :             :                      * Informix has an additional way to specify NULLs note
     270                 :             :                      * that this uses special values to denote NULL
     271                 :             :                      */
     272                 :          24 :                     ECPGset_noind_null(type, var + offset * act_tuple);
     273                 :             :                 }
     274                 :             :                 else
     275                 :             :                 {
     276                 :          12 :                     ecpg_raise(lineno, ECPG_MISSING_INDICATOR,
     277                 :             :                                ECPG_SQLSTATE_NULL_VALUE_NO_INDICATOR_PARAMETER,
     278                 :             :                                NULL);
     279                 :          12 :                     return false;
     280                 :             :                 }
     281                 :             :             }
     282                 :        2590 :             break;
     283                 :           0 :         default:
     284                 :           0 :             ecpg_raise(lineno, ECPG_UNSUPPORTED,
     285                 :             :                        ECPG_SQLSTATE_ECPG_INTERNAL_ERROR,
     286                 :             :                        ecpg_type_name(ind_type));
     287                 :           0 :             return false;
     288                 :             :             break;
     289                 :             :     }
     290                 :             : 
     291         [ +  + ]:        2870 :     if (value_for_indicator == -1)
     292                 :          84 :         return true;
     293                 :             : 
     294                 :             :     /* let's check if it really is an array if it should be one */
     295         [ +  + ]:        2786 :     if (isarray == ECPG_ARRAY_ARRAY)
     296                 :             :     {
     297         [ -  + ]:          12 :         if (*pval != '{')
     298                 :             :         {
     299                 :           0 :             ecpg_raise(lineno, ECPG_DATA_NOT_ARRAY,
     300                 :             :                        ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
     301                 :           0 :             return false;
     302                 :             :         }
     303                 :             : 
     304         [ +  + ]:          12 :         switch (type)
     305                 :             :         {
     306                 :           2 :             case ECPGt_char:
     307                 :             :             case ECPGt_unsigned_char:
     308                 :             :             case ECPGt_varchar:
     309                 :             :             case ECPGt_string:
     310                 :           2 :                 break;
     311                 :             : 
     312                 :          10 :             default:
     313                 :          10 :                 pval++;
     314                 :          10 :                 break;
     315                 :             :         }
     316                 :             :     }
     317                 :             : 
     318                 :             :     do
     319                 :             :     {
     320         [ +  + ]:        2876 :         if (binary)
     321                 :             :         {
     322   [ +  +  +  - ]:           8 :             if (varcharsize == 0 || varcharsize * offset >= size)
     323                 :           8 :                 memcpy(var + offset * act_tuple, pval, size);
     324                 :             :             else
     325                 :             :             {
     326                 :           0 :                 memcpy(var + offset * act_tuple, pval, varcharsize * offset);
     327                 :             : 
     328         [ #  # ]:           0 :                 if (varcharsize * offset < size)
     329                 :             :                 {
     330                 :             :                     /* truncation */
     331   [ #  #  #  #  :           0 :                     switch (ind_type)
                      # ]
     332                 :             :                     {
     333                 :           0 :                         case ECPGt_short:
     334                 :             :                         case ECPGt_unsigned_short:
     335                 :           0 :                             *((short *) (ind + ind_offset * act_tuple)) = size;
     336                 :           0 :                             break;
     337                 :           0 :                         case ECPGt_int:
     338                 :             :                         case ECPGt_unsigned_int:
     339                 :           0 :                             *((int *) (ind + ind_offset * act_tuple)) = size;
     340                 :           0 :                             break;
     341                 :           0 :                         case ECPGt_long:
     342                 :             :                         case ECPGt_unsigned_long:
     343                 :           0 :                             *((long *) (ind + ind_offset * act_tuple)) = size;
     344                 :           0 :                             break;
     345                 :           0 :                         case ECPGt_long_long:
     346                 :             :                         case ECPGt_unsigned_long_long:
     347                 :           0 :                             *((long long int *) (ind + ind_offset * act_tuple)) = size;
     348                 :           0 :                             break;
     349                 :           0 :                         default:
     350                 :           0 :                             break;
     351                 :             :                     }
     352                 :           0 :                     sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
     353                 :             :                 }
     354                 :             :             }
     355                 :           8 :             pval += size;
     356                 :             :         }
     357                 :             :         else
     358                 :             :         {
     359   [ +  -  -  -  :        2868 :             switch (type)
          +  +  +  +  +  
             +  +  +  +  
                      - ]
     360                 :             :             {
     361                 :             :                     long        res;
     362                 :             :                     unsigned long ures;
     363                 :             :                     double      dres;
     364                 :             :                     char       *scan_length;
     365                 :             :                     numeric    *nres;
     366                 :             :                     date        ddres;
     367                 :             :                     timestamp   tres;
     368                 :             :                     interval   *ires;
     369                 :             :                     char       *endptr,
     370                 :             :                                 endchar;
     371                 :             : 
     372                 :         496 :                 case ECPGt_short:
     373                 :             :                 case ECPGt_int:
     374                 :             :                 case ECPGt_long:
     375                 :         496 :                     res = strtol(pval, &scan_length, 10);
     376         [ -  + ]:         496 :                     if (garbage_left(isarray, &scan_length, compat))
     377                 :             :                     {
     378                 :           0 :                         ecpg_raise(lineno, ECPG_INT_FORMAT,
     379                 :             :                                    ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     380                 :           0 :                         return false;
     381                 :             :                     }
     382                 :         496 :                     pval = scan_length;
     383                 :             : 
     384   [ +  +  +  - ]:         496 :                     switch (type)
     385                 :             :                     {
     386                 :          32 :                         case ECPGt_short:
     387                 :          32 :                             *((short *) (var + offset * act_tuple)) = (short) res;
     388                 :          32 :                             break;
     389                 :         438 :                         case ECPGt_int:
     390                 :         438 :                             *((int *) (var + offset * act_tuple)) = (int) res;
     391                 :         438 :                             break;
     392                 :          26 :                         case ECPGt_long:
     393                 :          26 :                             *((long *) (var + offset * act_tuple)) = (long) res;
     394                 :          26 :                             break;
     395                 :           0 :                         default:
     396                 :             :                             /* Cannot happen */
     397                 :           0 :                             break;
     398                 :             :                     }
     399                 :         496 :                     break;
     400                 :             : 
     401                 :           0 :                 case ECPGt_unsigned_short:
     402                 :             :                 case ECPGt_unsigned_int:
     403                 :             :                 case ECPGt_unsigned_long:
     404                 :           0 :                     ures = strtoul(pval, &scan_length, 10);
     405         [ #  # ]:           0 :                     if (garbage_left(isarray, &scan_length, compat))
     406                 :             :                     {
     407                 :           0 :                         ecpg_raise(lineno, ECPG_UINT_FORMAT,
     408                 :             :                                    ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     409                 :           0 :                         return false;
     410                 :             :                     }
     411                 :           0 :                     pval = scan_length;
     412                 :             : 
     413   [ #  #  #  # ]:           0 :                     switch (type)
     414                 :             :                     {
     415                 :           0 :                         case ECPGt_unsigned_short:
     416                 :           0 :                             *((unsigned short *) (var + offset * act_tuple)) = (unsigned short) ures;
     417                 :           0 :                             break;
     418                 :           0 :                         case ECPGt_unsigned_int:
     419                 :           0 :                             *((unsigned int *) (var + offset * act_tuple)) = (unsigned int) ures;
     420                 :           0 :                             break;
     421                 :           0 :                         case ECPGt_unsigned_long:
     422                 :           0 :                             *((unsigned long *) (var + offset * act_tuple)) = (unsigned long) ures;
     423                 :           0 :                             break;
     424                 :           0 :                         default:
     425                 :             :                             /* Cannot happen */
     426                 :           0 :                             break;
     427                 :             :                     }
     428                 :           0 :                     break;
     429                 :             : 
     430                 :           0 :                 case ECPGt_long_long:
     431                 :           0 :                     *((long long int *) (var + offset * act_tuple)) = strtoll(pval, &scan_length, 10);
     432         [ #  # ]:           0 :                     if (garbage_left(isarray, &scan_length, compat))
     433                 :             :                     {
     434                 :           0 :                         ecpg_raise(lineno, ECPG_INT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     435                 :           0 :                         return false;
     436                 :             :                     }
     437                 :           0 :                     pval = scan_length;
     438                 :             : 
     439                 :           0 :                     break;
     440                 :             : 
     441                 :           0 :                 case ECPGt_unsigned_long_long:
     442                 :           0 :                     *((unsigned long long int *) (var + offset * act_tuple)) = strtoull(pval, &scan_length, 10);
     443         [ #  # ]:           0 :                     if (garbage_left(isarray, &scan_length, compat))
     444                 :             :                     {
     445                 :           0 :                         ecpg_raise(lineno, ECPG_UINT_FORMAT, ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     446                 :           0 :                         return false;
     447                 :             :                     }
     448                 :           0 :                     pval = scan_length;
     449                 :             : 
     450                 :           0 :                     break;
     451                 :             : 
     452                 :          90 :                 case ECPGt_float:
     453                 :             :                 case ECPGt_double:
     454   [ +  -  -  + ]:          90 :                     if (isarray && *pval == '"')
     455                 :           0 :                         pval++;
     456                 :             : 
     457         [ +  + ]:          90 :                     if (!check_special_value(pval, &dres, &scan_length))
     458                 :          66 :                         dres = strtod(pval, &scan_length);
     459                 :             : 
     460   [ +  -  -  + ]:          90 :                     if (isarray && *scan_length == '"')
     461                 :           0 :                         scan_length++;
     462                 :             : 
     463                 :             :                     /* no special INFORMIX treatment for floats */
     464         [ -  + ]:          90 :                     if (garbage_left(isarray, &scan_length, ECPG_COMPAT_PGSQL))
     465                 :             :                     {
     466                 :           0 :                         ecpg_raise(lineno, ECPG_FLOAT_FORMAT,
     467                 :             :                                    ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     468                 :           0 :                         return false;
     469                 :             :                     }
     470                 :          90 :                     pval = scan_length;
     471                 :             : 
     472      [ +  +  - ]:          90 :                     switch (type)
     473                 :             :                     {
     474                 :          14 :                         case ECPGt_float:
     475                 :          14 :                             *((float *) (var + offset * act_tuple)) = dres;
     476                 :          14 :                             break;
     477                 :          76 :                         case ECPGt_double:
     478                 :          76 :                             *((double *) (var + offset * act_tuple)) = dres;
     479                 :          76 :                             break;
     480                 :           0 :                         default:
     481                 :             :                             /* Cannot happen */
     482                 :           0 :                             break;
     483                 :             :                     }
     484                 :          90 :                     break;
     485                 :             : 
     486                 :          24 :                 case ECPGt_bool:
     487   [ +  +  +  - ]:          24 :                     if (pval[0] == 'f' && pval[1] == '\0')
     488                 :             :                     {
     489                 :          10 :                         *((bool *) (var + offset * act_tuple)) = false;
     490                 :          10 :                         pval++;
     491                 :          10 :                         break;
     492                 :             :                     }
     493   [ +  -  +  - ]:          14 :                     else if (pval[0] == 't' && pval[1] == '\0')
     494                 :             :                     {
     495                 :          14 :                         *((bool *) (var + offset * act_tuple)) = true;
     496                 :          14 :                         pval++;
     497                 :          14 :                         break;
     498                 :             :                     }
     499   [ #  #  #  # ]:           0 :                     else if (pval[0] == '\0' && PQgetisnull(results, act_tuple, act_field))
     500                 :             :                     {
     501                 :             :                         /* NULL is valid */
     502                 :           0 :                         break;
     503                 :             :                     }
     504                 :             : 
     505                 :           0 :                     ecpg_raise(lineno, ECPG_CONVERT_BOOL,
     506                 :             :                                ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     507                 :           0 :                     return false;
     508                 :             :                     break;
     509                 :             : 
     510                 :          18 :                 case ECPGt_bytea:
     511                 :             :                     {
     512                 :          18 :                         struct ECPGgeneric_bytea *variable =
     513                 :          18 :                             (struct ECPGgeneric_bytea *) (var + offset * act_tuple);
     514                 :             :                         long        dst_size,
     515                 :             :                                     src_size,
     516                 :             :                                     dec_size;
     517                 :             : 
     518                 :          18 :                         dst_size = ecpg_hex_enc_len(varcharsize);
     519                 :          18 :                         src_size = size - 2;    /* exclude backslash + 'x' */
     520                 :          18 :                         dec_size = src_size < dst_size ? src_size : dst_size;
     521                 :          18 :                         variable->len = hex_decode(pval + 2, dec_size, variable->arr);
     522                 :             : 
     523         [ +  + ]:          18 :                         if (dst_size < src_size)
     524                 :             :                         {
     525                 :           6 :                             long        rcv_size = ecpg_hex_dec_len(size - 2);
     526                 :             : 
     527                 :             :                             /* truncation */
     528   [ -  +  -  -  :           6 :                             switch (ind_type)
                      - ]
     529                 :             :                             {
     530                 :           0 :                                 case ECPGt_short:
     531                 :             :                                 case ECPGt_unsigned_short:
     532                 :           0 :                                     *((short *) (ind + ind_offset * act_tuple)) = rcv_size;
     533                 :           0 :                                     break;
     534                 :           6 :                                 case ECPGt_int:
     535                 :             :                                 case ECPGt_unsigned_int:
     536                 :           6 :                                     *((int *) (ind + ind_offset * act_tuple)) = rcv_size;
     537                 :           6 :                                     break;
     538                 :           0 :                                 case ECPGt_long:
     539                 :             :                                 case ECPGt_unsigned_long:
     540                 :           0 :                                     *((long *) (ind + ind_offset * act_tuple)) = rcv_size;
     541                 :           0 :                                     break;
     542                 :           0 :                                 case ECPGt_long_long:
     543                 :             :                                 case ECPGt_unsigned_long_long:
     544                 :           0 :                                     *((long long int *) (ind + ind_offset * act_tuple)) = rcv_size;
     545                 :           0 :                                     break;
     546                 :           0 :                                 default:
     547                 :           0 :                                     break;
     548                 :             :                             }
     549                 :           6 :                             sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
     550                 :             :                         }
     551                 :             : 
     552                 :          18 :                         pval += size;
     553                 :             :                     }
     554                 :          18 :                     break;
     555                 :             : 
     556                 :        2082 :                 case ECPGt_char:
     557                 :             :                 case ECPGt_unsigned_char:
     558                 :             :                 case ECPGt_string:
     559                 :             :                     {
     560                 :        2082 :                         char       *str = (char *) (var + offset * act_tuple);
     561                 :             : 
     562                 :             :                         /*
     563                 :             :                          * If varcharsize is unknown and the offset is that of
     564                 :             :                          * char *, then this variable represents the array of
     565                 :             :                          * character pointers. So, use extra indirection.
     566                 :             :                          */
     567   [ +  +  -  + ]:        2082 :                         if (varcharsize == 0 && offset == sizeof(char *))
     568                 :           0 :                             str = *(char **) str;
     569                 :             : 
     570         [ +  + ]:        2082 :                         if (varcharsize > size)
     571                 :             :                         {
     572                 :             :                             /*
     573                 :             :                              * compatibility mode, blank pad and null
     574                 :             :                              * terminate char array
     575                 :             :                              */
     576   [ +  +  -  +  :        1918 :                             if (ORACLE_MODE(compat) && (type == ECPGt_char || type == ECPGt_unsigned_char))
                   -  - ]
     577                 :             :                             {
     578                 :          18 :                                 memset(str, ' ', varcharsize);
     579                 :          18 :                                 memcpy(str, pval, size);
     580                 :          18 :                                 str[varcharsize - 1] = '\0';
     581                 :             : 
     582                 :             :                                 /*
     583                 :             :                                  * compatibility mode empty string gets -1
     584                 :             :                                  * indicator but no warning
     585                 :             :                                  */
     586         [ +  + ]:          18 :                                 if (size == 0)
     587                 :             :                                 {
     588                 :             :                                     /* truncation */
     589   [ +  -  -  -  :           4 :                                     switch (ind_type)
                      - ]
     590                 :             :                                     {
     591                 :           4 :                                         case ECPGt_short:
     592                 :             :                                         case ECPGt_unsigned_short:
     593                 :           4 :                                             *((short *) (ind + ind_offset * act_tuple)) = -1;
     594                 :           4 :                                             break;
     595                 :           0 :                                         case ECPGt_int:
     596                 :             :                                         case ECPGt_unsigned_int:
     597                 :           0 :                                             *((int *) (ind + ind_offset * act_tuple)) = -1;
     598                 :           0 :                                             break;
     599                 :           0 :                                         case ECPGt_long:
     600                 :             :                                         case ECPGt_unsigned_long:
     601                 :           0 :                                             *((long *) (ind + ind_offset * act_tuple)) = -1;
     602                 :           0 :                                             break;
     603                 :           0 :                                         case ECPGt_long_long:
     604                 :             :                                         case ECPGt_unsigned_long_long:
     605                 :           0 :                                             *((long long int *) (ind + ind_offset * act_tuple)) = -1;
     606                 :           0 :                                             break;
     607                 :           0 :                                         default:
     608                 :           0 :                                             break;
     609                 :             :                                     }
     610                 :             :                                 }
     611                 :             :                             }
     612                 :             :                             else
     613                 :             :                             {
     614                 :        1900 :                                 strncpy(str, pval, size + 1);
     615                 :             :                             }
     616                 :             :                             /* do the rtrim() */
     617         [ +  + ]:        1918 :                             if (type == ECPGt_string)
     618                 :             :                             {
     619                 :           4 :                                 char       *last = str + size;
     620                 :             : 
     621   [ +  +  +  +  :          26 :                                 while (last > str && (*last == ' ' || *last == '\0'))
                   +  + ]
     622                 :             :                                 {
     623                 :          22 :                                     *last = '\0';
     624                 :          22 :                                     last--;
     625                 :             :                                 }
     626                 :             :                             }
     627                 :             :                         }
     628                 :             :                         else
     629                 :             :                         {
     630                 :         164 :                             int         charsize = varcharsize;
     631                 :             : 
     632                 :             :                             /*
     633                 :             :                              * assume that the caller provided storage exactly
     634                 :             :                              * fit when varcharsize is zero.
     635                 :             :                              */
     636         [ +  + ]:         164 :                             if (varcharsize == 0)
     637                 :          68 :                                 charsize = size + 1;
     638                 :             : 
     639                 :         164 :                             strncpy(str, pval, charsize);
     640                 :             : 
     641                 :             :                             /* compatibility mode, null terminate char array */
     642   [ +  +  +  + ]:         164 :                             if (ORACLE_MODE(compat) && (charsize - 1) < size)
     643                 :             :                             {
     644   [ -  +  -  - ]:           6 :                                 if (type == ECPGt_char || type == ECPGt_unsigned_char)
     645                 :           6 :                                     str[charsize - 1] = '\0';
     646                 :             :                             }
     647                 :             : 
     648   [ +  +  +  +  :         164 :                             if (charsize < size || (ORACLE_MODE(compat) && (charsize - 1) < size))
                   +  + ]
     649                 :             :                             {
     650                 :             :                                 /* truncation */
     651   [ +  +  -  -  :          12 :                                 switch (ind_type)
                      + ]
     652                 :             :                                 {
     653                 :           6 :                                     case ECPGt_short:
     654                 :             :                                     case ECPGt_unsigned_short:
     655                 :           6 :                                         *((short *) (ind + ind_offset * act_tuple)) = size;
     656                 :           6 :                                         break;
     657                 :           2 :                                     case ECPGt_int:
     658                 :             :                                     case ECPGt_unsigned_int:
     659                 :           2 :                                         *((int *) (ind + ind_offset * act_tuple)) = size;
     660                 :           2 :                                         break;
     661                 :           0 :                                     case ECPGt_long:
     662                 :             :                                     case ECPGt_unsigned_long:
     663                 :           0 :                                         *((long *) (ind + ind_offset * act_tuple)) = size;
     664                 :           0 :                                         break;
     665                 :           0 :                                     case ECPGt_long_long:
     666                 :             :                                     case ECPGt_unsigned_long_long:
     667                 :           0 :                                         *((long long int *) (ind + ind_offset * act_tuple)) = size;
     668                 :           0 :                                         break;
     669                 :           4 :                                     default:
     670                 :           4 :                                         break;
     671                 :             :                                 }
     672                 :          12 :                                 sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
     673                 :             :                             }
     674                 :             :                         }
     675                 :        2082 :                         pval += size;
     676                 :             :                     }
     677                 :        2082 :                     break;
     678                 :             : 
     679                 :          44 :                 case ECPGt_varchar:
     680                 :             :                     {
     681                 :          44 :                         struct ECPGgeneric_varchar *variable =
     682                 :          44 :                             (struct ECPGgeneric_varchar *) (var + offset * act_tuple);
     683                 :             : 
     684                 :          44 :                         variable->len = size;
     685         [ -  + ]:          44 :                         if (varcharsize == 0)
     686                 :           0 :                             strncpy(variable->arr, pval, variable->len);
     687                 :             :                         else
     688                 :             :                         {
     689                 :          44 :                             strncpy(variable->arr, pval, varcharsize);
     690                 :             : 
     691         [ -  + ]:          44 :                             if (variable->len > varcharsize)
     692                 :             :                             {
     693                 :             :                                 /* truncation */
     694   [ #  #  #  #  :           0 :                                 switch (ind_type)
                      # ]
     695                 :             :                                 {
     696                 :           0 :                                     case ECPGt_short:
     697                 :             :                                     case ECPGt_unsigned_short:
     698                 :           0 :                                         *((short *) (ind + ind_offset * act_tuple)) = variable->len;
     699                 :           0 :                                         break;
     700                 :           0 :                                     case ECPGt_int:
     701                 :             :                                     case ECPGt_unsigned_int:
     702                 :           0 :                                         *((int *) (ind + ind_offset * act_tuple)) = variable->len;
     703                 :           0 :                                         break;
     704                 :           0 :                                     case ECPGt_long:
     705                 :             :                                     case ECPGt_unsigned_long:
     706                 :           0 :                                         *((long *) (ind + ind_offset * act_tuple)) = variable->len;
     707                 :           0 :                                         break;
     708                 :           0 :                                     case ECPGt_long_long:
     709                 :             :                                     case ECPGt_unsigned_long_long:
     710                 :           0 :                                         *((long long int *) (ind + ind_offset * act_tuple)) = variable->len;
     711                 :           0 :                                         break;
     712                 :           0 :                                     default:
     713                 :           0 :                                         break;
     714                 :             :                                 }
     715                 :           0 :                                 sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W';
     716                 :             : 
     717                 :           0 :                                 variable->len = varcharsize;
     718                 :             :                             }
     719                 :             :                         }
     720                 :          44 :                         pval += size;
     721                 :             :                     }
     722                 :          44 :                     break;
     723                 :             : 
     724                 :          46 :                 case ECPGt_decimal:
     725                 :             :                 case ECPGt_numeric:
     726   [ +  +  +  +  :         194 :                     for (endptr = pval; *endptr && *endptr != ',' && *endptr != '}'; endptr++);
                   +  + ]
     727                 :          46 :                     endchar = *endptr;
     728                 :          46 :                     *endptr = '\0';
     729                 :          46 :                     nres = PGTYPESnumeric_from_asc(pval, &scan_length);
     730                 :          46 :                     *endptr = endchar;
     731                 :             : 
     732                 :             :                     /* did we get an error? */
     733         [ -  + ]:          46 :                     if (nres == NULL)
     734                 :             :                     {
     735                 :           0 :                         ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
     736                 :           0 :                                  lineno, pval, errno);
     737                 :             : 
     738   [ #  #  #  # ]:           0 :                         if (INFORMIX_MODE(compat))
     739                 :             :                         {
     740                 :             :                             /*
     741                 :             :                              * Informix wants its own NULL value here instead
     742                 :             :                              * of an error
     743                 :             :                              */
     744                 :           0 :                             nres = PGTYPESnumeric_new();
     745         [ #  # ]:           0 :                             if (nres)
     746                 :           0 :                                 ECPGset_noind_null(ECPGt_numeric, nres);
     747                 :             :                             else
     748                 :             :                             {
     749                 :           0 :                                 ecpg_raise(lineno, ECPG_OUT_OF_MEMORY,
     750                 :             :                                            ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
     751                 :           0 :                                 return false;
     752                 :             :                             }
     753                 :             :                         }
     754                 :             :                         else
     755                 :             :                         {
     756                 :           0 :                             ecpg_raise(lineno, ECPG_NUMERIC_FORMAT,
     757                 :             :                                        ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     758                 :           0 :                             return false;
     759                 :             :                         }
     760                 :             :                     }
     761                 :             :                     else
     762                 :             :                     {
     763   [ -  +  -  - ]:          46 :                         if (!isarray && garbage_left(isarray, &scan_length, compat))
     764                 :             :                         {
     765                 :           0 :                             free(nres);
     766                 :           0 :                             ecpg_raise(lineno, ECPG_NUMERIC_FORMAT,
     767                 :             :                                        ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     768                 :           0 :                             return false;
     769                 :             :                         }
     770                 :             :                     }
     771                 :          46 :                     pval = scan_length;
     772                 :             : 
     773         [ +  + ]:          46 :                     if (type == ECPGt_numeric)
     774                 :          30 :                         PGTYPESnumeric_copy(nres, (numeric *) (var + offset * act_tuple));
     775                 :             :                     else
     776                 :          16 :                         PGTYPESnumeric_to_decimal(nres, (decimal *) (var + offset * act_tuple));
     777                 :             : 
     778                 :          46 :                     PGTYPESnumeric_free(nres);
     779                 :          46 :                     break;
     780                 :             : 
     781                 :          20 :                 case ECPGt_interval:
     782         [ +  - ]:          20 :                     if (*pval == '"')
     783                 :          20 :                         pval++;
     784                 :             : 
     785   [ +  -  +  -  :         220 :                     for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
             +  +  +  - ]
     786                 :          20 :                     endchar = *endptr;
     787                 :          20 :                     *endptr = '\0';
     788                 :          20 :                     ires = PGTYPESinterval_from_asc(pval, &scan_length);
     789                 :          20 :                     *endptr = endchar;
     790                 :             : 
     791                 :             :                     /* did we get an error? */
     792         [ -  + ]:          20 :                     if (ires == NULL)
     793                 :             :                     {
     794                 :           0 :                         ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
     795                 :           0 :                                  lineno, pval, errno);
     796                 :             : 
     797   [ #  #  #  # ]:           0 :                         if (INFORMIX_MODE(compat))
     798                 :             :                         {
     799                 :             :                             /*
     800                 :             :                              * Informix wants its own NULL value here instead
     801                 :             :                              * of an error
     802                 :             :                              */
     803                 :           0 :                             ires = (interval *) ecpg_alloc(sizeof(interval), lineno);
     804         [ #  # ]:           0 :                             if (!ires)
     805                 :           0 :                                 return false;
     806                 :             : 
     807                 :           0 :                             ECPGset_noind_null(ECPGt_interval, ires);
     808                 :             :                         }
     809                 :             :                         else
     810                 :             :                         {
     811                 :           0 :                             ecpg_raise(lineno, ECPG_INTERVAL_FORMAT,
     812                 :             :                                        ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     813                 :           0 :                             return false;
     814                 :             :                         }
     815                 :             :                     }
     816                 :             :                     else
     817                 :             :                     {
     818         [ +  - ]:          20 :                         if (*scan_length == '"')
     819                 :          20 :                             scan_length++;
     820                 :             : 
     821   [ -  +  -  - ]:          20 :                         if (!isarray && garbage_left(isarray, &scan_length, compat))
     822                 :             :                         {
     823                 :           0 :                             free(ires);
     824                 :           0 :                             ecpg_raise(lineno, ECPG_INTERVAL_FORMAT,
     825                 :             :                                        ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     826                 :           0 :                             return false;
     827                 :             :                         }
     828                 :             :                     }
     829                 :          20 :                     pval = scan_length;
     830                 :             : 
     831                 :          20 :                     PGTYPESinterval_copy(ires, (interval *) (var + offset * act_tuple));
     832                 :          20 :                     free(ires);
     833                 :          20 :                     break;
     834                 :             : 
     835                 :          22 :                 case ECPGt_date:
     836         [ -  + ]:          22 :                     if (*pval == '"')
     837                 :           0 :                         pval++;
     838                 :             : 
     839   [ +  +  +  +  :         242 :                     for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
             +  -  +  + ]
     840                 :          22 :                     endchar = *endptr;
     841                 :          22 :                     *endptr = '\0';
     842                 :          22 :                     ddres = PGTYPESdate_from_asc(pval, &scan_length);
     843                 :          22 :                     *endptr = endchar;
     844                 :             : 
     845                 :             :                     /* did we get an error? */
     846         [ -  + ]:          22 :                     if (errno != 0)
     847                 :             :                     {
     848                 :           0 :                         ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
     849                 :           0 :                                  lineno, pval, errno);
     850                 :             : 
     851   [ #  #  #  # ]:           0 :                         if (INFORMIX_MODE(compat))
     852                 :             :                         {
     853                 :             :                             /*
     854                 :             :                              * Informix wants its own NULL value here instead
     855                 :             :                              * of an error
     856                 :             :                              */
     857                 :           0 :                             ECPGset_noind_null(ECPGt_date, &ddres);
     858                 :             :                         }
     859                 :             :                         else
     860                 :             :                         {
     861                 :           0 :                             ecpg_raise(lineno, ECPG_DATE_FORMAT,
     862                 :             :                                        ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     863                 :           0 :                             return false;
     864                 :             :                         }
     865                 :             :                     }
     866                 :             :                     else
     867                 :             :                     {
     868         [ -  + ]:          22 :                         if (*scan_length == '"')
     869                 :           0 :                             scan_length++;
     870                 :             : 
     871   [ -  +  -  - ]:          22 :                         if (!isarray && garbage_left(isarray, &scan_length, compat))
     872                 :             :                         {
     873                 :           0 :                             ecpg_raise(lineno, ECPG_DATE_FORMAT,
     874                 :             :                                        ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     875                 :           0 :                             return false;
     876                 :             :                         }
     877                 :             :                     }
     878                 :             : 
     879                 :          22 :                     *((date *) (var + offset * act_tuple)) = ddres;
     880                 :          22 :                     pval = scan_length;
     881                 :          22 :                     break;
     882                 :             : 
     883                 :          26 :                 case ECPGt_timestamp:
     884         [ +  + ]:          26 :                     if (*pval == '"')
     885                 :          20 :                         pval++;
     886                 :             : 
     887   [ +  +  +  -  :         640 :                     for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
             +  +  +  - ]
     888                 :          26 :                     endchar = *endptr;
     889                 :          26 :                     *endptr = '\0';
     890                 :          26 :                     tres = PGTYPEStimestamp_from_asc(pval, &scan_length);
     891                 :          26 :                     *endptr = endchar;
     892                 :             : 
     893                 :             :                     /* did we get an error? */
     894         [ -  + ]:          26 :                     if (errno != 0)
     895                 :             :                     {
     896                 :           0 :                         ecpg_log("ecpg_get_data on line %d: RESULT %s; errno %d\n",
     897                 :           0 :                                  lineno, pval, errno);
     898                 :             : 
     899   [ #  #  #  # ]:           0 :                         if (INFORMIX_MODE(compat))
     900                 :             :                         {
     901                 :             :                             /*
     902                 :             :                              * Informix wants its own NULL value here instead
     903                 :             :                              * of an error
     904                 :             :                              */
     905                 :           0 :                             ECPGset_noind_null(ECPGt_timestamp, &tres);
     906                 :             :                         }
     907                 :             :                         else
     908                 :             :                         {
     909                 :           0 :                             ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT,
     910                 :             :                                        ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     911                 :           0 :                             return false;
     912                 :             :                         }
     913                 :             :                     }
     914                 :             :                     else
     915                 :             :                     {
     916         [ +  + ]:          26 :                         if (*scan_length == '"')
     917                 :          20 :                             scan_length++;
     918                 :             : 
     919   [ -  +  -  - ]:          26 :                         if (!isarray && garbage_left(isarray, &scan_length, compat))
     920                 :             :                         {
     921                 :           0 :                             ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT,
     922                 :             :                                        ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
     923                 :           0 :                             return false;
     924                 :             :                         }
     925                 :             :                     }
     926                 :             : 
     927                 :          26 :                     *((timestamp *) (var + offset * act_tuple)) = tres;
     928                 :          26 :                     pval = scan_length;
     929                 :          26 :                     break;
     930                 :             : 
     931                 :           0 :                 default:
     932                 :           0 :                     ecpg_raise(lineno, ECPG_UNSUPPORTED,
     933                 :             :                                ECPG_SQLSTATE_ECPG_INTERNAL_ERROR,
     934                 :             :                                ecpg_type_name(type));
     935                 :           0 :                     return false;
     936                 :             :                     break;
     937                 :             :             }
     938   [ +  +  -  + ]:        2868 :             if (ECPG_IS_ARRAY(isarray))
     939                 :             :             {
     940                 :         102 :                 bool        string = false;
     941                 :             : 
     942                 :             :                 /* set array to next entry */
     943                 :         102 :                 ++act_tuple;
     944                 :             : 
     945                 :             :                 /* set pval to the next entry */
     946                 :             : 
     947                 :             :                 /*
     948                 :             :                  * *pval != '\0' should not be needed, but is used as a safety
     949                 :             :                  * guard
     950                 :             :                  */
     951   [ +  +  -  +  :         102 :                 for (; *pval != '\0' && (string || (!array_delimiter(isarray, *pval) && !array_boundary(isarray, *pval))); ++pval)
             +  +  -  + ]
     952         [ #  # ]:           0 :                     if (*pval == '"')
     953                 :           0 :                         string = string ? false : true;
     954                 :             : 
     955         [ +  + ]:         102 :                 if (array_delimiter(isarray, *pval))
     956                 :          90 :                     ++pval;
     957                 :             :             }
     958                 :             :         }
     959   [ +  +  +  + ]:        2876 :     } while (*pval != '\0' && !array_boundary(isarray, *pval));
     960                 :             : 
     961                 :        2786 :     return true;
     962                 :             : }
        

Generated by: LCOV version 2.0-1