LCOV - code coverage report
Current view: top level - src/interfaces/ecpg/compatlib - informix.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 563 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 47 0
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            0 : deccall2(decimal *arg1, decimal *arg2, int (*ptr) (numeric *, numeric *))
      49              : {
      50            0 :         numeric    *a1,
      51              :                            *a2;
      52            0 :         int                     i;
      53              : 
      54            0 :         if ((a1 = PGTYPESnumeric_new()) == NULL)
      55            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
      56              : 
      57            0 :         if ((a2 = PGTYPESnumeric_new()) == NULL)
      58              :         {
      59            0 :                 PGTYPESnumeric_free(a1);
      60            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
      61              :         }
      62              : 
      63            0 :         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            0 :         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            0 :         i = (*ptr) (a1, a2);
      78              : 
      79            0 :         PGTYPESnumeric_free(a1);
      80            0 :         PGTYPESnumeric_free(a2);
      81              : 
      82            0 :         return i;
      83            0 : }
      84              : 
      85              : static int
      86            0 : deccall3(decimal *arg1, decimal *arg2, decimal *result, int (*ptr) (numeric *, numeric *, numeric *))
      87              : {
      88            0 :         numeric    *a1,
      89              :                            *a2,
      90              :                            *nres;
      91            0 :         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            0 :         if (risnull(CDECIMALTYPE, (char *) arg1) || risnull(CDECIMALTYPE, (char *) arg2))
      98            0 :                 return 0;
      99              : 
     100            0 :         if ((a1 = PGTYPESnumeric_new()) == NULL)
     101            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
     102              : 
     103            0 :         if ((a2 = PGTYPESnumeric_new()) == NULL)
     104              :         {
     105            0 :                 PGTYPESnumeric_free(a1);
     106            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
     107              :         }
     108              : 
     109            0 :         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            0 :         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            0 :         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            0 :         i = (*ptr) (a1, a2, nres);
     133              : 
     134            0 :         if (i == 0)                                     /* No error */
     135              :         {
     136              : 
     137              :                 /* set the result to null in case it errors out later */
     138            0 :                 rsetnull(CDECIMALTYPE, (char *) result);
     139            0 :                 PGTYPESnumeric_to_decimal(nres, result);
     140            0 :         }
     141              : 
     142            0 :         PGTYPESnumeric_free(nres);
     143            0 :         PGTYPESnumeric_free(a1);
     144            0 :         PGTYPESnumeric_free(a2);
     145              : 
     146            0 :         return i;
     147            0 : }
     148              : 
     149              : /* we start with the numeric functions */
     150              : int
     151            0 : decadd(decimal *arg1, decimal *arg2, decimal *sum)
     152              : {
     153            0 :         errno = 0;
     154            0 :         deccall3(arg1, arg2, sum, PGTYPESnumeric_add);
     155              : 
     156            0 :         if (errno == PGTYPES_NUM_OVERFLOW)
     157            0 :                 return ECPG_INFORMIX_NUM_OVERFLOW;
     158            0 :         else if (errno == PGTYPES_NUM_UNDERFLOW)
     159            0 :                 return ECPG_INFORMIX_NUM_UNDERFLOW;
     160            0 :         else if (errno != 0)
     161            0 :                 return -1;
     162              :         else
     163            0 :                 return 0;
     164            0 : }
     165              : 
     166              : int
     167            0 : deccmp(decimal *arg1, decimal *arg2)
     168              : {
     169            0 :         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            0 : ecpg_strndup(const char *str, size_t len)
     180              : {
     181            0 :         size_t          real_len = strlen(str);
     182            0 :         int                     use_len = (int) ((real_len > len) ? len : real_len);
     183              : 
     184            0 :         char       *new = malloc(use_len + 1);
     185              : 
     186            0 :         if (new)
     187              :         {
     188            0 :                 memcpy(new, str, use_len);
     189            0 :                 new[use_len] = '\0';
     190            0 :         }
     191              :         else
     192            0 :                 errno = ENOMEM;
     193              : 
     194            0 :         return new;
     195            0 : }
     196              : 
     197              : int
     198            0 : deccvasc(const char *cp, int len, decimal *np)
     199              : {
     200            0 :         char       *str;
     201            0 :         int                     ret = 0;
     202            0 :         numeric    *result;
     203              : 
     204            0 :         rsetnull(CDECIMALTYPE, (char *) np);
     205            0 :         if (risnull(CSTRINGTYPE, cp))
     206            0 :                 return 0;
     207              : 
     208            0 :         str = ecpg_strndup(cp, len);    /* decimal_in always converts the complete
     209              :                                                                          * string */
     210            0 :         if (!str)
     211            0 :                 ret = ECPG_INFORMIX_NUM_UNDERFLOW;
     212              :         else
     213              :         {
     214            0 :                 errno = 0;
     215            0 :                 result = PGTYPESnumeric_from_asc(str, NULL);
     216            0 :                 if (!result)
     217              :                 {
     218            0 :                         switch (errno)
     219              :                         {
     220              :                                 case PGTYPES_NUM_OVERFLOW:
     221            0 :                                         ret = ECPG_INFORMIX_NUM_OVERFLOW;
     222            0 :                                         break;
     223              :                                 case PGTYPES_NUM_BAD_NUMERIC:
     224            0 :                                         ret = ECPG_INFORMIX_BAD_NUMERIC;
     225            0 :                                         break;
     226              :                                 default:
     227            0 :                                         ret = ECPG_INFORMIX_BAD_EXPONENT;
     228            0 :                                         break;
     229              :                         }
     230            0 :                 }
     231              :                 else
     232              :                 {
     233            0 :                         int                     i = PGTYPESnumeric_to_decimal(result, np);
     234              : 
     235            0 :                         PGTYPESnumeric_free(result);
     236            0 :                         if (i != 0)
     237            0 :                                 ret = ECPG_INFORMIX_NUM_OVERFLOW;
     238            0 :                 }
     239              :         }
     240              : 
     241            0 :         free(str);
     242            0 :         return ret;
     243            0 : }
     244              : 
     245              : int
     246            0 : deccvdbl(double dbl, decimal *np)
     247              : {
     248            0 :         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            0 : }
     266              : 
     267              : int
     268            0 : deccvint(int in, decimal *np)
     269              : {
     270            0 :         numeric    *nres;
     271            0 :         int                     result = 1;
     272              : 
     273            0 :         rsetnull(CDECIMALTYPE, (char *) np);
     274            0 :         if (risnull(CINTTYPE, (char *) &in))
     275            0 :                 return 0;
     276              : 
     277            0 :         nres = PGTYPESnumeric_new();
     278            0 :         if (nres == NULL)
     279            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
     280              : 
     281            0 :         result = PGTYPESnumeric_from_int(in, nres);
     282            0 :         if (result == 0)
     283            0 :                 result = PGTYPESnumeric_to_decimal(nres, np);
     284              : 
     285            0 :         PGTYPESnumeric_free(nres);
     286            0 :         return result;
     287            0 : }
     288              : 
     289              : int
     290            0 : deccvlong(long lng, decimal *np)
     291              : {
     292            0 :         numeric    *nres;
     293            0 :         int                     result = 1;
     294              : 
     295            0 :         rsetnull(CDECIMALTYPE, (char *) np);
     296            0 :         if (risnull(CLONGTYPE, (char *) &lng))
     297            0 :                 return 0;
     298              : 
     299            0 :         nres = PGTYPESnumeric_new();
     300            0 :         if (nres == NULL)
     301            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
     302              : 
     303            0 :         result = PGTYPESnumeric_from_long(lng, nres);
     304            0 :         if (result == 0)
     305            0 :                 result = PGTYPESnumeric_to_decimal(nres, np);
     306              : 
     307            0 :         PGTYPESnumeric_free(nres);
     308            0 :         return result;
     309            0 : }
     310              : 
     311              : int
     312            0 : decdiv(decimal *n1, decimal *n2, decimal *result)
     313              : {
     314            0 :         int                     i;
     315              : 
     316            0 :         errno = 0;
     317            0 :         i = deccall3(n1, n2, result, PGTYPESnumeric_div);
     318              : 
     319            0 :         if (i != 0)
     320            0 :                 switch (errno)
     321              :                 {
     322              :                         case PGTYPES_NUM_DIVIDE_ZERO:
     323            0 :                                 return ECPG_INFORMIX_DIVIDE_ZERO;
     324              :                                 break;
     325              :                         case PGTYPES_NUM_OVERFLOW:
     326            0 :                                 return ECPG_INFORMIX_NUM_OVERFLOW;
     327              :                                 break;
     328              :                         default:
     329            0 :                                 return ECPG_INFORMIX_NUM_UNDERFLOW;
     330              :                                 break;
     331              :                 }
     332              : 
     333            0 :         return 0;
     334            0 : }
     335              : 
     336              : int
     337            0 : decmul(decimal *n1, decimal *n2, decimal *result)
     338              : {
     339            0 :         int                     i;
     340              : 
     341            0 :         errno = 0;
     342            0 :         i = deccall3(n1, n2, result, PGTYPESnumeric_mul);
     343              : 
     344            0 :         if (i != 0)
     345            0 :                 switch (errno)
     346              :                 {
     347              :                         case PGTYPES_NUM_OVERFLOW:
     348            0 :                                 return ECPG_INFORMIX_NUM_OVERFLOW;
     349              :                                 break;
     350              :                         default:
     351            0 :                                 return ECPG_INFORMIX_NUM_UNDERFLOW;
     352              :                                 break;
     353              :                 }
     354              : 
     355            0 :         return 0;
     356            0 : }
     357              : 
     358              : int
     359            0 : decsub(decimal *n1, decimal *n2, decimal *result)
     360              : {
     361            0 :         int                     i;
     362              : 
     363            0 :         errno = 0;
     364            0 :         i = deccall3(n1, n2, result, PGTYPESnumeric_sub);
     365              : 
     366            0 :         if (i != 0)
     367            0 :                 switch (errno)
     368              :                 {
     369              :                         case PGTYPES_NUM_OVERFLOW:
     370            0 :                                 return ECPG_INFORMIX_NUM_OVERFLOW;
     371              :                                 break;
     372              :                         default:
     373            0 :                                 return ECPG_INFORMIX_NUM_UNDERFLOW;
     374              :                                 break;
     375              :                 }
     376              : 
     377            0 :         return 0;
     378            0 : }
     379              : 
     380              : int
     381            0 : dectoasc(decimal *np, char *cp, int len, int right)
     382              : {
     383            0 :         char       *str;
     384            0 :         numeric    *nres;
     385              : 
     386            0 :         rsetnull(CSTRINGTYPE, (char *) cp);
     387            0 :         if (risnull(CDECIMALTYPE, (char *) np))
     388            0 :                 return 0;
     389              : 
     390            0 :         nres = PGTYPESnumeric_new();
     391            0 :         if (nres == NULL)
     392            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
     393              : 
     394            0 :         if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     395              :         {
     396            0 :                 PGTYPESnumeric_free(nres);
     397            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
     398              :         }
     399              : 
     400            0 :         if (right >= 0)
     401            0 :                 str = PGTYPESnumeric_to_asc(nres, right);
     402              :         else
     403            0 :                 str = PGTYPESnumeric_to_asc(nres, nres->dscale);
     404              : 
     405            0 :         PGTYPESnumeric_free(nres);
     406            0 :         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            0 :         if ((int) (strlen(str) + 1) > len)
     414              :         {
     415            0 :                 if (len > 1)
     416              :                 {
     417            0 :                         cp[0] = '*';
     418            0 :                         cp[1] = '\0';
     419            0 :                 }
     420            0 :                 free(str);
     421            0 :                 return -1;
     422              :         }
     423              :         else
     424              :         {
     425            0 :                 strcpy(cp, str);
     426            0 :                 free(str);
     427            0 :                 return 0;
     428              :         }
     429            0 : }
     430              : 
     431              : int
     432            0 : dectodbl(decimal *np, double *dblp)
     433              : {
     434            0 :         int                     i;
     435            0 :         numeric    *nres = PGTYPESnumeric_new();
     436              : 
     437            0 :         if (nres == NULL)
     438            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
     439              : 
     440            0 :         if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     441              :         {
     442            0 :                 PGTYPESnumeric_free(nres);
     443            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
     444              :         }
     445              : 
     446            0 :         i = PGTYPESnumeric_to_double(nres, dblp);
     447            0 :         PGTYPESnumeric_free(nres);
     448              : 
     449            0 :         return i;
     450            0 : }
     451              : 
     452              : int
     453            0 : dectoint(decimal *np, int *ip)
     454              : {
     455            0 :         int                     ret;
     456            0 :         numeric    *nres = PGTYPESnumeric_new();
     457            0 :         int                     errnum;
     458              : 
     459            0 :         if (nres == NULL)
     460            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
     461              : 
     462            0 :         if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     463              :         {
     464            0 :                 PGTYPESnumeric_free(nres);
     465            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
     466              :         }
     467              : 
     468            0 :         errno = 0;
     469            0 :         ret = PGTYPESnumeric_to_int(nres, ip);
     470            0 :         errnum = errno;
     471            0 :         PGTYPESnumeric_free(nres);
     472              : 
     473            0 :         if (ret == -1 && errnum == PGTYPES_NUM_OVERFLOW)
     474            0 :                 ret = ECPG_INFORMIX_NUM_OVERFLOW;
     475              : 
     476            0 :         return ret;
     477            0 : }
     478              : 
     479              : int
     480            0 : dectolong(decimal *np, long *lngp)
     481              : {
     482            0 :         int                     ret;
     483            0 :         numeric    *nres = PGTYPESnumeric_new();
     484            0 :         int                     errnum;
     485              : 
     486            0 :         if (nres == NULL)
     487            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
     488              : 
     489            0 :         if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     490              :         {
     491            0 :                 PGTYPESnumeric_free(nres);
     492            0 :                 return ECPG_INFORMIX_OUT_OF_MEMORY;
     493              :         }
     494              : 
     495            0 :         errno = 0;
     496            0 :         ret = PGTYPESnumeric_to_long(nres, lngp);
     497            0 :         errnum = errno;
     498            0 :         PGTYPESnumeric_free(nres);
     499              : 
     500            0 :         if (ret == -1 && errnum == PGTYPES_NUM_OVERFLOW)
     501            0 :                 ret = ECPG_INFORMIX_NUM_OVERFLOW;
     502              : 
     503            0 :         return ret;
     504            0 : }
     505              : 
     506              : /* Now the date functions */
     507              : int
     508            0 : rdatestr(date d, char *str)
     509              : {
     510            0 :         char       *tmp = PGTYPESdate_to_asc(d);
     511              : 
     512            0 :         if (!tmp)
     513            0 :                 return ECPG_INFORMIX_DATE_CONVERT;
     514              : 
     515              :         /* move to user allocated buffer */
     516            0 :         strcpy(str, tmp);
     517            0 :         free(tmp);
     518              : 
     519            0 :         return 0;
     520            0 : }
     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            0 : rstrdate(const char *str, date * d)
     530              : {
     531            0 :         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            0 :         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            0 : }
     551              : 
     552              : int
     553            0 : 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            0 :         errno = 0;
     559            0 :         if (PGTYPESdate_defmt_asc(d, fmt, str) == 0)
     560            0 :                 return 0;
     561              : 
     562            0 :         switch (errno)
     563              :         {
     564              :                 case PGTYPES_DATE_ERR_ENOSHORTDATE:
     565            0 :                         return ECPG_INFORMIX_ENOSHORTDATE;
     566              :                 case PGTYPES_DATE_ERR_EARGS:
     567              :                 case PGTYPES_DATE_ERR_ENOTDMY:
     568            0 :                         return ECPG_INFORMIX_ENOTDMY;
     569              :                 case PGTYPES_DATE_BAD_DAY:
     570            0 :                         return ECPG_INFORMIX_BAD_DAY;
     571              :                 case PGTYPES_DATE_BAD_MONTH:
     572            0 :                         return ECPG_INFORMIX_BAD_MONTH;
     573              :                 default:
     574            0 :                         return ECPG_INFORMIX_BAD_YEAR;
     575              :         }
     576            0 : }
     577              : 
     578              : int
     579            0 : rfmtdate(date d, const char *fmt, char *str)
     580              : {
     581            0 :         errno = 0;
     582            0 :         if (PGTYPESdate_fmt_asc(d, fmt, str) == 0)
     583            0 :                 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            0 : }
     590              : 
     591              : int
     592            0 : rmdyjul(short *mdy, date * d)
     593              : {
     594            0 :         int                     mdy_int[3];
     595              : 
     596            0 :         mdy_int[0] = mdy[0];
     597            0 :         mdy_int[1] = mdy[1];
     598            0 :         mdy_int[2] = mdy[2];
     599            0 :         PGTYPESdate_mdyjul(mdy_int, d);
     600            0 :         return 0;
     601            0 : }
     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            0 :         timestamp       ts_tmp;
     621            0 :         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            0 : }
     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            0 : }
     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            0 : intoasc(interval * i, char *str)
     673              : {
     674            0 :         char       *tmp;
     675              : 
     676            0 :         errno = 0;
     677            0 :         tmp = PGTYPESinterval_to_asc(i);
     678              : 
     679            0 :         if (!tmp)
     680            0 :                 return -errno;
     681              : 
     682            0 :         strcpy(str, tmp);
     683            0 :         free(tmp);
     684            0 :         return 0;
     685            0 : }
     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            0 : initValue(long lng_val)
     703              : {
     704            0 :         int                     i,
     705              :                                 j;
     706            0 :         long            l,
     707              :                                 dig;
     708              : 
     709              :         /* set some obvious things */
     710            0 :         value.val = lng_val >= 0 ? lng_val : lng_val * (-1);
     711            0 :         value.sign = lng_val >= 0 ? '+' : '-';
     712            0 :         value.maxdigits = log10(2) * (8 * sizeof(long) - 1);
     713              : 
     714              :         /* determine the number of digits */
     715            0 :         i = 0;
     716            0 :         l = 1;
     717            0 :         do
     718              :         {
     719            0 :                 i++;
     720            0 :                 l *= 10;
     721            0 :         }
     722            0 :         while ((l - 1) < value.val && l <= LONG_MAX / 10);
     723              : 
     724            0 :         if (l <= LONG_MAX / 10)
     725              :         {
     726            0 :                 value.digits = i;
     727            0 :                 l /= 10;
     728            0 :         }
     729              :         else
     730            0 :                 value.digits = i + 1;
     731              : 
     732            0 :         value.remaining = value.digits;
     733              : 
     734              :         /* convert the long to string */
     735            0 :         if ((value.val_string = (char *) malloc(value.digits + 1)) == NULL)
     736            0 :                 return -1;
     737            0 :         dig = value.val;
     738            0 :         for (i = value.digits, j = 0; i > 0; i--, j++)
     739              :         {
     740            0 :                 value.val_string[j] = dig / l + '0';
     741            0 :                 dig = dig % l;
     742            0 :                 l /= 10;
     743            0 :         }
     744            0 :         value.val_string[value.digits] = '\0';
     745            0 :         return 0;
     746            0 : }
     747              : 
     748              : /* return the position of the right-most dot in some string */
     749              : static int
     750            0 : getRightMostDot(const char *str)
     751              : {
     752            0 :         size_t          len = strlen(str);
     753            0 :         int                     i,
     754              :                                 j;
     755              : 
     756            0 :         j = 0;
     757            0 :         for (i = len - 1; i >= 0; i--)
     758              :         {
     759            0 :                 if (str[i] == '.')
     760            0 :                         return len - j - 1;
     761            0 :                 j++;
     762            0 :         }
     763            0 :         return -1;
     764            0 : }
     765              : 
     766              : /* And finally some misc functions */
     767              : int
     768            0 : rfmtlong(long lng_val, const char *fmt, char *outbuf)
     769              : {
     770            0 :         size_t          fmt_len = strlen(fmt);
     771            0 :         size_t          temp_len;
     772            0 :         int                     i,
     773              :                                 j,                              /* position in temp */
     774              :                                 k,
     775              :                                 dotpos;
     776            0 :         int                     leftalign = 0,
     777            0 :                                 blank = 0,
     778            0 :                                 sign = 0,
     779            0 :                                 entitydone = 0,
     780            0 :                                 signdone = 0,
     781            0 :                                 brackets_ok = 0;
     782            0 :         char       *temp;
     783            0 :         char            tmp[2] = " ";
     784            0 :         char            lastfmt = ' ',
     785            0 :                                 fmtchar = ' ';
     786              : 
     787            0 :         temp = (char *) malloc(fmt_len + 1);
     788            0 :         if (!temp)
     789              :         {
     790            0 :                 errno = ENOMEM;
     791            0 :                 return -1;
     792              :         }
     793              : 
     794              :         /* put all info about the long in a struct */
     795            0 :         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            0 :         if (strchr(fmt, (int) '<'))
     804            0 :                 leftalign = 1;
     805              : 
     806              :         /* '(' requires ')' */
     807            0 :         if (strchr(fmt, (int) '(') && strchr(fmt, (int) ')'))
     808            0 :                 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            0 :         dotpos = getRightMostDot(fmt);
     815              : 
     816              :         /* start to parse the format-string */
     817            0 :         temp[0] = '\0';
     818            0 :         k = value.digits - 1;           /* position in the value_string */
     819            0 :         for (i = fmt_len - 1, j = 0; i >= 0; i--, j++)
     820              :         {
     821              :                 /* qualify, where we are in the value_string */
     822            0 :                 if (k < 0)
     823              :                 {
     824            0 :                         blank = 1;
     825            0 :                         if (k == -1)
     826            0 :                                 sign = 1;
     827            0 :                         if (leftalign)
     828              :                         {
     829              :                                 /* can't use strncat(,,0) here, Solaris would freak out */
     830            0 :                                 if (sign)
     831            0 :                                         if (signdone)
     832              :                                         {
     833            0 :                                                 temp[j] = '\0';
     834            0 :                                                 break;
     835              :                                         }
     836            0 :                         }
     837            0 :                 }
     838              :                 /* if we're right side of the right-most dot, print '0' */
     839            0 :                 if (dotpos >= 0 && dotpos <= i)
     840              :                 {
     841            0 :                         if (dotpos < i)
     842              :                         {
     843            0 :                                 if (fmt[i] == ')')
     844            0 :                                         tmp[0] = value.sign == '-' ? ')' : ' ';
     845              :                                 else
     846            0 :                                         tmp[0] = '0';
     847            0 :                         }
     848              :                         else
     849            0 :                                 tmp[0] = '.';
     850            0 :                         strcat(temp, tmp);
     851            0 :                         continue;
     852              :                 }
     853              :                 /* the ',' needs special attention, if it is in the blank area */
     854            0 :                 if (blank && fmt[i] == ',')
     855            0 :                         fmtchar = lastfmt;
     856              :                 else
     857            0 :                         fmtchar = fmt[i];
     858              :                 /* waiting for the sign */
     859            0 :                 if (k < 0 && leftalign && sign && !signdone && fmtchar != '+' && fmtchar != '-')
     860            0 :                         continue;
     861              :                 /* analyse this format-char */
     862            0 :                 switch (fmtchar)
     863              :                 {
     864              :                         case ',':
     865            0 :                                 tmp[0] = ',';
     866            0 :                                 k++;
     867            0 :                                 break;
     868              :                         case '*':
     869            0 :                                 if (blank)
     870            0 :                                         tmp[0] = '*';
     871              :                                 else
     872            0 :                                         tmp[0] = value.val_string[k];
     873            0 :                                 break;
     874              :                         case '&':
     875            0 :                                 if (blank)
     876            0 :                                         tmp[0] = '0';
     877              :                                 else
     878            0 :                                         tmp[0] = value.val_string[k];
     879            0 :                                 break;
     880              :                         case '#':
     881            0 :                                 if (blank)
     882            0 :                                         tmp[0] = ' ';
     883              :                                 else
     884            0 :                                         tmp[0] = value.val_string[k];
     885            0 :                                 break;
     886              :                         case '-':
     887            0 :                                 if (sign && value.sign == '-' && !signdone)
     888              :                                 {
     889            0 :                                         tmp[0] = '-';
     890            0 :                                         signdone = 1;
     891            0 :                                 }
     892            0 :                                 else if (blank)
     893            0 :                                         tmp[0] = ' ';
     894              :                                 else
     895            0 :                                         tmp[0] = value.val_string[k];
     896            0 :                                 break;
     897              :                         case '+':
     898            0 :                                 if (sign && !signdone)
     899              :                                 {
     900            0 :                                         tmp[0] = value.sign;
     901            0 :                                         signdone = 1;
     902            0 :                                 }
     903            0 :                                 else if (blank)
     904            0 :                                         tmp[0] = ' ';
     905              :                                 else
     906            0 :                                         tmp[0] = value.val_string[k];
     907            0 :                                 break;
     908              :                         case '(':
     909            0 :                                 if (sign && brackets_ok && value.sign == '-')
     910            0 :                                         tmp[0] = '(';
     911            0 :                                 else if (blank)
     912            0 :                                         tmp[0] = ' ';
     913              :                                 else
     914            0 :                                         tmp[0] = value.val_string[k];
     915            0 :                                 break;
     916              :                         case ')':
     917            0 :                                 if (brackets_ok && value.sign == '-')
     918            0 :                                         tmp[0] = ')';
     919              :                                 else
     920            0 :                                         tmp[0] = ' ';
     921            0 :                                 break;
     922              :                         case '$':
     923            0 :                                 if (blank && !entitydone)
     924              :                                 {
     925            0 :                                         tmp[0] = '$';
     926            0 :                                         entitydone = 1;
     927            0 :                                 }
     928            0 :                                 else if (blank)
     929            0 :                                         tmp[0] = ' ';
     930              :                                 else
     931            0 :                                         tmp[0] = value.val_string[k];
     932            0 :                                 break;
     933              :                         case '<':
     934            0 :                                 tmp[0] = value.val_string[k];
     935            0 :                                 break;
     936              :                         default:
     937            0 :                                 tmp[0] = fmt[i];
     938            0 :                 }
     939            0 :                 strcat(temp, tmp);
     940            0 :                 lastfmt = fmt[i];
     941            0 :                 k--;
     942            0 :         }
     943              :         /* safety-net */
     944            0 :         temp[fmt_len] = '\0';
     945              : 
     946              :         /* reverse the temp-string and put it into the outbuf */
     947            0 :         temp_len = strlen(temp);
     948            0 :         outbuf[0] = '\0';
     949            0 :         for (i = temp_len - 1; i >= 0; i--)
     950              :         {
     951            0 :                 tmp[0] = temp[i];
     952            0 :                 strcat(outbuf, tmp);
     953            0 :         }
     954            0 :         outbuf[temp_len] = '\0';
     955              : 
     956              :         /* cleaning up */
     957            0 :         free(temp);
     958            0 :         free(value.val_string);
     959              : 
     960            0 :         return 0;
     961            0 : }
     962              : 
     963              : void
     964            0 : rupshift(char *str)
     965              : {
     966            0 :         for (; *str != '\0'; str++)
     967            0 :                 if (islower((unsigned char) *str))
     968            0 :                         *str = toupper((unsigned char) *str);
     969            0 : }
     970              : 
     971              : int
     972            0 : byleng(char *str, int len)
     973              : {
     974            0 :         for (len--; str[len] && str[len] == ' '; len--);
     975            0 :         return (len + 1);
     976              : }
     977              : 
     978              : void
     979            0 : ldchar(char *src, int len, char *dest)
     980              : {
     981            0 :         int                     dlen = byleng(src, len);
     982              : 
     983            0 :         memmove(dest, src, dlen);
     984            0 :         dest[dlen] = '\0';
     985            0 : }
     986              : 
     987              : int
     988            0 : rgetmsg(int msgnum, char *s, int maxsize)
     989              : {
     990            0 :         (void) msgnum;                          /* keep the compiler quiet */
     991            0 :         (void) s;                                       /* keep the compiler quiet */
     992            0 :         (void) maxsize;                         /* keep the compiler quiet */
     993            0 :         return 0;
     994              : }
     995              : 
     996              : int
     997            0 : rtypalign(int offset, int type)
     998              : {
     999            0 :         (void) offset;                          /* keep the compiler quiet */
    1000            0 :         (void) type;                            /* keep the compiler quiet */
    1001            0 :         return 0;
    1002              : }
    1003              : 
    1004              : int
    1005            0 : rtypmsize(int type, int len)
    1006              : {
    1007            0 :         (void) type;                            /* keep the compiler quiet */
    1008            0 :         (void) len;                                     /* keep the compiler quiet */
    1009            0 :         return 0;
    1010              : }
    1011              : 
    1012              : int
    1013            0 : rtypwidth(int sqltype, int sqllen)
    1014              : {
    1015            0 :         (void) sqltype;                         /* keep the compiler quiet */
    1016            0 :         (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            0 : }
    1042              : 
    1043              : int
    1044            0 : rsetnull(int t, char *ptr)
    1045              : {
    1046            0 :         ECPGset_noind_null(t, ptr);
    1047            0 :         return 0;
    1048              : }
    1049              : 
    1050              : int
    1051            0 : risnull(int t, const char *ptr)
    1052              : {
    1053            0 :         return ECPGis_noind_null(t, ptr);
    1054              : }
        

Generated by: LCOV version 2.3.2-1