LCOV - code coverage report
Current view: top level - src/interfaces/ecpg/compatlib - informix.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 68.5 % 504 345
Test Date: 2026-03-10 17:14:41 Functions: 61.7 % 47 29
Legend: Lines:     hit not hit

            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