LCOV - code coverage report
Current view: top level - src/interfaces/ecpg/compatlib - informix.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 316 474 66.7 %
Date: 2019-11-21 14:06:36 Functions: 28 47 59.6 %
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             :                 case PGTYPES_NUM_OVERFLOW:
     221           0 :                     ret = ECPG_INFORMIX_NUM_OVERFLOW;
     222           0 :                     break;
     223             :                 case PGTYPES_NUM_BAD_NUMERIC:
     224           4 :                     ret = ECPG_INFORMIX_BAD_NUMERIC;
     225           4 :                     break;
     226             :                 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             :             case PGTYPES_NUM_DIVIDE_ZERO:
     323          56 :                 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         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             :             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         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             :             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         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             : 
     458          64 :     if (nres == NULL)
     459           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     460             : 
     461          64 :     if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     462             :     {
     463           0 :         PGTYPESnumeric_free(nres);
     464           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     465             :     }
     466             : 
     467          64 :     ret = PGTYPESnumeric_to_int(nres, ip);
     468          64 :     PGTYPESnumeric_free(nres);
     469             : 
     470          64 :     if (ret == PGTYPES_NUM_OVERFLOW)
     471           0 :         ret = ECPG_INFORMIX_NUM_OVERFLOW;
     472             : 
     473          64 :     return ret;
     474             : }
     475             : 
     476             : int
     477          56 : dectolong(decimal *np, long *lngp)
     478             : {
     479             :     int         ret;
     480          56 :     numeric    *nres = PGTYPESnumeric_new();
     481             : 
     482          56 :     if (nres == NULL)
     483           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     484             : 
     485          56 :     if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     486             :     {
     487           0 :         PGTYPESnumeric_free(nres);
     488           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     489             :     }
     490             : 
     491          56 :     ret = PGTYPESnumeric_to_long(nres, lngp);
     492          56 :     PGTYPESnumeric_free(nres);
     493             : 
     494          56 :     if (ret == PGTYPES_NUM_OVERFLOW)
     495           0 :         ret = ECPG_INFORMIX_NUM_OVERFLOW;
     496             : 
     497          56 :     return ret;
     498             : }
     499             : 
     500             : /* Now the date functions */
     501             : int
     502          72 : rdatestr(date d, char *str)
     503             : {
     504          72 :     char       *tmp = PGTYPESdate_to_asc(d);
     505             : 
     506          72 :     if (!tmp)
     507           0 :         return ECPG_INFORMIX_DATE_CONVERT;
     508             : 
     509             :     /* move to user allocated buffer */
     510          72 :     strcpy(str, tmp);
     511          72 :     free(tmp);
     512             : 
     513          72 :     return 0;
     514             : }
     515             : 
     516             : /*
     517             : *
     518             : * the input for this function is mmddyyyy and any non-numeric
     519             : * character can be used as a separator
     520             : *
     521             : */
     522             : int
     523           8 : rstrdate(const char *str, date * d)
     524             : {
     525           8 :     return rdefmtdate(d, "mm/dd/yyyy", str);
     526             : }
     527             : 
     528             : void
     529           0 : rtoday(date * d)
     530             : {
     531           0 :     PGTYPESdate_today(d);
     532           0 :     return;
     533             : }
     534             : 
     535             : int
     536           0 : rjulmdy(date d, short mdy[3])
     537             : {
     538             :     int         mdy_int[3];
     539             : 
     540           0 :     PGTYPESdate_julmdy(d, mdy_int);
     541           0 :     mdy[0] = (short) mdy_int[0];
     542           0 :     mdy[1] = (short) mdy_int[1];
     543           0 :     mdy[2] = (short) mdy_int[2];
     544           0 :     return 0;
     545             : }
     546             : 
     547             : int
     548          88 : rdefmtdate(date * d, const char *fmt, const char *str)
     549             : {
     550             :     /* TODO: take care of DBCENTURY environment variable */
     551             :     /* PGSQL functions allow all centuries */
     552             : 
     553          88 :     errno = 0;
     554          88 :     if (PGTYPESdate_defmt_asc(d, fmt, str) == 0)
     555          68 :         return 0;
     556             : 
     557          20 :     switch (errno)
     558             :     {
     559             :         case PGTYPES_DATE_ERR_ENOSHORTDATE:
     560           8 :             return ECPG_INFORMIX_ENOSHORTDATE;
     561             :         case PGTYPES_DATE_ERR_EARGS:
     562             :         case PGTYPES_DATE_ERR_ENOTDMY:
     563           4 :             return ECPG_INFORMIX_ENOTDMY;
     564             :         case PGTYPES_DATE_BAD_DAY:
     565           4 :             return ECPG_INFORMIX_BAD_DAY;
     566             :         case PGTYPES_DATE_BAD_MONTH:
     567           4 :             return ECPG_INFORMIX_BAD_MONTH;
     568             :         default:
     569           0 :             return ECPG_INFORMIX_BAD_YEAR;
     570             :     }
     571             : }
     572             : 
     573             : int
     574          48 : rfmtdate(date d, const char *fmt, char *str)
     575             : {
     576          48 :     errno = 0;
     577          48 :     if (PGTYPESdate_fmt_asc(d, fmt, str) == 0)
     578          48 :         return 0;
     579             : 
     580           0 :     if (errno == ENOMEM)
     581           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     582             : 
     583           0 :     return ECPG_INFORMIX_DATE_CONVERT;
     584             : }
     585             : 
     586             : int
     587           4 : rmdyjul(short mdy[3], date * d)
     588             : {
     589             :     int         mdy_int[3];
     590             : 
     591           4 :     mdy_int[0] = mdy[0];
     592           4 :     mdy_int[1] = mdy[1];
     593           4 :     mdy_int[2] = mdy[2];
     594           4 :     PGTYPESdate_mdyjul(mdy_int, d);
     595           4 :     return 0;
     596             : }
     597             : 
     598             : int
     599           0 : rdayofweek(date d)
     600             : {
     601           0 :     return PGTYPESdate_dayofweek(d);
     602             : }
     603             : 
     604             : /* And the datetime stuff */
     605             : 
     606             : void
     607           0 : dtcurrent(timestamp * ts)
     608             : {
     609           0 :     PGTYPEStimestamp_current(ts);
     610           0 : }
     611             : 
     612             : int
     613           0 : dtcvasc(char *str, timestamp * ts)
     614             : {
     615             :     timestamp   ts_tmp;
     616             :     int         i;
     617           0 :     char      **endptr = &str;
     618             : 
     619           0 :     errno = 0;
     620           0 :     ts_tmp = PGTYPEStimestamp_from_asc(str, endptr);
     621           0 :     i = errno;
     622           0 :     if (i)
     623             :         /* TODO: rewrite to Informix error codes */
     624           0 :         return i;
     625           0 :     if (**endptr)
     626             :     {
     627             :         /* extra characters exist at the end */
     628           0 :         return ECPG_INFORMIX_EXTRA_CHARS;
     629             :     }
     630             :     /* TODO: other Informix error codes missing */
     631             : 
     632             :     /* everything went fine */
     633           0 :     *ts = ts_tmp;
     634             : 
     635           0 :     return 0;
     636             : }
     637             : 
     638             : int
     639           0 : dtcvfmtasc(char *inbuf, char *fmtstr, timestamp * dtvalue)
     640             : {
     641           0 :     return PGTYPEStimestamp_defmt_asc(inbuf, fmtstr, dtvalue);
     642             : }
     643             : 
     644             : int
     645           0 : dtsub(timestamp * ts1, timestamp * ts2, interval * iv)
     646             : {
     647           0 :     return PGTYPEStimestamp_sub(ts1, ts2, iv);
     648             : }
     649             : 
     650             : int
     651           0 : dttoasc(timestamp * ts, char *output)
     652             : {
     653           0 :     char       *asctime = PGTYPEStimestamp_to_asc(*ts);
     654             : 
     655           0 :     strcpy(output, asctime);
     656           0 :     free(asctime);
     657           0 :     return 0;
     658             : }
     659             : 
     660             : int
     661           0 : dttofmtasc(timestamp * ts, char *output, int str_len, char *fmtstr)
     662             : {
     663           0 :     return PGTYPEStimestamp_fmt_asc(ts, output, str_len, fmtstr);
     664             : }
     665             : 
     666             : int
     667           0 : intoasc(interval * i, char *str)
     668             : {
     669             :     char       *tmp;
     670             : 
     671           0 :     errno = 0;
     672           0 :     tmp = PGTYPESinterval_to_asc(i);
     673             : 
     674           0 :     if (!tmp)
     675           0 :         return -errno;
     676             : 
     677           0 :     memcpy(str, tmp, strlen(tmp));
     678           0 :     free(tmp);
     679           0 :     return 0;
     680             : }
     681             : 
     682             : static struct
     683             : {
     684             :     long        val;
     685             :     int         maxdigits;
     686             :     int         digits;
     687             :     int         remaining;
     688             :     char        sign;
     689             :     char       *val_string;
     690             : }           value;
     691             : 
     692             : /**
     693             :  * initialize the struct, which holds the different forms
     694             :  * of the long value
     695             :  */
     696             : static int
     697          40 : initValue(long lng_val)
     698             : {
     699             :     int         i,
     700             :                 j;
     701             :     long        l,
     702             :                 dig;
     703             : 
     704             :     /* set some obvious things */
     705          40 :     value.val = lng_val >= 0 ? lng_val : lng_val * (-1);
     706          40 :     value.sign = lng_val >= 0 ? '+' : '-';
     707          40 :     value.maxdigits = log10(2) * (8 * sizeof(long) - 1);
     708             : 
     709             :     /* determine the number of digits */
     710          40 :     i = 0;
     711          40 :     l = 1;
     712             :     do
     713             :     {
     714         280 :         i++;
     715         280 :         l *= 10;
     716             :     }
     717         280 :     while ((l - 1) < value.val && l <= LONG_MAX / 10);
     718             : 
     719          40 :     if (l <= LONG_MAX / 10)
     720             :     {
     721          40 :         value.digits = i;
     722          40 :         l /= 10;
     723             :     }
     724             :     else
     725           0 :         value.digits = i + 1;
     726             : 
     727          40 :     value.remaining = value.digits;
     728             : 
     729             :     /* convert the long to string */
     730          40 :     if ((value.val_string = (char *) malloc(value.digits + 1)) == NULL)
     731           0 :         return -1;
     732          40 :     dig = value.val;
     733         320 :     for (i = value.digits, j = 0; i > 0; i--, j++)
     734             :     {
     735         280 :         value.val_string[j] = dig / l + '0';
     736         280 :         dig = dig % l;
     737         280 :         l /= 10;
     738             :     }
     739          40 :     value.val_string[value.digits] = '\0';
     740          40 :     return 0;
     741             : }
     742             : 
     743             : /* return the position of the right-most dot in some string */
     744             : static int
     745          40 : getRightMostDot(const char *str)
     746             : {
     747          40 :     size_t      len = strlen(str);
     748             :     int         i,
     749             :                 j;
     750             : 
     751          40 :     j = 0;
     752         504 :     for (i = len - 1; i >= 0; i--)
     753             :     {
     754         480 :         if (str[i] == '.')
     755          16 :             return len - j - 1;
     756         464 :         j++;
     757             :     }
     758          24 :     return -1;
     759             : }
     760             : 
     761             : /* And finally some misc functions */
     762             : int
     763          40 : rfmtlong(long lng_val, const char *fmt, char *outbuf)
     764             : {
     765          40 :     size_t      fmt_len = strlen(fmt);
     766             :     size_t      temp_len;
     767             :     int         i,
     768             :                 j,              /* position in temp */
     769             :                 k,
     770             :                 dotpos;
     771          40 :     int         leftalign = 0,
     772          40 :                 blank = 0,
     773          40 :                 sign = 0,
     774          40 :                 entitydone = 0,
     775          40 :                 signdone = 0,
     776          40 :                 brackets_ok = 0;
     777             :     char       *temp;
     778          40 :     char        tmp[2] = " ";
     779          40 :     char        lastfmt = ' ',
     780          40 :                 fmtchar = ' ';
     781             : 
     782          40 :     temp = (char *) malloc(fmt_len + 1);
     783          40 :     if (!temp)
     784             :     {
     785           0 :         errno = ENOMEM;
     786           0 :         return -1;
     787             :     }
     788             : 
     789             :     /* put all info about the long in a struct */
     790          40 :     if (initValue(lng_val) == -1)
     791             :     {
     792           0 :         free(temp);
     793           0 :         errno = ENOMEM;
     794           0 :         return -1;
     795             :     }
     796             : 
     797             :     /* '<' is the only format, where we have to align left */
     798          40 :     if (strchr(fmt, (int) '<'))
     799          12 :         leftalign = 1;
     800             : 
     801             :     /* '(' requires ')' */
     802          40 :     if (strchr(fmt, (int) '(') && strchr(fmt, (int) ')'))
     803           4 :         brackets_ok = 1;
     804             : 
     805             :     /* get position of the right-most dot in the format-string */
     806             :     /* and fill the temp-string wit '0's up to there. */
     807          40 :     dotpos = getRightMostDot(fmt);
     808             : 
     809             :     /* start to parse the format-string */
     810          40 :     temp[0] = '\0';
     811          40 :     k = value.digits - 1;       /* position in the value_string */
     812         756 :     for (i = fmt_len - 1, j = 0; i >= 0; i--, j++)
     813             :     {
     814             :         /* qualify, where we are in the value_string */
     815         716 :         if (k < 0)
     816             :         {
     817         360 :             blank = 1;
     818         360 :             if (k == -1)
     819         120 :                 sign = 1;
     820         360 :             if (leftalign)
     821             :             {
     822             :                 /* can't use strncat(,,0) here, Solaris would freak out */
     823          92 :                 if (sign)
     824          92 :                     if (signdone)
     825             :                     {
     826           0 :                         temp[j] = '\0';
     827           0 :                         break;
     828             :                     }
     829             :             }
     830             :         }
     831             :         /* if we're right side of the right-most dot, print '0' */
     832         716 :         if (dotpos >= 0 && dotpos <= i)
     833             :         {
     834          44 :             if (dotpos < i)
     835             :             {
     836          28 :                 if (fmt[i] == ')')
     837           4 :                     tmp[0] = value.sign == '-' ? ')' : ' ';
     838             :                 else
     839          24 :                     tmp[0] = '0';
     840             :             }
     841             :             else
     842          16 :                 tmp[0] = '.';
     843          44 :             strcat(temp, tmp);
     844          44 :             continue;
     845             :         }
     846             :         /* the ',' needs special attention, if it is in the blank area */
     847         672 :         if (blank && fmt[i] == ',')
     848          16 :             fmtchar = lastfmt;
     849             :         else
     850         656 :             fmtchar = fmt[i];
     851             :         /* waiting for the sign */
     852         672 :         if (k < 0 && leftalign && sign && !signdone && fmtchar != '+' && fmtchar != '-')
     853          84 :             continue;
     854             :         /* analyse this format-char */
     855         588 :         switch (fmtchar)
     856             :         {
     857             :             case ',':
     858          32 :                 tmp[0] = ',';
     859          32 :                 k++;
     860          32 :                 break;
     861             :             case '*':
     862          96 :                 if (blank)
     863          40 :                     tmp[0] = '*';
     864             :                 else
     865          56 :                     tmp[0] = value.val_string[k];
     866          96 :                 break;
     867             :             case '&':
     868          44 :                 if (blank)
     869          16 :                     tmp[0] = '0';
     870             :                 else
     871          28 :                     tmp[0] = value.val_string[k];
     872          44 :                 break;
     873             :             case '#':
     874         192 :                 if (blank)
     875         120 :                     tmp[0] = ' ';
     876             :                 else
     877          72 :                     tmp[0] = value.val_string[k];
     878         192 :                 break;
     879             :             case '-':
     880          24 :                 if (sign && value.sign == '-' && !signdone)
     881             :                 {
     882           8 :                     tmp[0] = '-';
     883           8 :                     signdone = 1;
     884             :                 }
     885          16 :                 else if (blank)
     886          12 :                     tmp[0] = ' ';
     887             :                 else
     888           4 :                     tmp[0] = value.val_string[k];
     889          24 :                 break;
     890             :             case '+':
     891          32 :                 if (sign && !signdone)
     892             :                 {
     893          12 :                     tmp[0] = value.sign;
     894          12 :                     signdone = 1;
     895             :                 }
     896          20 :                 else if (blank)
     897          12 :                     tmp[0] = ' ';
     898             :                 else
     899           8 :                     tmp[0] = value.val_string[k];
     900          32 :                 break;
     901             :             case '(':
     902           4 :                 if (sign && brackets_ok && value.sign == '-')
     903           4 :                     tmp[0] = '(';
     904           0 :                 else if (blank)
     905           0 :                     tmp[0] = ' ';
     906             :                 else
     907           0 :                     tmp[0] = value.val_string[k];
     908           4 :                 break;
     909             :             case ')':
     910           0 :                 if (brackets_ok && value.sign == '-')
     911           0 :                     tmp[0] = ')';
     912             :                 else
     913           0 :                     tmp[0] = ' ';
     914           0 :                 break;
     915             :             case '$':
     916          60 :                 if (blank && !entitydone)
     917             :                 {
     918          12 :                     tmp[0] = '$';
     919          12 :                     entitydone = 1;
     920             :                 }
     921          48 :                 else if (blank)
     922          20 :                     tmp[0] = ' ';
     923             :                 else
     924          28 :                     tmp[0] = value.val_string[k];
     925          60 :                 break;
     926             :             case '<':
     927          84 :                 tmp[0] = value.val_string[k];
     928          84 :                 break;
     929             :             default:
     930          20 :                 tmp[0] = fmt[i];
     931             :         }
     932         588 :         strcat(temp, tmp);
     933         588 :         lastfmt = fmt[i];
     934         588 :         k--;
     935             :     }
     936             :     /* safety-net */
     937          40 :     temp[fmt_len] = '\0';
     938             : 
     939             :     /* reverse the temp-string and put it into the outbuf */
     940          40 :     temp_len = strlen(temp);
     941          40 :     outbuf[0] = '\0';
     942         672 :     for (i = temp_len - 1; i >= 0; i--)
     943             :     {
     944         632 :         tmp[0] = temp[i];
     945         632 :         strcat(outbuf, tmp);
     946             :     }
     947          40 :     outbuf[temp_len] = '\0';
     948             : 
     949             :     /* cleaning up */
     950          40 :     free(temp);
     951          40 :     free(value.val_string);
     952             : 
     953          40 :     return 0;
     954             : }
     955             : 
     956             : void
     957           4 : rupshift(char *str)
     958             : {
     959          64 :     for (; *str != '\0'; str++)
     960          60 :         if (islower((unsigned char) *str))
     961          36 :             *str = toupper((unsigned char) *str);
     962           4 :     return;
     963             : }
     964             : 
     965             : int
     966          32 : byleng(char *str, int len)
     967             : {
     968          32 :     for (len--; str[len] && str[len] == ' '; len--);
     969          32 :     return (len + 1);
     970             : }
     971             : 
     972             : void
     973          16 : ldchar(char *src, int len, char *dest)
     974             : {
     975          16 :     int         dlen = byleng(src, len);
     976             : 
     977          16 :     memmove(dest, src, dlen);
     978          16 :     dest[dlen] = '\0';
     979          16 : }
     980             : 
     981             : int
     982           0 : rgetmsg(int msgnum, char *s, int maxsize)
     983             : {
     984             :     (void) msgnum;              /* keep the compiler quiet */
     985             :     (void) s;                   /* keep the compiler quiet */
     986             :     (void) maxsize;             /* keep the compiler quiet */
     987           0 :     return 0;
     988             : }
     989             : 
     990             : int
     991           0 : rtypalign(int offset, int type)
     992             : {
     993             :     (void) offset;              /* keep the compiler quiet */
     994             :     (void) type;                /* keep the compiler quiet */
     995           0 :     return 0;
     996             : }
     997             : 
     998             : int
     999           0 : rtypmsize(int type, int len)
    1000             : {
    1001             :     (void) type;                /* keep the compiler quiet */
    1002             :     (void) len;                 /* keep the compiler quiet */
    1003           0 :     return 0;
    1004             : }
    1005             : 
    1006             : int
    1007           0 : rtypwidth(int sqltype, int sqllen)
    1008             : {
    1009             :     (void) sqltype;             /* keep the compiler quiet */
    1010             :     (void) sqllen;              /* keep the compiler quiet */
    1011           0 :     return 0;
    1012             : }
    1013             : 
    1014             : void
    1015           0 : ECPG_informix_set_var(int number, void *pointer, int lineno)
    1016             : {
    1017           0 :     ECPGset_var(number, pointer, lineno);
    1018           0 : }
    1019             : 
    1020             : void *
    1021           0 : ECPG_informix_get_var(int number)
    1022             : {
    1023           0 :     return ECPGget_var(number);
    1024             : }
    1025             : 
    1026             : void
    1027           0 : ECPG_informix_reset_sqlca(void)
    1028             : {
    1029           0 :     struct sqlca_t *sqlca = ECPGget_sqlca();
    1030             : 
    1031           0 :     if (sqlca == NULL)
    1032           0 :         return;
    1033             : 
    1034           0 :     memcpy((char *) sqlca, (char *) &sqlca_init, sizeof(struct sqlca_t));
    1035             : }
    1036             : 
    1037             : int
    1038        7052 : rsetnull(int t, char *ptr)
    1039             : {
    1040        7052 :     ECPGset_noind_null(t, ptr);
    1041        7052 :     return 0;
    1042             : }
    1043             : 
    1044             : int
    1045       10984 : risnull(int t, const char *ptr)
    1046             : {
    1047       10984 :     return ECPGis_noind_null(t, ptr);
    1048             : }

Generated by: LCOV version 1.13