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

Generated by: LCOV version 1.14