LCOV - code coverage report
Current view: top level - src/interfaces/ecpg/compatlib - informix.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 68.5 % 504 345
Test Date: 2026-07-12 22:15:32 Functions: 61.7 % 47 29
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 66.9 % 254 170

             Branch data     Line data    Source code
       1                 :             : /* src/interfaces/ecpg/compatlib/informix.c */
       2                 :             : 
       3                 :             : #define POSTGRES_ECPG_INTERNAL
       4                 :             : #include "postgres_fe.h"
       5                 :             : 
       6                 :             : #include <math.h>
       7                 :             : #include <ctype.h>
       8                 :             : #include <limits.h>
       9                 :             : 
      10                 :             : #include "ecpg_informix.h"
      11                 :             : #include "ecpgerrno.h"
      12                 :             : #include "ecpgtype.h"
      13                 :             : #include "pgtypes_date.h"
      14                 :             : #include "pgtypes_error.h"
      15                 :             : #include "pgtypes_numeric.h"
      16                 :             : #include "sqlca.h"
      17                 :             : #include "sqltypes.h"
      18                 :             : 
      19                 :             : /* this is also defined in ecpglib/misc.c, by defining it twice we don't have to export the symbol */
      20                 :             : 
      21                 :             : static struct sqlca_t sqlca_init =
      22                 :             : {
      23                 :             :     {
      24                 :             :         'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
      25                 :             :     },
      26                 :             :     sizeof(struct sqlca_t),
      27                 :             :     0,
      28                 :             :     {
      29                 :             :         0,
      30                 :             :         {
      31                 :             :             0
      32                 :             :         }
      33                 :             :     },
      34                 :             :     {
      35                 :             :         'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
      36                 :             :     },
      37                 :             :     {
      38                 :             :         0, 0, 0, 0, 0, 0
      39                 :             :     },
      40                 :             :     {
      41                 :             :         0, 0, 0, 0, 0, 0, 0, 0
      42                 :             :     },
      43                 :             :     {
      44                 :             :         '0', '0', '0', '0', '0'
      45                 :             :     }
      46                 :             : };
      47                 :             : static int
      48                 :         494 : deccall2(decimal *arg1, decimal *arg2, int (*ptr) (numeric *, numeric *))
      49                 :             : {
      50                 :             :     numeric    *a1,
      51                 :             :                *a2;
      52                 :             :     int         i;
      53                 :             : 
      54         [ -  + ]:         494 :     if ((a1 = PGTYPESnumeric_new()) == NULL)
      55                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
      56                 :             : 
      57         [ -  + ]:         494 :     if ((a2 = PGTYPESnumeric_new()) == NULL)
      58                 :             :     {
      59                 :           0 :         PGTYPESnumeric_free(a1);
      60                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
      61                 :             :     }
      62                 :             : 
      63         [ -  + ]:         494 :     if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
      64                 :             :     {
      65                 :           0 :         PGTYPESnumeric_free(a1);
      66                 :           0 :         PGTYPESnumeric_free(a2);
      67                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
      68                 :             :     }
      69                 :             : 
      70         [ -  + ]:         494 :     if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
      71                 :             :     {
      72                 :           0 :         PGTYPESnumeric_free(a1);
      73                 :           0 :         PGTYPESnumeric_free(a2);
      74                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
      75                 :             :     }
      76                 :             : 
      77                 :         494 :     i = (*ptr) (a1, a2);
      78                 :             : 
      79                 :         494 :     PGTYPESnumeric_free(a1);
      80                 :         494 :     PGTYPESnumeric_free(a2);
      81                 :             : 
      82                 :         494 :     return i;
      83                 :             : }
      84                 :             : 
      85                 :             : static int
      86                 :        1802 : deccall3(decimal *arg1, decimal *arg2, decimal *result, int (*ptr) (numeric *, numeric *, numeric *))
      87                 :             : {
      88                 :             :     numeric    *a1,
      89                 :             :                *a2,
      90                 :             :                *nres;
      91                 :             :     int         i;
      92                 :             : 
      93                 :             :     /*
      94                 :             :      * we must NOT set the result to NULL here because it may be the same
      95                 :             :      * variable as one of the arguments
      96                 :             :      */
      97   [ +  +  +  + ]:        1802 :     if (risnull(CDECIMALTYPE, (char *) arg1) || risnull(CDECIMALTYPE, (char *) arg2))
      98                 :         232 :         return 0;
      99                 :             : 
     100         [ -  + ]:        1570 :     if ((a1 = PGTYPESnumeric_new()) == NULL)
     101                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     102                 :             : 
     103         [ -  + ]:        1570 :     if ((a2 = PGTYPESnumeric_new()) == NULL)
     104                 :             :     {
     105                 :           0 :         PGTYPESnumeric_free(a1);
     106                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     107                 :             :     }
     108                 :             : 
     109         [ -  + ]:        1570 :     if ((nres = PGTYPESnumeric_new()) == NULL)
     110                 :             :     {
     111                 :           0 :         PGTYPESnumeric_free(a1);
     112                 :           0 :         PGTYPESnumeric_free(a2);
     113                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     114                 :             :     }
     115                 :             : 
     116         [ -  + ]:        1570 :     if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
     117                 :             :     {
     118                 :           0 :         PGTYPESnumeric_free(a1);
     119                 :           0 :         PGTYPESnumeric_free(a2);
     120                 :           0 :         PGTYPESnumeric_free(nres);
     121                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     122                 :             :     }
     123                 :             : 
     124         [ -  + ]:        1570 :     if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
     125                 :             :     {
     126                 :           0 :         PGTYPESnumeric_free(a1);
     127                 :           0 :         PGTYPESnumeric_free(a2);
     128                 :           0 :         PGTYPESnumeric_free(nres);
     129                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     130                 :             :     }
     131                 :             : 
     132                 :        1570 :     i = (*ptr) (a1, a2, nres);
     133                 :             : 
     134         [ +  + ]:        1570 :     if (i == 0)                 /* No error */
     135                 :             :     {
     136                 :             : 
     137                 :             :         /* set the result to null in case it errors out later */
     138                 :        1542 :         rsetnull(CDECIMALTYPE, (char *) result);
     139                 :        1542 :         PGTYPESnumeric_to_decimal(nres, result);
     140                 :             :     }
     141                 :             : 
     142                 :        1570 :     PGTYPESnumeric_free(nres);
     143                 :        1570 :     PGTYPESnumeric_free(a1);
     144                 :        1570 :     PGTYPESnumeric_free(a2);
     145                 :             : 
     146                 :        1570 :     return i;
     147                 :             : }
     148                 :             : 
     149                 :             : /* we start with the numeric functions */
     150                 :             : int
     151                 :         452 : decadd(decimal *arg1, decimal *arg2, decimal *sum)
     152                 :             : {
     153                 :         452 :     errno = 0;
     154                 :         452 :     deccall3(arg1, arg2, sum, PGTYPESnumeric_add);
     155                 :             : 
     156         [ +  + ]:         452 :     if (errno == PGTYPES_NUM_OVERFLOW)
     157                 :         124 :         return ECPG_INFORMIX_NUM_OVERFLOW;
     158         [ -  + ]:         328 :     else if (errno == PGTYPES_NUM_UNDERFLOW)
     159                 :           0 :         return ECPG_INFORMIX_NUM_UNDERFLOW;
     160         [ -  + ]:         328 :     else if (errno != 0)
     161                 :           0 :         return -1;
     162                 :             :     else
     163                 :         328 :         return 0;
     164                 :             : }
     165                 :             : 
     166                 :             : int
     167                 :         494 : deccmp(decimal *arg1, decimal *arg2)
     168                 :             : {
     169                 :         494 :     return deccall2(arg1, arg2, PGTYPESnumeric_cmp);
     170                 :             : }
     171                 :             : 
     172                 :             : void
     173                 :           0 : deccopy(decimal *src, decimal *target)
     174                 :             : {
     175                 :           0 :     memcpy(target, src, sizeof(decimal));
     176                 :           0 : }
     177                 :             : 
     178                 :             : static char *
     179                 :          32 : ecpg_strndup(const char *str, size_t len)
     180                 :             : {
     181                 :          32 :     size_t      real_len = strlen(str);
     182         [ -  + ]:          32 :     int         use_len = (int) ((real_len > len) ? len : real_len);
     183                 :             : 
     184                 :          32 :     char       *new = malloc(use_len + 1);
     185                 :             : 
     186         [ +  - ]:          32 :     if (new)
     187                 :             :     {
     188                 :          32 :         memcpy(new, str, use_len);
     189                 :          32 :         new[use_len] = '\0';
     190                 :             :     }
     191                 :             :     else
     192                 :           0 :         errno = ENOMEM;
     193                 :             : 
     194                 :          32 :     return new;
     195                 :             : }
     196                 :             : 
     197                 :             : int
     198                 :          32 : deccvasc(const char *cp, int len, decimal *np)
     199                 :             : {
     200                 :             :     char       *str;
     201                 :          32 :     int         ret = 0;
     202                 :             :     numeric    *result;
     203                 :             : 
     204                 :          32 :     rsetnull(CDECIMALTYPE, (char *) np);
     205         [ -  + ]:          32 :     if (risnull(CSTRINGTYPE, cp))
     206                 :           0 :         return 0;
     207                 :             : 
     208                 :          32 :     str = ecpg_strndup(cp, len);    /* decimal_in always converts the complete
     209                 :             :                                      * string */
     210         [ -  + ]:          32 :     if (!str)
     211                 :           0 :         ret = ECPG_INFORMIX_NUM_UNDERFLOW;
     212                 :             :     else
     213                 :             :     {
     214                 :          32 :         errno = 0;
     215                 :          32 :         result = PGTYPESnumeric_from_asc(str, NULL);
     216         [ +  + ]:          32 :         if (!result)
     217                 :             :         {
     218      [ -  +  - ]:           2 :             switch (errno)
     219                 :             :             {
     220                 :           0 :                 case PGTYPES_NUM_OVERFLOW:
     221                 :           0 :                     ret = ECPG_INFORMIX_NUM_OVERFLOW;
     222                 :           0 :                     break;
     223                 :           2 :                 case PGTYPES_NUM_BAD_NUMERIC:
     224                 :           2 :                     ret = ECPG_INFORMIX_BAD_NUMERIC;
     225                 :           2 :                     break;
     226                 :           0 :                 default:
     227                 :           0 :                     ret = ECPG_INFORMIX_BAD_EXPONENT;
     228                 :           0 :                     break;
     229                 :             :             }
     230                 :             :         }
     231                 :             :         else
     232                 :             :         {
     233                 :          30 :             int         i = PGTYPESnumeric_to_decimal(result, np);
     234                 :             : 
     235                 :          30 :             PGTYPESnumeric_free(result);
     236         [ +  + ]:          30 :             if (i != 0)
     237                 :           2 :                 ret = ECPG_INFORMIX_NUM_OVERFLOW;
     238                 :             :         }
     239                 :             :     }
     240                 :             : 
     241                 :          32 :     free(str);
     242                 :          32 :     return ret;
     243                 :             : }
     244                 :             : 
     245                 :             : int
     246                 :           0 : deccvdbl(double dbl, decimal *np)
     247                 :             : {
     248                 :             :     numeric    *nres;
     249                 :           0 :     int         result = 1;
     250                 :             : 
     251                 :           0 :     rsetnull(CDECIMALTYPE, (char *) np);
     252         [ #  # ]:           0 :     if (risnull(CDOUBLETYPE, (char *) &dbl))
     253                 :           0 :         return 0;
     254                 :             : 
     255                 :           0 :     nres = PGTYPESnumeric_new();
     256         [ #  # ]:           0 :     if (nres == NULL)
     257                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     258                 :             : 
     259                 :           0 :     result = PGTYPESnumeric_from_double(dbl, nres);
     260         [ #  # ]:           0 :     if (result == 0)
     261                 :           0 :         result = PGTYPESnumeric_to_decimal(nres, np);
     262                 :             : 
     263                 :           0 :     PGTYPESnumeric_free(nres);
     264                 :           0 :     return result;
     265                 :             : }
     266                 :             : 
     267                 :             : int
     268                 :        1828 : deccvint(int in, decimal *np)
     269                 :             : {
     270                 :             :     numeric    *nres;
     271                 :        1828 :     int         result = 1;
     272                 :             : 
     273                 :        1828 :     rsetnull(CDECIMALTYPE, (char *) np);
     274         [ -  + ]:        1828 :     if (risnull(CINTTYPE, (char *) &in))
     275                 :           0 :         return 0;
     276                 :             : 
     277                 :        1828 :     nres = PGTYPESnumeric_new();
     278         [ -  + ]:        1828 :     if (nres == NULL)
     279                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     280                 :             : 
     281                 :        1828 :     result = PGTYPESnumeric_from_int(in, nres);
     282         [ +  - ]:        1828 :     if (result == 0)
     283                 :        1828 :         result = PGTYPESnumeric_to_decimal(nres, np);
     284                 :             : 
     285                 :        1828 :     PGTYPESnumeric_free(nres);
     286                 :        1828 :     return result;
     287                 :             : }
     288                 :             : 
     289                 :             : int
     290                 :          22 : deccvlong(long lng, decimal *np)
     291                 :             : {
     292                 :             :     numeric    *nres;
     293                 :          22 :     int         result = 1;
     294                 :             : 
     295                 :          22 :     rsetnull(CDECIMALTYPE, (char *) np);
     296         [ -  + ]:          22 :     if (risnull(CLONGTYPE, (char *) &lng))
     297                 :           0 :         return 0;
     298                 :             : 
     299                 :          22 :     nres = PGTYPESnumeric_new();
     300         [ -  + ]:          22 :     if (nres == NULL)
     301                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     302                 :             : 
     303                 :          22 :     result = PGTYPESnumeric_from_long(lng, nres);
     304         [ +  - ]:          22 :     if (result == 0)
     305                 :          22 :         result = PGTYPESnumeric_to_decimal(nres, np);
     306                 :             : 
     307                 :          22 :     PGTYPESnumeric_free(nres);
     308                 :          22 :     return result;
     309                 :             : }
     310                 :             : 
     311                 :             : int
     312                 :         450 : decdiv(decimal *n1, decimal *n2, decimal *result)
     313                 :             : {
     314                 :             :     int         i;
     315                 :             : 
     316                 :         450 :     errno = 0;
     317                 :         450 :     i = deccall3(n1, n2, result, PGTYPESnumeric_div);
     318                 :             : 
     319         [ +  + ]:         450 :     if (i != 0)
     320      [ +  -  - ]:          28 :         switch (errno)
     321                 :             :         {
     322                 :          28 :             case PGTYPES_NUM_DIVIDE_ZERO:
     323                 :          28 :                 return ECPG_INFORMIX_DIVIDE_ZERO;
     324                 :             :                 break;
     325                 :           0 :             case PGTYPES_NUM_OVERFLOW:
     326                 :           0 :                 return ECPG_INFORMIX_NUM_OVERFLOW;
     327                 :             :                 break;
     328                 :           0 :             default:
     329                 :           0 :                 return ECPG_INFORMIX_NUM_UNDERFLOW;
     330                 :             :                 break;
     331                 :             :         }
     332                 :             : 
     333                 :         422 :     return 0;
     334                 :             : }
     335                 :             : 
     336                 :             : int
     337                 :         450 : decmul(decimal *n1, decimal *n2, decimal *result)
     338                 :             : {
     339                 :             :     int         i;
     340                 :             : 
     341                 :         450 :     errno = 0;
     342                 :         450 :     i = deccall3(n1, n2, result, PGTYPESnumeric_mul);
     343                 :             : 
     344         [ -  + ]:         450 :     if (i != 0)
     345         [ #  # ]:           0 :         switch (errno)
     346                 :             :         {
     347                 :           0 :             case PGTYPES_NUM_OVERFLOW:
     348                 :           0 :                 return ECPG_INFORMIX_NUM_OVERFLOW;
     349                 :             :                 break;
     350                 :           0 :             default:
     351                 :           0 :                 return ECPG_INFORMIX_NUM_UNDERFLOW;
     352                 :             :                 break;
     353                 :             :         }
     354                 :             : 
     355                 :         450 :     return 0;
     356                 :             : }
     357                 :             : 
     358                 :             : int
     359                 :         450 : decsub(decimal *n1, decimal *n2, decimal *result)
     360                 :             : {
     361                 :             :     int         i;
     362                 :             : 
     363                 :         450 :     errno = 0;
     364                 :         450 :     i = deccall3(n1, n2, result, PGTYPESnumeric_sub);
     365                 :             : 
     366         [ -  + ]:         450 :     if (i != 0)
     367         [ #  # ]:           0 :         switch (errno)
     368                 :             :         {
     369                 :           0 :             case PGTYPES_NUM_OVERFLOW:
     370                 :           0 :                 return ECPG_INFORMIX_NUM_OVERFLOW;
     371                 :             :                 break;
     372                 :           0 :             default:
     373                 :           0 :                 return ECPG_INFORMIX_NUM_UNDERFLOW;
     374                 :             :                 break;
     375                 :             :         }
     376                 :             : 
     377                 :         450 :     return 0;
     378                 :             : }
     379                 :             : 
     380                 :             : int
     381                 :        1878 : dectoasc(decimal *np, char *cp, int len, int right)
     382                 :             : {
     383                 :             :     char       *str;
     384                 :             :     numeric    *nres;
     385                 :             : 
     386                 :        1878 :     rsetnull(CSTRINGTYPE, (char *) cp);
     387         [ +  + ]:        1878 :     if (risnull(CDECIMALTYPE, (char *) np))
     388                 :         198 :         return 0;
     389                 :             : 
     390                 :        1680 :     nres = PGTYPESnumeric_new();
     391         [ -  + ]:        1680 :     if (nres == NULL)
     392                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     393                 :             : 
     394         [ -  + ]:        1680 :     if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     395                 :             :     {
     396                 :           0 :         PGTYPESnumeric_free(nres);
     397                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     398                 :             :     }
     399                 :             : 
     400         [ +  + ]:        1680 :     if (right >= 0)
     401                 :         156 :         str = PGTYPESnumeric_to_asc(nres, right);
     402                 :             :     else
     403                 :        1524 :         str = PGTYPESnumeric_to_asc(nres, nres->dscale);
     404                 :             : 
     405                 :        1680 :     PGTYPESnumeric_free(nres);
     406         [ -  + ]:        1680 :     if (!str)
     407                 :           0 :         return -1;
     408                 :             : 
     409                 :             :     /*
     410                 :             :      * TODO: have to take care of len here and create exponential notation if
     411                 :             :      * necessary
     412                 :             :      */
     413         [ +  + ]:        1680 :     if ((int) (strlen(str) + 1) > len)
     414                 :             :     {
     415         [ +  + ]:         216 :         if (len > 1)
     416                 :             :         {
     417                 :         212 :             cp[0] = '*';
     418                 :         212 :             cp[1] = '\0';
     419                 :             :         }
     420                 :         216 :         free(str);
     421                 :         216 :         return -1;
     422                 :             :     }
     423                 :             :     else
     424                 :             :     {
     425                 :        1464 :         strcpy(cp, str);
     426                 :        1464 :         free(str);
     427                 :        1464 :         return 0;
     428                 :             :     }
     429                 :             : }
     430                 :             : 
     431                 :             : int
     432                 :          26 : dectodbl(decimal *np, double *dblp)
     433                 :             : {
     434                 :             :     int         i;
     435                 :          26 :     numeric    *nres = PGTYPESnumeric_new();
     436                 :             : 
     437         [ -  + ]:          26 :     if (nres == NULL)
     438                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     439                 :             : 
     440         [ -  + ]:          26 :     if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     441                 :             :     {
     442                 :           0 :         PGTYPESnumeric_free(nres);
     443                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     444                 :             :     }
     445                 :             : 
     446                 :          26 :     i = PGTYPESnumeric_to_double(nres, dblp);
     447                 :          26 :     PGTYPESnumeric_free(nres);
     448                 :             : 
     449                 :          26 :     return i;
     450                 :             : }
     451                 :             : 
     452                 :             : int
     453                 :          32 : dectoint(decimal *np, int *ip)
     454                 :             : {
     455                 :             :     int         ret;
     456                 :          32 :     numeric    *nres = PGTYPESnumeric_new();
     457                 :             :     int         errnum;
     458                 :             : 
     459         [ -  + ]:          32 :     if (nres == NULL)
     460                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     461                 :             : 
     462         [ -  + ]:          32 :     if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     463                 :             :     {
     464                 :           0 :         PGTYPESnumeric_free(nres);
     465                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     466                 :             :     }
     467                 :             : 
     468                 :          32 :     errno = 0;
     469                 :          32 :     ret = PGTYPESnumeric_to_int(nres, ip);
     470                 :          32 :     errnum = errno;
     471                 :          32 :     PGTYPESnumeric_free(nres);
     472                 :             : 
     473   [ +  +  +  - ]:          32 :     if (ret == -1 && errnum == PGTYPES_NUM_OVERFLOW)
     474                 :           6 :         ret = ECPG_INFORMIX_NUM_OVERFLOW;
     475                 :             : 
     476                 :          32 :     return ret;
     477                 :             : }
     478                 :             : 
     479                 :             : int
     480                 :          28 : dectolong(decimal *np, long *lngp)
     481                 :             : {
     482                 :             :     int         ret;
     483                 :          28 :     numeric    *nres = PGTYPESnumeric_new();
     484                 :             :     int         errnum;
     485                 :             : 
     486         [ -  + ]:          28 :     if (nres == NULL)
     487                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     488                 :             : 
     489         [ -  + ]:          28 :     if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     490                 :             :     {
     491                 :           0 :         PGTYPESnumeric_free(nres);
     492                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     493                 :             :     }
     494                 :             : 
     495                 :          28 :     errno = 0;
     496                 :          28 :     ret = PGTYPESnumeric_to_long(nres, lngp);
     497                 :          28 :     errnum = errno;
     498                 :          28 :     PGTYPESnumeric_free(nres);
     499                 :             : 
     500   [ +  +  +  - ]:          28 :     if (ret == -1 && errnum == PGTYPES_NUM_OVERFLOW)
     501                 :           6 :         ret = ECPG_INFORMIX_NUM_OVERFLOW;
     502                 :             : 
     503                 :          28 :     return ret;
     504                 :             : }
     505                 :             : 
     506                 :             : /* Now the date functions */
     507                 :             : int
     508                 :          36 : rdatestr(date d, char *str)
     509                 :             : {
     510                 :          36 :     char       *tmp = PGTYPESdate_to_asc(d);
     511                 :             : 
     512         [ -  + ]:          36 :     if (!tmp)
     513                 :           0 :         return ECPG_INFORMIX_DATE_CONVERT;
     514                 :             : 
     515                 :             :     /* move to user allocated buffer */
     516                 :          36 :     strcpy(str, tmp);
     517                 :          36 :     free(tmp);
     518                 :             : 
     519                 :          36 :     return 0;
     520                 :             : }
     521                 :             : 
     522                 :             : /*
     523                 :             :  *
     524                 :             :  * the input for this function is mmddyyyy and any non-numeric
     525                 :             :  * character can be used as a separator
     526                 :             :  *
     527                 :             :  */
     528                 :             : int
     529                 :           4 : rstrdate(const char *str, date * d)
     530                 :             : {
     531                 :           4 :     return rdefmtdate(d, "mm/dd/yyyy", str);
     532                 :             : }
     533                 :             : 
     534                 :             : void
     535                 :           0 : rtoday(date * d)
     536                 :             : {
     537                 :           0 :     PGTYPESdate_today(d);
     538                 :           0 : }
     539                 :             : 
     540                 :             : int
     541                 :           0 : rjulmdy(date d, short *mdy)
     542                 :             : {
     543                 :             :     int         mdy_int[3];
     544                 :             : 
     545                 :           0 :     PGTYPESdate_julmdy(d, mdy_int);
     546                 :           0 :     mdy[0] = (short) mdy_int[0];
     547                 :           0 :     mdy[1] = (short) mdy_int[1];
     548                 :           0 :     mdy[2] = (short) mdy_int[2];
     549                 :           0 :     return 0;
     550                 :             : }
     551                 :             : 
     552                 :             : int
     553                 :          44 : rdefmtdate(date * d, const char *fmt, const char *str)
     554                 :             : {
     555                 :             :     /* TODO: take care of DBCENTURY environment variable */
     556                 :             :     /* PGSQL functions allow all centuries */
     557                 :             : 
     558                 :          44 :     errno = 0;
     559         [ +  + ]:          44 :     if (PGTYPESdate_defmt_asc(d, fmt, str) == 0)
     560                 :          34 :         return 0;
     561                 :             : 
     562   [ +  +  +  +  :          10 :     switch (errno)
                      - ]
     563                 :             :     {
     564                 :           4 :         case PGTYPES_DATE_ERR_ENOSHORTDATE:
     565                 :           4 :             return ECPG_INFORMIX_ENOSHORTDATE;
     566                 :           2 :         case PGTYPES_DATE_ERR_EARGS:
     567                 :             :         case PGTYPES_DATE_ERR_ENOTDMY:
     568                 :           2 :             return ECPG_INFORMIX_ENOTDMY;
     569                 :           2 :         case PGTYPES_DATE_BAD_DAY:
     570                 :           2 :             return ECPG_INFORMIX_BAD_DAY;
     571                 :           2 :         case PGTYPES_DATE_BAD_MONTH:
     572                 :           2 :             return ECPG_INFORMIX_BAD_MONTH;
     573                 :           0 :         default:
     574                 :           0 :             return ECPG_INFORMIX_BAD_YEAR;
     575                 :             :     }
     576                 :             : }
     577                 :             : 
     578                 :             : int
     579                 :          24 : rfmtdate(date d, const char *fmt, char *str)
     580                 :             : {
     581                 :          24 :     errno = 0;
     582         [ +  - ]:          24 :     if (PGTYPESdate_fmt_asc(d, fmt, str) == 0)
     583                 :          24 :         return 0;
     584                 :             : 
     585         [ #  # ]:           0 :     if (errno == ENOMEM)
     586                 :           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     587                 :             : 
     588                 :           0 :     return ECPG_INFORMIX_DATE_CONVERT;
     589                 :             : }
     590                 :             : 
     591                 :             : int
     592                 :           2 : rmdyjul(short *mdy, date * d)
     593                 :             : {
     594                 :             :     int         mdy_int[3];
     595                 :             : 
     596                 :           2 :     mdy_int[0] = mdy[0];
     597                 :           2 :     mdy_int[1] = mdy[1];
     598                 :           2 :     mdy_int[2] = mdy[2];
     599                 :           2 :     PGTYPESdate_mdyjul(mdy_int, d);
     600                 :           2 :     return 0;
     601                 :             : }
     602                 :             : 
     603                 :             : int
     604                 :           0 : rdayofweek(date d)
     605                 :             : {
     606                 :           0 :     return PGTYPESdate_dayofweek(d);
     607                 :             : }
     608                 :             : 
     609                 :             : /* And the datetime stuff */
     610                 :             : 
     611                 :             : void
     612                 :           0 : dtcurrent(timestamp * ts)
     613                 :             : {
     614                 :           0 :     PGTYPEStimestamp_current(ts);
     615                 :           0 : }
     616                 :             : 
     617                 :             : int
     618                 :           0 : dtcvasc(char *str, timestamp * ts)
     619                 :             : {
     620                 :             :     timestamp   ts_tmp;
     621                 :             :     int         i;
     622                 :           0 :     char      **endptr = &str;
     623                 :             : 
     624                 :           0 :     errno = 0;
     625                 :           0 :     ts_tmp = PGTYPEStimestamp_from_asc(str, endptr);
     626                 :           0 :     i = errno;
     627         [ #  # ]:           0 :     if (i)
     628                 :             :         /* TODO: rewrite to Informix error codes */
     629                 :           0 :         return i;
     630         [ #  # ]:           0 :     if (**endptr)
     631                 :             :     {
     632                 :             :         /* extra characters exist at the end */
     633                 :           0 :         return ECPG_INFORMIX_EXTRA_CHARS;
     634                 :             :     }
     635                 :             :     /* TODO: other Informix error codes missing */
     636                 :             : 
     637                 :             :     /* everything went fine */
     638                 :           0 :     *ts = ts_tmp;
     639                 :             : 
     640                 :           0 :     return 0;
     641                 :             : }
     642                 :             : 
     643                 :             : int
     644                 :           0 : dtcvfmtasc(char *inbuf, char *fmtstr, timestamp * dtvalue)
     645                 :             : {
     646                 :           0 :     return PGTYPEStimestamp_defmt_asc(inbuf, fmtstr, dtvalue);
     647                 :             : }
     648                 :             : 
     649                 :             : int
     650                 :           0 : dtsub(timestamp * ts1, timestamp * ts2, interval * iv)
     651                 :             : {
     652                 :           0 :     return PGTYPEStimestamp_sub(ts1, ts2, iv);
     653                 :             : }
     654                 :             : 
     655                 :             : int
     656                 :           0 : dttoasc(timestamp * ts, char *output)
     657                 :             : {
     658                 :           0 :     char       *asctime = PGTYPEStimestamp_to_asc(*ts);
     659                 :             : 
     660                 :           0 :     strcpy(output, asctime);
     661                 :           0 :     free(asctime);
     662                 :           0 :     return 0;
     663                 :             : }
     664                 :             : 
     665                 :             : int
     666                 :           0 : dttofmtasc(timestamp * ts, char *output, int str_len, char *fmtstr)
     667                 :             : {
     668                 :           0 :     return PGTYPEStimestamp_fmt_asc(ts, output, str_len, fmtstr);
     669                 :             : }
     670                 :             : 
     671                 :             : int
     672                 :           2 : intoasc(interval * i, char *str)
     673                 :             : {
     674                 :             :     char       *tmp;
     675                 :             : 
     676                 :           2 :     errno = 0;
     677                 :           2 :     tmp = PGTYPESinterval_to_asc(i);
     678                 :             : 
     679         [ -  + ]:           2 :     if (!tmp)
     680                 :           0 :         return -errno;
     681                 :             : 
     682                 :           2 :     strcpy(str, tmp);
     683                 :           2 :     free(tmp);
     684                 :           2 :     return 0;
     685                 :             : }
     686                 :             : 
     687                 :             : static struct
     688                 :             : {
     689                 :             :     long        val;
     690                 :             :     int         maxdigits;
     691                 :             :     int         digits;
     692                 :             :     int         remaining;
     693                 :             :     char        sign;
     694                 :             :     char       *val_string;
     695                 :             : }           value;
     696                 :             : 
     697                 :             : /**
     698                 :             :  * initialize the struct, which holds the different forms
     699                 :             :  * of the long value
     700                 :             :  */
     701                 :             : static int
     702                 :          20 : initValue(long lng_val)
     703                 :             : {
     704                 :             :     int         i,
     705                 :             :                 j;
     706                 :             :     long        l,
     707                 :             :                 dig;
     708                 :             : 
     709                 :             :     /* set some obvious things */
     710                 :          20 :     value.val = lng_val >= 0 ? lng_val : lng_val * (-1);
     711         [ -  + ]:          20 :     value.sign = lng_val >= 0 ? '+' : '-';
     712                 :          20 :     value.maxdigits = log10(2) * (8 * sizeof(long) - 1);
     713                 :             : 
     714                 :             :     /* determine the number of digits */
     715                 :          20 :     i = 0;
     716                 :          20 :     l = 1;
     717                 :             :     do
     718                 :             :     {
     719                 :         140 :         i++;
     720                 :         140 :         l *= 10;
     721                 :             :     }
     722   [ +  +  +  - ]:         140 :     while ((l - 1) < value.val && l <= LONG_MAX / 10);
     723                 :             : 
     724         [ +  - ]:          20 :     if (l <= LONG_MAX / 10)
     725                 :             :     {
     726                 :          20 :         value.digits = i;
     727                 :          20 :         l /= 10;
     728                 :             :     }
     729                 :             :     else
     730                 :           0 :         value.digits = i + 1;
     731                 :             : 
     732                 :          20 :     value.remaining = value.digits;
     733                 :             : 
     734                 :             :     /* convert the long to string */
     735         [ -  + ]:          20 :     if ((value.val_string = (char *) malloc(value.digits + 1)) == NULL)
     736                 :           0 :         return -1;
     737                 :          20 :     dig = value.val;
     738         [ +  + ]:         160 :     for (i = value.digits, j = 0; i > 0; i--, j++)
     739                 :             :     {
     740                 :         140 :         value.val_string[j] = dig / l + '0';
     741                 :         140 :         dig = dig % l;
     742                 :         140 :         l /= 10;
     743                 :             :     }
     744                 :          20 :     value.val_string[value.digits] = '\0';
     745                 :          20 :     return 0;
     746                 :             : }
     747                 :             : 
     748                 :             : /* return the position of the right-most dot in some string */
     749                 :             : static int
     750                 :          20 : getRightMostDot(const char *str)
     751                 :             : {
     752                 :          20 :     size_t      len = strlen(str);
     753                 :             :     int         i,
     754                 :             :                 j;
     755                 :             : 
     756                 :          20 :     j = 0;
     757         [ +  + ]:         252 :     for (i = len - 1; i >= 0; i--)
     758                 :             :     {
     759         [ +  + ]:         240 :         if (str[i] == '.')
     760                 :           8 :             return len - j - 1;
     761                 :         232 :         j++;
     762                 :             :     }
     763                 :          12 :     return -1;
     764                 :             : }
     765                 :             : 
     766                 :             : /* And finally some misc functions */
     767                 :             : int
     768                 :          20 : rfmtlong(long lng_val, const char *fmt, char *outbuf)
     769                 :             : {
     770                 :          20 :     size_t      fmt_len = strlen(fmt);
     771                 :             :     size_t      temp_len;
     772                 :             :     int         i,
     773                 :             :                 j,              /* position in temp */
     774                 :             :                 k,
     775                 :             :                 dotpos;
     776                 :          20 :     int         leftalign = 0,
     777                 :          20 :                 blank = 0,
     778                 :          20 :                 sign = 0,
     779                 :          20 :                 entitydone = 0,
     780                 :          20 :                 signdone = 0,
     781                 :          20 :                 brackets_ok = 0;
     782                 :             :     char       *temp;
     783                 :          20 :     char        tmp[2] = " ";
     784                 :          20 :     char        lastfmt = ' ',
     785                 :          20 :                 fmtchar = ' ';
     786                 :             : 
     787                 :          20 :     temp = (char *) malloc(fmt_len + 1);
     788         [ -  + ]:          20 :     if (!temp)
     789                 :             :     {
     790                 :           0 :         errno = ENOMEM;
     791                 :           0 :         return -1;
     792                 :             :     }
     793                 :             : 
     794                 :             :     /* put all info about the long in a struct */
     795         [ -  + ]:          20 :     if (initValue(lng_val) == -1)
     796                 :             :     {
     797                 :           0 :         free(temp);
     798                 :           0 :         errno = ENOMEM;
     799                 :           0 :         return -1;
     800                 :             :     }
     801                 :             : 
     802                 :             :     /* '<' is the only format, where we have to align left */
     803         [ +  + ]:          20 :     if (strchr(fmt, (int) '<'))
     804                 :           6 :         leftalign = 1;
     805                 :             : 
     806                 :             :     /* '(' requires ')' */
     807   [ +  +  +  - ]:          20 :     if (strchr(fmt, (int) '(') && strchr(fmt, (int) ')'))
     808                 :           2 :         brackets_ok = 1;
     809                 :             : 
     810                 :             :     /*
     811                 :             :      * get position of the right-most dot in the format-string and fill the
     812                 :             :      * temp-string with '0's up to there.
     813                 :             :      */
     814                 :          20 :     dotpos = getRightMostDot(fmt);
     815                 :             : 
     816                 :             :     /* start to parse the format-string */
     817                 :          20 :     temp[0] = '\0';
     818                 :          20 :     k = value.digits - 1;       /* position in the value_string */
     819         [ +  + ]:         378 :     for (i = fmt_len - 1, j = 0; i >= 0; i--, j++)
     820                 :             :     {
     821                 :             :         /* qualify, where we are in the value_string */
     822         [ +  + ]:         358 :         if (k < 0)
     823                 :             :         {
     824                 :         180 :             blank = 1;
     825         [ +  + ]:         180 :             if (k == -1)
     826                 :          60 :                 sign = 1;
     827         [ +  + ]:         180 :             if (leftalign)
     828                 :             :             {
     829                 :             :                 /* can't use strncat(,,0) here, Solaris would freak out */
     830         [ +  - ]:          46 :                 if (sign)
     831         [ -  + ]:          46 :                     if (signdone)
     832                 :             :                     {
     833                 :           0 :                         temp[j] = '\0';
     834                 :           0 :                         break;
     835                 :             :                     }
     836                 :             :             }
     837                 :             :         }
     838                 :             :         /* if we're right side of the right-most dot, print '0' */
     839   [ +  +  +  + ]:         358 :         if (dotpos >= 0 && dotpos <= i)
     840                 :             :         {
     841         [ +  + ]:          22 :             if (dotpos < i)
     842                 :             :             {
     843         [ +  + ]:          14 :                 if (fmt[i] == ')')
     844         [ +  - ]:           2 :                     tmp[0] = value.sign == '-' ? ')' : ' ';
     845                 :             :                 else
     846                 :          12 :                     tmp[0] = '0';
     847                 :             :             }
     848                 :             :             else
     849                 :           8 :                 tmp[0] = '.';
     850                 :          22 :             strcat(temp, tmp);
     851                 :          22 :             continue;
     852                 :             :         }
     853                 :             :         /* the ',' needs special attention, if it is in the blank area */
     854   [ +  +  +  + ]:         336 :         if (blank && fmt[i] == ',')
     855                 :           8 :             fmtchar = lastfmt;
     856                 :             :         else
     857                 :         328 :             fmtchar = fmt[i];
     858                 :             :         /* waiting for the sign */
     859   [ +  +  +  +  :         336 :         if (k < 0 && leftalign && sign && !signdone && fmtchar != '+' && fmtchar != '-')
          +  -  +  -  +  
                +  +  + ]
     860                 :          42 :             continue;
     861                 :             :         /* analyse this format-char */
     862   [ +  +  +  +  :         294 :         switch (fmtchar)
          +  +  +  -  +  
                   +  + ]
     863                 :             :         {
     864                 :          16 :             case ',':
     865                 :          16 :                 tmp[0] = ',';
     866                 :          16 :                 k++;
     867                 :          16 :                 break;
     868                 :          48 :             case '*':
     869         [ +  + ]:          48 :                 if (blank)
     870                 :          20 :                     tmp[0] = '*';
     871                 :             :                 else
     872                 :          28 :                     tmp[0] = value.val_string[k];
     873                 :          48 :                 break;
     874                 :          22 :             case '&':
     875         [ +  + ]:          22 :                 if (blank)
     876                 :           8 :                     tmp[0] = '0';
     877                 :             :                 else
     878                 :          14 :                     tmp[0] = value.val_string[k];
     879                 :          22 :                 break;
     880                 :          96 :             case '#':
     881         [ +  + ]:          96 :                 if (blank)
     882                 :          60 :                     tmp[0] = ' ';
     883                 :             :                 else
     884                 :          36 :                     tmp[0] = value.val_string[k];
     885                 :          96 :                 break;
     886                 :          12 :             case '-':
     887   [ +  +  +  -  :          12 :                 if (sign && value.sign == '-' && !signdone)
                   +  + ]
     888                 :             :                 {
     889                 :           4 :                     tmp[0] = '-';
     890                 :           4 :                     signdone = 1;
     891                 :             :                 }
     892         [ +  + ]:           8 :                 else if (blank)
     893                 :           6 :                     tmp[0] = ' ';
     894                 :             :                 else
     895                 :           2 :                     tmp[0] = value.val_string[k];
     896                 :          12 :                 break;
     897                 :          16 :             case '+':
     898   [ +  +  +  + ]:          16 :                 if (sign && !signdone)
     899                 :             :                 {
     900                 :           6 :                     tmp[0] = value.sign;
     901                 :           6 :                     signdone = 1;
     902                 :             :                 }
     903         [ +  + ]:          10 :                 else if (blank)
     904                 :           6 :                     tmp[0] = ' ';
     905                 :             :                 else
     906                 :           4 :                     tmp[0] = value.val_string[k];
     907                 :          16 :                 break;
     908                 :           2 :             case '(':
     909   [ +  -  +  -  :           2 :                 if (sign && brackets_ok && value.sign == '-')
                   +  - ]
     910                 :           2 :                     tmp[0] = '(';
     911         [ #  # ]:           0 :                 else if (blank)
     912                 :           0 :                     tmp[0] = ' ';
     913                 :             :                 else
     914                 :           0 :                     tmp[0] = value.val_string[k];
     915                 :           2 :                 break;
     916                 :           0 :             case ')':
     917   [ #  #  #  # ]:           0 :                 if (brackets_ok && value.sign == '-')
     918                 :           0 :                     tmp[0] = ')';
     919                 :             :                 else
     920                 :           0 :                     tmp[0] = ' ';
     921                 :           0 :                 break;
     922                 :          30 :             case '$':
     923   [ +  +  +  + ]:          30 :                 if (blank && !entitydone)
     924                 :             :                 {
     925                 :           6 :                     tmp[0] = '$';
     926                 :           6 :                     entitydone = 1;
     927                 :             :                 }
     928         [ +  + ]:          24 :                 else if (blank)
     929                 :          10 :                     tmp[0] = ' ';
     930                 :             :                 else
     931                 :          14 :                     tmp[0] = value.val_string[k];
     932                 :          30 :                 break;
     933                 :          42 :             case '<':
     934                 :          42 :                 tmp[0] = value.val_string[k];
     935                 :          42 :                 break;
     936                 :          10 :             default:
     937                 :          10 :                 tmp[0] = fmt[i];
     938                 :             :         }
     939                 :         294 :         strcat(temp, tmp);
     940                 :         294 :         lastfmt = fmt[i];
     941                 :         294 :         k--;
     942                 :             :     }
     943                 :             :     /* safety-net */
     944                 :          20 :     temp[fmt_len] = '\0';
     945                 :             : 
     946                 :             :     /* reverse the temp-string and put it into the outbuf */
     947                 :          20 :     temp_len = strlen(temp);
     948                 :          20 :     outbuf[0] = '\0';
     949         [ +  + ]:         336 :     for (i = temp_len - 1; i >= 0; i--)
     950                 :             :     {
     951                 :         316 :         tmp[0] = temp[i];
     952                 :         316 :         strcat(outbuf, tmp);
     953                 :             :     }
     954                 :          20 :     outbuf[temp_len] = '\0';
     955                 :             : 
     956                 :             :     /* cleaning up */
     957                 :          20 :     free(temp);
     958                 :          20 :     free(value.val_string);
     959                 :             : 
     960                 :          20 :     return 0;
     961                 :             : }
     962                 :             : 
     963                 :             : void
     964                 :           2 : rupshift(char *str)
     965                 :             : {
     966         [ +  + ]:          32 :     for (; *str != '\0'; str++)
     967         [ +  + ]:          30 :         if (islower((unsigned char) *str))
     968                 :          18 :             *str = toupper((unsigned char) *str);
     969                 :           2 : }
     970                 :             : 
     971                 :             : int
     972                 :          16 : byleng(char *str, int len)
     973                 :             : {
     974   [ +  -  +  + ]:          36 :     for (len--; str[len] && str[len] == ' '; len--);
     975                 :          16 :     return (len + 1);
     976                 :             : }
     977                 :             : 
     978                 :             : void
     979                 :           8 : ldchar(char *src, int len, char *dest)
     980                 :             : {
     981                 :           8 :     int         dlen = byleng(src, len);
     982                 :             : 
     983                 :           8 :     memmove(dest, src, dlen);
     984                 :           8 :     dest[dlen] = '\0';
     985                 :           8 : }
     986                 :             : 
     987                 :             : int
     988                 :           0 : rgetmsg(int msgnum, char *s, int maxsize)
     989                 :             : {
     990                 :             :     (void) msgnum;              /* keep the compiler quiet */
     991                 :             :     (void) s;                   /* keep the compiler quiet */
     992                 :             :     (void) maxsize;             /* keep the compiler quiet */
     993                 :           0 :     return 0;
     994                 :             : }
     995                 :             : 
     996                 :             : int
     997                 :           0 : rtypalign(int offset, int type)
     998                 :             : {
     999                 :             :     (void) offset;              /* keep the compiler quiet */
    1000                 :             :     (void) type;                /* keep the compiler quiet */
    1001                 :           0 :     return 0;
    1002                 :             : }
    1003                 :             : 
    1004                 :             : int
    1005                 :           0 : rtypmsize(int type, int len)
    1006                 :             : {
    1007                 :             :     (void) type;                /* keep the compiler quiet */
    1008                 :             :     (void) len;                 /* keep the compiler quiet */
    1009                 :           0 :     return 0;
    1010                 :             : }
    1011                 :             : 
    1012                 :             : int
    1013                 :           0 : rtypwidth(int sqltype, int sqllen)
    1014                 :             : {
    1015                 :             :     (void) sqltype;             /* keep the compiler quiet */
    1016                 :             :     (void) sqllen;              /* keep the compiler quiet */
    1017                 :           0 :     return 0;
    1018                 :             : }
    1019                 :             : 
    1020                 :             : void
    1021                 :           0 : ECPG_informix_set_var(int number, void *pointer, int lineno)
    1022                 :             : {
    1023                 :           0 :     ECPGset_var(number, pointer, lineno);
    1024                 :           0 : }
    1025                 :             : 
    1026                 :             : void *
    1027                 :           0 : ECPG_informix_get_var(int number)
    1028                 :             : {
    1029                 :           0 :     return ECPGget_var(number);
    1030                 :             : }
    1031                 :             : 
    1032                 :             : void
    1033                 :           0 : ECPG_informix_reset_sqlca(void)
    1034                 :             : {
    1035                 :           0 :     struct sqlca_t *sqlca = ECPGget_sqlca();
    1036                 :             : 
    1037         [ #  # ]:           0 :     if (sqlca == NULL)
    1038                 :           0 :         return;
    1039                 :             : 
    1040                 :           0 :     memcpy(sqlca, &sqlca_init, sizeof(struct sqlca_t));
    1041                 :             : }
    1042                 :             : 
    1043                 :             : int
    1044                 :        5326 : rsetnull(int t, char *ptr)
    1045                 :             : {
    1046                 :        5326 :     ECPGset_noind_null(t, ptr);
    1047                 :        5326 :     return 0;
    1048                 :             : }
    1049                 :             : 
    1050                 :             : int
    1051                 :        7292 : risnull(int t, const char *ptr)
    1052                 :             : {
    1053                 :        7292 :     return ECPGis_noind_null(t, ptr);
    1054                 :             : }
        

Generated by: LCOV version 2.0-1