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

Generated by: LCOV version 1.14