LCOV - code coverage report
Current view: top level - src/interfaces/ecpg/compatlib - informix.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 324 491 66.0 %
Date: 2023-12-07 07:10:44 Functions: 27 46 58.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* src/interfaces/ecpg/compatlib/informix.c */
       2             : 
       3             : #define POSTGRES_ECPG_INTERNAL
       4             : #include "postgres_fe.h"
       5             : 
       6             : #include <math.h>
       7             : #include <ctype.h>
       8             : #include <limits.h>
       9             : 
      10             : #include "ecpg_informix.h"
      11             : #include "ecpgerrno.h"
      12             : #include "ecpgtype.h"
      13             : #include "pgtypes_date.h"
      14             : #include "pgtypes_error.h"
      15             : #include "pgtypes_numeric.h"
      16             : #include "sqlca.h"
      17             : #include "sqltypes.h"
      18             : 
      19             : /* this is also defined in ecpglib/misc.c, by defining it twice we don't have to export the symbol */
      20             : 
      21             : static struct sqlca_t sqlca_init =
      22             : {
      23             :     {
      24             :         'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '
      25             :     },
      26             :     sizeof(struct sqlca_t),
      27             :     0,
      28             :     {
      29             :         0,
      30             :         {
      31             :             0
      32             :         }
      33             :     },
      34             :     {
      35             :         'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '
      36             :     },
      37             :     {
      38             :         0, 0, 0, 0, 0, 0
      39             :     },
      40             :     {
      41             :         0, 0, 0, 0, 0, 0, 0, 0
      42             :     },
      43             :     {
      44             :         '0', '0', '0', '0', '0'
      45             :     }
      46             : };
      47             : static int
      48         988 : deccall2(decimal *arg1, decimal *arg2, int (*ptr) (numeric *, numeric *))
      49             : {
      50             :     numeric    *a1,
      51             :                *a2;
      52             :     int         i;
      53             : 
      54         988 :     if ((a1 = PGTYPESnumeric_new()) == NULL)
      55           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
      56             : 
      57         988 :     if ((a2 = PGTYPESnumeric_new()) == NULL)
      58             :     {
      59           0 :         PGTYPESnumeric_free(a1);
      60           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
      61             :     }
      62             : 
      63         988 :     if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
      64             :     {
      65           0 :         PGTYPESnumeric_free(a1);
      66           0 :         PGTYPESnumeric_free(a2);
      67           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
      68             :     }
      69             : 
      70         988 :     if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
      71             :     {
      72           0 :         PGTYPESnumeric_free(a1);
      73           0 :         PGTYPESnumeric_free(a2);
      74           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
      75             :     }
      76             : 
      77         988 :     i = (*ptr) (a1, a2);
      78             : 
      79         988 :     PGTYPESnumeric_free(a1);
      80         988 :     PGTYPESnumeric_free(a2);
      81             : 
      82         988 :     return i;
      83             : }
      84             : 
      85             : static int
      86        3604 : deccall3(decimal *arg1, decimal *arg2, decimal *result, int (*ptr) (numeric *, numeric *, numeric *))
      87             : {
      88             :     numeric    *a1,
      89             :                *a2,
      90             :                *nres;
      91             :     int         i;
      92             : 
      93             :     /*
      94             :      * we must NOT set the result to NULL here because it may be the same
      95             :      * variable as one of the arguments
      96             :      */
      97        3604 :     if (risnull(CDECIMALTYPE, (char *) arg1) || risnull(CDECIMALTYPE, (char *) arg2))
      98         464 :         return 0;
      99             : 
     100        3140 :     if ((a1 = PGTYPESnumeric_new()) == NULL)
     101           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     102             : 
     103        3140 :     if ((a2 = PGTYPESnumeric_new()) == NULL)
     104             :     {
     105           0 :         PGTYPESnumeric_free(a1);
     106           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     107             :     }
     108             : 
     109        3140 :     if ((nres = PGTYPESnumeric_new()) == NULL)
     110             :     {
     111           0 :         PGTYPESnumeric_free(a1);
     112           0 :         PGTYPESnumeric_free(a2);
     113           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     114             :     }
     115             : 
     116        3140 :     if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
     117             :     {
     118           0 :         PGTYPESnumeric_free(a1);
     119           0 :         PGTYPESnumeric_free(a2);
     120           0 :         PGTYPESnumeric_free(nres);
     121           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     122             :     }
     123             : 
     124        3140 :     if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
     125             :     {
     126           0 :         PGTYPESnumeric_free(a1);
     127           0 :         PGTYPESnumeric_free(a2);
     128           0 :         PGTYPESnumeric_free(nres);
     129           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     130             :     }
     131             : 
     132        3140 :     i = (*ptr) (a1, a2, nres);
     133             : 
     134        3140 :     if (i == 0)                 /* No error */
     135             :     {
     136             : 
     137             :         /* set the result to null in case it errors out later */
     138        3084 :         rsetnull(CDECIMALTYPE, (char *) result);
     139        3084 :         PGTYPESnumeric_to_decimal(nres, result);
     140             :     }
     141             : 
     142        3140 :     PGTYPESnumeric_free(nres);
     143        3140 :     PGTYPESnumeric_free(a1);
     144        3140 :     PGTYPESnumeric_free(a2);
     145             : 
     146        3140 :     return i;
     147             : }
     148             : 
     149             : /* we start with the numeric functions */
     150             : int
     151         904 : decadd(decimal *arg1, decimal *arg2, decimal *sum)
     152             : {
     153         904 :     errno = 0;
     154         904 :     deccall3(arg1, arg2, sum, PGTYPESnumeric_add);
     155             : 
     156         904 :     if (errno == PGTYPES_NUM_OVERFLOW)
     157         248 :         return ECPG_INFORMIX_NUM_OVERFLOW;
     158         656 :     else if (errno == PGTYPES_NUM_UNDERFLOW)
     159           0 :         return ECPG_INFORMIX_NUM_UNDERFLOW;
     160         656 :     else if (errno != 0)
     161           0 :         return -1;
     162             :     else
     163         656 :         return 0;
     164             : }
     165             : 
     166             : int
     167         988 : deccmp(decimal *arg1, decimal *arg2)
     168             : {
     169         988 :     return deccall2(arg1, arg2, PGTYPESnumeric_cmp);
     170             : }
     171             : 
     172             : void
     173           0 : deccopy(decimal *src, decimal *target)
     174             : {
     175           0 :     memcpy(target, src, sizeof(decimal));
     176           0 : }
     177             : 
     178             : 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             : 
     439          64 :     if (nres == NULL)
     440           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     441             : 
     442          64 :     if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     443             :     {
     444           0 :         PGTYPESnumeric_free(nres);
     445           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     446             :     }
     447             : 
     448          64 :     ret = PGTYPESnumeric_to_int(nres, ip);
     449          64 :     PGTYPESnumeric_free(nres);
     450             : 
     451          64 :     if (ret == PGTYPES_NUM_OVERFLOW)
     452           0 :         ret = ECPG_INFORMIX_NUM_OVERFLOW;
     453             : 
     454          64 :     return ret;
     455             : }
     456             : 
     457             : int
     458          56 : dectolong(decimal *np, long *lngp)
     459             : {
     460             :     int         ret;
     461          56 :     numeric    *nres = PGTYPESnumeric_new();
     462             : 
     463          56 :     if (nres == NULL)
     464           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     465             : 
     466          56 :     if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     467             :     {
     468           0 :         PGTYPESnumeric_free(nres);
     469           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     470             :     }
     471             : 
     472          56 :     ret = PGTYPESnumeric_to_long(nres, lngp);
     473          56 :     PGTYPESnumeric_free(nres);
     474             : 
     475          56 :     if (ret == PGTYPES_NUM_OVERFLOW)
     476           0 :         ret = ECPG_INFORMIX_NUM_OVERFLOW;
     477             : 
     478          56 :     return ret;
     479             : }
     480             : 
     481             : /* Now the date functions */
     482             : int
     483          72 : rdatestr(date d, char *str)
     484             : {
     485          72 :     char       *tmp = PGTYPESdate_to_asc(d);
     486             : 
     487          72 :     if (!tmp)
     488           0 :         return ECPG_INFORMIX_DATE_CONVERT;
     489             : 
     490             :     /* move to user allocated buffer */
     491          72 :     strcpy(str, tmp);
     492          72 :     free(tmp);
     493             : 
     494          72 :     return 0;
     495             : }
     496             : 
     497             : /*
     498             : *
     499             : * the input for this function is mmddyyyy and any non-numeric
     500             : * character can be used as a separator
     501             : *
     502             : */
     503             : int
     504           8 : rstrdate(const char *str, date * d)
     505             : {
     506           8 :     return rdefmtdate(d, "mm/dd/yyyy", str);
     507             : }
     508             : 
     509             : void
     510           0 : rtoday(date * d)
     511             : {
     512           0 :     PGTYPESdate_today(d);
     513           0 : }
     514             : 
     515             : int
     516           0 : rjulmdy(date d, short *mdy)
     517             : {
     518             :     int         mdy_int[3];
     519             : 
     520           0 :     PGTYPESdate_julmdy(d, mdy_int);
     521           0 :     mdy[0] = (short) mdy_int[0];
     522           0 :     mdy[1] = (short) mdy_int[1];
     523           0 :     mdy[2] = (short) mdy_int[2];
     524           0 :     return 0;
     525             : }
     526             : 
     527             : int
     528          88 : rdefmtdate(date * d, const char *fmt, const char *str)
     529             : {
     530             :     /* TODO: take care of DBCENTURY environment variable */
     531             :     /* PGSQL functions allow all centuries */
     532             : 
     533          88 :     errno = 0;
     534          88 :     if (PGTYPESdate_defmt_asc(d, fmt, str) == 0)
     535          68 :         return 0;
     536             : 
     537          20 :     switch (errno)
     538             :     {
     539           8 :         case PGTYPES_DATE_ERR_ENOSHORTDATE:
     540           8 :             return ECPG_INFORMIX_ENOSHORTDATE;
     541           4 :         case PGTYPES_DATE_ERR_EARGS:
     542             :         case PGTYPES_DATE_ERR_ENOTDMY:
     543           4 :             return ECPG_INFORMIX_ENOTDMY;
     544           4 :         case PGTYPES_DATE_BAD_DAY:
     545           4 :             return ECPG_INFORMIX_BAD_DAY;
     546           4 :         case PGTYPES_DATE_BAD_MONTH:
     547           4 :             return ECPG_INFORMIX_BAD_MONTH;
     548           0 :         default:
     549           0 :             return ECPG_INFORMIX_BAD_YEAR;
     550             :     }
     551             : }
     552             : 
     553             : int
     554          48 : rfmtdate(date d, const char *fmt, char *str)
     555             : {
     556          48 :     errno = 0;
     557          48 :     if (PGTYPESdate_fmt_asc(d, fmt, str) == 0)
     558          48 :         return 0;
     559             : 
     560           0 :     if (errno == ENOMEM)
     561           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     562             : 
     563           0 :     return ECPG_INFORMIX_DATE_CONVERT;
     564             : }
     565             : 
     566             : int
     567           4 : rmdyjul(short *mdy, date * d)
     568             : {
     569             :     int         mdy_int[3];
     570             : 
     571           4 :     mdy_int[0] = mdy[0];
     572           4 :     mdy_int[1] = mdy[1];
     573           4 :     mdy_int[2] = mdy[2];
     574           4 :     PGTYPESdate_mdyjul(mdy_int, d);
     575           4 :     return 0;
     576             : }
     577             : 
     578             : int
     579           0 : rdayofweek(date d)
     580             : {
     581           0 :     return PGTYPESdate_dayofweek(d);
     582             : }
     583             : 
     584             : /* And the datetime stuff */
     585             : 
     586             : void
     587           0 : dtcurrent(timestamp * ts)
     588             : {
     589           0 :     PGTYPEStimestamp_current(ts);
     590           0 : }
     591             : 
     592             : int
     593           0 : dtcvasc(char *str, timestamp * ts)
     594             : {
     595             :     timestamp   ts_tmp;
     596             :     int         i;
     597           0 :     char      **endptr = &str;
     598             : 
     599           0 :     errno = 0;
     600           0 :     ts_tmp = PGTYPEStimestamp_from_asc(str, endptr);
     601           0 :     i = errno;
     602           0 :     if (i)
     603             :         /* TODO: rewrite to Informix error codes */
     604           0 :         return i;
     605           0 :     if (**endptr)
     606             :     {
     607             :         /* extra characters exist at the end */
     608           0 :         return ECPG_INFORMIX_EXTRA_CHARS;
     609             :     }
     610             :     /* TODO: other Informix error codes missing */
     611             : 
     612             :     /* everything went fine */
     613           0 :     *ts = ts_tmp;
     614             : 
     615           0 :     return 0;
     616             : }
     617             : 
     618             : int
     619           0 : dtcvfmtasc(char *inbuf, char *fmtstr, timestamp * dtvalue)
     620             : {
     621           0 :     return PGTYPEStimestamp_defmt_asc(inbuf, fmtstr, dtvalue);
     622             : }
     623             : 
     624             : int
     625           0 : dtsub(timestamp * ts1, timestamp * ts2, interval * iv)
     626             : {
     627           0 :     return PGTYPEStimestamp_sub(ts1, ts2, iv);
     628             : }
     629             : 
     630             : int
     631           0 : dttoasc(timestamp * ts, char *output)
     632             : {
     633           0 :     char       *asctime = PGTYPEStimestamp_to_asc(*ts);
     634             : 
     635           0 :     strcpy(output, asctime);
     636           0 :     free(asctime);
     637           0 :     return 0;
     638             : }
     639             : 
     640             : int
     641           0 : dttofmtasc(timestamp * ts, char *output, int str_len, char *fmtstr)
     642             : {
     643           0 :     return PGTYPEStimestamp_fmt_asc(ts, output, str_len, fmtstr);
     644             : }
     645             : 
     646             : int
     647           0 : intoasc(interval * i, char *str)
     648             : {
     649             :     char       *tmp;
     650             : 
     651           0 :     errno = 0;
     652           0 :     tmp = PGTYPESinterval_to_asc(i);
     653             : 
     654           0 :     if (!tmp)
     655           0 :         return -errno;
     656             : 
     657           0 :     memcpy(str, tmp, strlen(tmp));
     658           0 :     free(tmp);
     659           0 :     return 0;
     660             : }
     661             : 
     662             : static struct
     663             : {
     664             :     long        val;
     665             :     int         maxdigits;
     666             :     int         digits;
     667             :     int         remaining;
     668             :     char        sign;
     669             :     char       *val_string;
     670             : }           value;
     671             : 
     672             : /**
     673             :  * initialize the struct, which holds the different forms
     674             :  * of the long value
     675             :  */
     676             : static int
     677          40 : initValue(long lng_val)
     678             : {
     679             :     int         i,
     680             :                 j;
     681             :     long        l,
     682             :                 dig;
     683             : 
     684             :     /* set some obvious things */
     685          40 :     value.val = lng_val >= 0 ? lng_val : lng_val * (-1);
     686          40 :     value.sign = lng_val >= 0 ? '+' : '-';
     687          40 :     value.maxdigits = log10(2) * (8 * sizeof(long) - 1);
     688             : 
     689             :     /* determine the number of digits */
     690          40 :     i = 0;
     691          40 :     l = 1;
     692             :     do
     693             :     {
     694         280 :         i++;
     695         280 :         l *= 10;
     696             :     }
     697         280 :     while ((l - 1) < value.val && l <= LONG_MAX / 10);
     698             : 
     699          40 :     if (l <= LONG_MAX / 10)
     700             :     {
     701          40 :         value.digits = i;
     702          40 :         l /= 10;
     703             :     }
     704             :     else
     705           0 :         value.digits = i + 1;
     706             : 
     707          40 :     value.remaining = value.digits;
     708             : 
     709             :     /* convert the long to string */
     710          40 :     if ((value.val_string = (char *) malloc(value.digits + 1)) == NULL)
     711           0 :         return -1;
     712          40 :     dig = value.val;
     713         320 :     for (i = value.digits, j = 0; i > 0; i--, j++)
     714             :     {
     715         280 :         value.val_string[j] = dig / l + '0';
     716         280 :         dig = dig % l;
     717         280 :         l /= 10;
     718             :     }
     719          40 :     value.val_string[value.digits] = '\0';
     720          40 :     return 0;
     721             : }
     722             : 
     723             : /* return the position of the right-most dot in some string */
     724             : static int
     725          40 : getRightMostDot(const char *str)
     726             : {
     727          40 :     size_t      len = strlen(str);
     728             :     int         i,
     729             :                 j;
     730             : 
     731          40 :     j = 0;
     732         504 :     for (i = len - 1; i >= 0; i--)
     733             :     {
     734         480 :         if (str[i] == '.')
     735          16 :             return len - j - 1;
     736         464 :         j++;
     737             :     }
     738          24 :     return -1;
     739             : }
     740             : 
     741             : /* And finally some misc functions */
     742             : int
     743          40 : rfmtlong(long lng_val, const char *fmt, char *outbuf)
     744             : {
     745          40 :     size_t      fmt_len = strlen(fmt);
     746             :     size_t      temp_len;
     747             :     int         i,
     748             :                 j,              /* position in temp */
     749             :                 k,
     750             :                 dotpos;
     751          40 :     int         leftalign = 0,
     752          40 :                 blank = 0,
     753          40 :                 sign = 0,
     754          40 :                 entitydone = 0,
     755          40 :                 signdone = 0,
     756          40 :                 brackets_ok = 0;
     757             :     char       *temp;
     758          40 :     char        tmp[2] = " ";
     759          40 :     char        lastfmt = ' ',
     760          40 :                 fmtchar = ' ';
     761             : 
     762          40 :     temp = (char *) malloc(fmt_len + 1);
     763          40 :     if (!temp)
     764             :     {
     765           0 :         errno = ENOMEM;
     766           0 :         return -1;
     767             :     }
     768             : 
     769             :     /* put all info about the long in a struct */
     770          40 :     if (initValue(lng_val) == -1)
     771             :     {
     772           0 :         free(temp);
     773           0 :         errno = ENOMEM;
     774           0 :         return -1;
     775             :     }
     776             : 
     777             :     /* '<' is the only format, where we have to align left */
     778          40 :     if (strchr(fmt, (int) '<'))
     779          12 :         leftalign = 1;
     780             : 
     781             :     /* '(' requires ')' */
     782          40 :     if (strchr(fmt, (int) '(') && strchr(fmt, (int) ')'))
     783           4 :         brackets_ok = 1;
     784             : 
     785             :     /* get position of the right-most dot in the format-string */
     786             :     /* and fill the temp-string wit '0's up to there. */
     787          40 :     dotpos = getRightMostDot(fmt);
     788             : 
     789             :     /* start to parse the format-string */
     790          40 :     temp[0] = '\0';
     791          40 :     k = value.digits - 1;       /* position in the value_string */
     792         756 :     for (i = fmt_len - 1, j = 0; i >= 0; i--, j++)
     793             :     {
     794             :         /* qualify, where we are in the value_string */
     795         716 :         if (k < 0)
     796             :         {
     797         360 :             blank = 1;
     798         360 :             if (k == -1)
     799         120 :                 sign = 1;
     800         360 :             if (leftalign)
     801             :             {
     802             :                 /* can't use strncat(,,0) here, Solaris would freak out */
     803          92 :                 if (sign)
     804          92 :                     if (signdone)
     805             :                     {
     806           0 :                         temp[j] = '\0';
     807           0 :                         break;
     808             :                     }
     809             :             }
     810             :         }
     811             :         /* if we're right side of the right-most dot, print '0' */
     812         716 :         if (dotpos >= 0 && dotpos <= i)
     813             :         {
     814          44 :             if (dotpos < i)
     815             :             {
     816          28 :                 if (fmt[i] == ')')
     817           4 :                     tmp[0] = value.sign == '-' ? ')' : ' ';
     818             :                 else
     819          24 :                     tmp[0] = '0';
     820             :             }
     821             :             else
     822          16 :                 tmp[0] = '.';
     823          44 :             strcat(temp, tmp);
     824          44 :             continue;
     825             :         }
     826             :         /* the ',' needs special attention, if it is in the blank area */
     827         672 :         if (blank && fmt[i] == ',')
     828          16 :             fmtchar = lastfmt;
     829             :         else
     830         656 :             fmtchar = fmt[i];
     831             :         /* waiting for the sign */
     832         672 :         if (k < 0 && leftalign && sign && !signdone && fmtchar != '+' && fmtchar != '-')
     833          84 :             continue;
     834             :         /* analyse this format-char */
     835         588 :         switch (fmtchar)
     836             :         {
     837          32 :             case ',':
     838          32 :                 tmp[0] = ',';
     839          32 :                 k++;
     840          32 :                 break;
     841          96 :             case '*':
     842          96 :                 if (blank)
     843          40 :                     tmp[0] = '*';
     844             :                 else
     845          56 :                     tmp[0] = value.val_string[k];
     846          96 :                 break;
     847          44 :             case '&':
     848          44 :                 if (blank)
     849          16 :                     tmp[0] = '0';
     850             :                 else
     851          28 :                     tmp[0] = value.val_string[k];
     852          44 :                 break;
     853         192 :             case '#':
     854         192 :                 if (blank)
     855         120 :                     tmp[0] = ' ';
     856             :                 else
     857          72 :                     tmp[0] = value.val_string[k];
     858         192 :                 break;
     859          24 :             case '-':
     860          24 :                 if (sign && value.sign == '-' && !signdone)
     861             :                 {
     862           8 :                     tmp[0] = '-';
     863           8 :                     signdone = 1;
     864             :                 }
     865          16 :                 else if (blank)
     866          12 :                     tmp[0] = ' ';
     867             :                 else
     868           4 :                     tmp[0] = value.val_string[k];
     869          24 :                 break;
     870          32 :             case '+':
     871          32 :                 if (sign && !signdone)
     872             :                 {
     873          12 :                     tmp[0] = value.sign;
     874          12 :                     signdone = 1;
     875             :                 }
     876          20 :                 else if (blank)
     877          12 :                     tmp[0] = ' ';
     878             :                 else
     879           8 :                     tmp[0] = value.val_string[k];
     880          32 :                 break;
     881           4 :             case '(':
     882           4 :                 if (sign && brackets_ok && value.sign == '-')
     883           4 :                     tmp[0] = '(';
     884           0 :                 else if (blank)
     885           0 :                     tmp[0] = ' ';
     886             :                 else
     887           0 :                     tmp[0] = value.val_string[k];
     888           4 :                 break;
     889           0 :             case ')':
     890           0 :                 if (brackets_ok && value.sign == '-')
     891           0 :                     tmp[0] = ')';
     892             :                 else
     893           0 :                     tmp[0] = ' ';
     894           0 :                 break;
     895          60 :             case '$':
     896          60 :                 if (blank && !entitydone)
     897             :                 {
     898          12 :                     tmp[0] = '$';
     899          12 :                     entitydone = 1;
     900             :                 }
     901          48 :                 else if (blank)
     902          20 :                     tmp[0] = ' ';
     903             :                 else
     904          28 :                     tmp[0] = value.val_string[k];
     905          60 :                 break;
     906          84 :             case '<':
     907          84 :                 tmp[0] = value.val_string[k];
     908          84 :                 break;
     909          20 :             default:
     910          20 :                 tmp[0] = fmt[i];
     911             :         }
     912         588 :         strcat(temp, tmp);
     913         588 :         lastfmt = fmt[i];
     914         588 :         k--;
     915             :     }
     916             :     /* safety-net */
     917          40 :     temp[fmt_len] = '\0';
     918             : 
     919             :     /* reverse the temp-string and put it into the outbuf */
     920          40 :     temp_len = strlen(temp);
     921          40 :     outbuf[0] = '\0';
     922         672 :     for (i = temp_len - 1; i >= 0; i--)
     923             :     {
     924         632 :         tmp[0] = temp[i];
     925         632 :         strcat(outbuf, tmp);
     926             :     }
     927          40 :     outbuf[temp_len] = '\0';
     928             : 
     929             :     /* cleaning up */
     930          40 :     free(temp);
     931          40 :     free(value.val_string);
     932             : 
     933          40 :     return 0;
     934             : }
     935             : 
     936             : void
     937           4 : rupshift(char *str)
     938             : {
     939          64 :     for (; *str != '\0'; str++)
     940          60 :         if (islower((unsigned char) *str))
     941          36 :             *str = toupper((unsigned char) *str);
     942           4 : }
     943             : 
     944             : int
     945          32 : byleng(char *str, int len)
     946             : {
     947          72 :     for (len--; str[len] && str[len] == ' '; len--);
     948          32 :     return (len + 1);
     949             : }
     950             : 
     951             : void
     952          16 : ldchar(char *src, int len, char *dest)
     953             : {
     954          16 :     int         dlen = byleng(src, len);
     955             : 
     956          16 :     memmove(dest, src, dlen);
     957          16 :     dest[dlen] = '\0';
     958          16 : }
     959             : 
     960             : int
     961           0 : rgetmsg(int msgnum, char *s, int maxsize)
     962             : {
     963             :     (void) msgnum;              /* keep the compiler quiet */
     964             :     (void) s;                   /* keep the compiler quiet */
     965             :     (void) maxsize;             /* keep the compiler quiet */
     966           0 :     return 0;
     967             : }
     968             : 
     969             : int
     970           0 : rtypalign(int offset, int type)
     971             : {
     972             :     (void) offset;              /* keep the compiler quiet */
     973             :     (void) type;                /* keep the compiler quiet */
     974           0 :     return 0;
     975             : }
     976             : 
     977             : int
     978           0 : rtypmsize(int type, int len)
     979             : {
     980             :     (void) type;                /* keep the compiler quiet */
     981             :     (void) len;                 /* keep the compiler quiet */
     982           0 :     return 0;
     983             : }
     984             : 
     985             : int
     986           0 : rtypwidth(int sqltype, int sqllen)
     987             : {
     988             :     (void) sqltype;             /* keep the compiler quiet */
     989             :     (void) sqllen;              /* keep the compiler quiet */
     990           0 :     return 0;
     991             : }
     992             : 
     993             : void
     994           0 : ECPG_informix_set_var(int number, void *pointer, int lineno)
     995             : {
     996           0 :     ECPGset_var(number, pointer, lineno);
     997           0 : }
     998             : 
     999             : void *
    1000           0 : ECPG_informix_get_var(int number)
    1001             : {
    1002           0 :     return ECPGget_var(number);
    1003             : }
    1004             : 
    1005             : void
    1006           0 : ECPG_informix_reset_sqlca(void)
    1007             : {
    1008           0 :     struct sqlca_t *sqlca = ECPGget_sqlca();
    1009             : 
    1010           0 :     if (sqlca == NULL)
    1011           0 :         return;
    1012             : 
    1013           0 :     memcpy((char *) sqlca, (char *) &sqlca_init, sizeof(struct sqlca_t));
    1014             : }
    1015             : 
    1016             : int
    1017        7052 : rsetnull(int t, char *ptr)
    1018             : {
    1019        7052 :     ECPGset_noind_null(t, ptr);
    1020        7052 :     return 0;
    1021             : }
    1022             : 
    1023             : int
    1024       10984 : risnull(int t, const char *ptr)
    1025             : {
    1026       10984 :     return ECPGis_noind_null(t, ptr);
    1027             : }

Generated by: LCOV version 1.14