LCOV - differential code coverage report
Current view: top level - src/interfaces/ecpg/compatlib - informix.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 66.0 % 491 324 167 324
Current Date: 2023-04-08 15:15:32 Functions: 58.7 % 46 27 19 27
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  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 CBC         247 : deccall2(decimal *arg1, decimal *arg2, int (*ptr) (numeric *, numeric *))
      49                 : {
      50                 :     numeric    *a1,
      51                 :                *a2;
      52                 :     int         i;
      53                 : 
      54             247 :     if ((a1 = PGTYPESnumeric_new()) == NULL)
      55 UBC           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
      56                 : 
      57 CBC         247 :     if ((a2 = PGTYPESnumeric_new()) == NULL)
      58                 :     {
      59 UBC           0 :         PGTYPESnumeric_free(a1);
      60               0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
      61                 :     }
      62                 : 
      63 CBC         247 :     if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
      64                 :     {
      65 UBC           0 :         PGTYPESnumeric_free(a1);
      66               0 :         PGTYPESnumeric_free(a2);
      67               0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
      68                 :     }
      69                 : 
      70 CBC         247 :     if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
      71                 :     {
      72 UBC           0 :         PGTYPESnumeric_free(a1);
      73               0 :         PGTYPESnumeric_free(a2);
      74               0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
      75                 :     }
      76                 : 
      77 CBC         247 :     i = (*ptr) (a1, a2);
      78                 : 
      79             247 :     PGTYPESnumeric_free(a1);
      80             247 :     PGTYPESnumeric_free(a2);
      81                 : 
      82             247 :     return i;
      83                 : }
      84                 : 
      85                 : static int
      86             901 : 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             901 :     if (risnull(CDECIMALTYPE, (char *) arg1) || risnull(CDECIMALTYPE, (char *) arg2))
      98             116 :         return 0;
      99                 : 
     100             785 :     if ((a1 = PGTYPESnumeric_new()) == NULL)
     101 UBC           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     102                 : 
     103 CBC         785 :     if ((a2 = PGTYPESnumeric_new()) == NULL)
     104                 :     {
     105 UBC           0 :         PGTYPESnumeric_free(a1);
     106               0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     107                 :     }
     108                 : 
     109 CBC         785 :     if ((nres = PGTYPESnumeric_new()) == NULL)
     110                 :     {
     111 UBC           0 :         PGTYPESnumeric_free(a1);
     112               0 :         PGTYPESnumeric_free(a2);
     113               0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     114                 :     }
     115                 : 
     116 CBC         785 :     if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
     117                 :     {
     118 UBC           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 CBC         785 :     if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
     125                 :     {
     126 UBC           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 CBC         785 :     i = (*ptr) (a1, a2, nres);
     133                 : 
     134             785 :     if (i == 0)                 /* No error */
     135                 :     {
     136                 : 
     137                 :         /* set the result to null in case it errors out later */
     138             771 :         rsetnull(CDECIMALTYPE, (char *) result);
     139             771 :         PGTYPESnumeric_to_decimal(nres, result);
     140                 :     }
     141                 : 
     142             785 :     PGTYPESnumeric_free(nres);
     143             785 :     PGTYPESnumeric_free(a1);
     144             785 :     PGTYPESnumeric_free(a2);
     145                 : 
     146             785 :     return i;
     147                 : }
     148                 : 
     149                 : /* we start with the numeric functions */
     150                 : int
     151             226 : decadd(decimal *arg1, decimal *arg2, decimal *sum)
     152                 : {
     153             226 :     errno = 0;
     154             226 :     deccall3(arg1, arg2, sum, PGTYPESnumeric_add);
     155                 : 
     156             226 :     if (errno == PGTYPES_NUM_OVERFLOW)
     157              62 :         return ECPG_INFORMIX_NUM_OVERFLOW;
     158             164 :     else if (errno == PGTYPES_NUM_UNDERFLOW)
     159 UBC           0 :         return ECPG_INFORMIX_NUM_UNDERFLOW;
     160 CBC         164 :     else if (errno != 0)
     161 UBC           0 :         return -1;
     162                 :     else
     163 CBC         164 :         return 0;
     164                 : }
     165                 : 
     166                 : int
     167             247 : deccmp(decimal *arg1, decimal *arg2)
     168                 : {
     169             247 :     return deccall2(arg1, arg2, PGTYPESnumeric_cmp);
     170                 : }
     171                 : 
     172                 : void
     173 UBC           0 : deccopy(decimal *src, decimal *target)
     174                 : {
     175               0 :     memcpy(target, src, sizeof(decimal));
     176               0 : }
     177                 : 
     178                 : int
     179 CBC          16 : deccvasc(const char *cp, int len, decimal *np)
     180                 : {
     181                 :     char       *str;
     182              16 :     int         ret = 0;
     183                 :     numeric    *result;
     184                 : 
     185              16 :     rsetnull(CDECIMALTYPE, (char *) np);
     186              16 :     if (risnull(CSTRINGTYPE, cp))
     187 UBC           0 :         return 0;
     188                 : 
     189 CBC          16 :     str = pnstrdup(cp, len);    /* decimal_in always converts the complete
     190                 :                                  * string */
     191              16 :     if (!str)
     192 UBC           0 :         ret = ECPG_INFORMIX_NUM_UNDERFLOW;
     193                 :     else
     194                 :     {
     195 CBC          16 :         errno = 0;
     196              16 :         result = PGTYPESnumeric_from_asc(str, NULL);
     197              16 :         if (!result)
     198                 :         {
     199               1 :             switch (errno)
     200                 :             {
     201 UBC           0 :                 case PGTYPES_NUM_OVERFLOW:
     202               0 :                     ret = ECPG_INFORMIX_NUM_OVERFLOW;
     203               0 :                     break;
     204 CBC           1 :                 case PGTYPES_NUM_BAD_NUMERIC:
     205               1 :                     ret = ECPG_INFORMIX_BAD_NUMERIC;
     206               1 :                     break;
     207 UBC           0 :                 default:
     208               0 :                     ret = ECPG_INFORMIX_BAD_EXPONENT;
     209               0 :                     break;
     210                 :             }
     211                 :         }
     212                 :         else
     213                 :         {
     214 CBC          15 :             int         i = PGTYPESnumeric_to_decimal(result, np);
     215                 : 
     216              15 :             PGTYPESnumeric_free(result);
     217              15 :             if (i != 0)
     218               1 :                 ret = ECPG_INFORMIX_NUM_OVERFLOW;
     219                 :         }
     220                 :     }
     221                 : 
     222              16 :     free(str);
     223              16 :     return ret;
     224                 : }
     225                 : 
     226                 : int
     227 UBC           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 CBC          14 : deccvint(int in, decimal *np)
     250                 : {
     251                 :     numeric    *nres;
     252              14 :     int         result = 1;
     253                 : 
     254              14 :     rsetnull(CDECIMALTYPE, (char *) np);
     255              14 :     if (risnull(CINTTYPE, (char *) &in))
     256 UBC           0 :         return 0;
     257                 : 
     258 CBC          14 :     nres = PGTYPESnumeric_new();
     259              14 :     if (nres == NULL)
     260 UBC           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     261                 : 
     262 CBC          14 :     result = PGTYPESnumeric_from_int(in, nres);
     263              14 :     if (result == 0)
     264              14 :         result = PGTYPESnumeric_to_decimal(nres, np);
     265                 : 
     266              14 :     PGTYPESnumeric_free(nres);
     267              14 :     return result;
     268                 : }
     269                 : 
     270                 : int
     271              11 : deccvlong(long lng, decimal *np)
     272                 : {
     273                 :     numeric    *nres;
     274              11 :     int         result = 1;
     275                 : 
     276              11 :     rsetnull(CDECIMALTYPE, (char *) np);
     277              11 :     if (risnull(CLONGTYPE, (char *) &lng))
     278 UBC           0 :         return 0;
     279                 : 
     280 CBC          11 :     nres = PGTYPESnumeric_new();
     281              11 :     if (nres == NULL)
     282 UBC           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     283                 : 
     284 CBC          11 :     result = PGTYPESnumeric_from_long(lng, nres);
     285              11 :     if (result == 0)
     286              11 :         result = PGTYPESnumeric_to_decimal(nres, np);
     287                 : 
     288              11 :     PGTYPESnumeric_free(nres);
     289              11 :     return result;
     290                 : }
     291                 : 
     292                 : int
     293             225 : decdiv(decimal *n1, decimal *n2, decimal *result)
     294                 : {
     295                 :     int         i;
     296                 : 
     297             225 :     errno = 0;
     298             225 :     i = deccall3(n1, n2, result, PGTYPESnumeric_div);
     299                 : 
     300             225 :     if (i != 0)
     301              14 :         switch (errno)
     302                 :         {
     303              14 :             case PGTYPES_NUM_DIVIDE_ZERO:
     304              14 :                 return ECPG_INFORMIX_DIVIDE_ZERO;
     305                 :                 break;
     306 UBC           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 CBC         211 :     return 0;
     315                 : }
     316                 : 
     317                 : int
     318             225 : decmul(decimal *n1, decimal *n2, decimal *result)
     319                 : {
     320                 :     int         i;
     321                 : 
     322             225 :     errno = 0;
     323             225 :     i = deccall3(n1, n2, result, PGTYPESnumeric_mul);
     324                 : 
     325             225 :     if (i != 0)
     326 UBC           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 CBC         225 :     return 0;
     337                 : }
     338                 : 
     339                 : int
     340             225 : decsub(decimal *n1, decimal *n2, decimal *result)
     341                 : {
     342                 :     int         i;
     343                 : 
     344             225 :     errno = 0;
     345             225 :     i = deccall3(n1, n2, result, PGTYPESnumeric_sub);
     346                 : 
     347             225 :     if (i != 0)
     348 UBC           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 CBC         225 :     return 0;
     359                 : }
     360                 : 
     361                 : int
     362             939 : dectoasc(decimal *np, char *cp, int len, int right)
     363                 : {
     364                 :     char       *str;
     365                 :     numeric    *nres;
     366                 : 
     367             939 :     rsetnull(CSTRINGTYPE, (char *) cp);
     368             939 :     if (risnull(CDECIMALTYPE, (char *) np))
     369             140 :         return 0;
     370                 : 
     371             799 :     nres = PGTYPESnumeric_new();
     372             799 :     if (nres == NULL)
     373 UBC           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     374                 : 
     375 CBC         799 :     if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     376                 :     {
     377 UBC           0 :         PGTYPESnumeric_free(nres);
     378               0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     379                 :     }
     380                 : 
     381 CBC         799 :     if (right >= 0)
     382              78 :         str = PGTYPESnumeric_to_asc(nres, right);
     383                 :     else
     384             721 :         str = PGTYPESnumeric_to_asc(nres, nres->dscale);
     385                 : 
     386             799 :     PGTYPESnumeric_free(nres);
     387             799 :     if (!str)
     388 UBC           0 :         return -1;
     389                 : 
     390                 :     /*
     391                 :      * TODO: have to take care of len here and create exponential notation if
     392                 :      * necessary
     393                 :      */
     394 CBC         799 :     if ((int) (strlen(str) + 1) > len)
     395                 :     {
     396             111 :         if (len > 1)
     397                 :         {
     398             109 :             cp[0] = '*';
     399             109 :             cp[1] = '\0';
     400                 :         }
     401             111 :         free(str);
     402             111 :         return -1;
     403                 :     }
     404                 :     else
     405                 :     {
     406             688 :         strcpy(cp, str);
     407             688 :         free(str);
     408             688 :         return 0;
     409                 :     }
     410                 : }
     411                 : 
     412                 : int
     413              13 : dectodbl(decimal *np, double *dblp)
     414                 : {
     415                 :     int         i;
     416              13 :     numeric    *nres = PGTYPESnumeric_new();
     417                 : 
     418              13 :     if (nres == NULL)
     419 UBC           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     420                 : 
     421 CBC          13 :     if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     422                 :     {
     423 UBC           0 :         PGTYPESnumeric_free(nres);
     424               0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     425                 :     }
     426                 : 
     427 CBC          13 :     i = PGTYPESnumeric_to_double(nres, dblp);
     428              13 :     PGTYPESnumeric_free(nres);
     429                 : 
     430              13 :     return i;
     431                 : }
     432                 : 
     433                 : int
     434              16 : dectoint(decimal *np, int *ip)
     435                 : {
     436                 :     int         ret;
     437              16 :     numeric    *nres = PGTYPESnumeric_new();
     438                 : 
     439              16 :     if (nres == NULL)
     440 UBC           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     441                 : 
     442 CBC          16 :     if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     443                 :     {
     444 UBC           0 :         PGTYPESnumeric_free(nres);
     445               0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     446                 :     }
     447                 : 
     448 CBC          16 :     ret = PGTYPESnumeric_to_int(nres, ip);
     449              16 :     PGTYPESnumeric_free(nres);
     450                 : 
     451              16 :     if (ret == PGTYPES_NUM_OVERFLOW)
     452 UBC           0 :         ret = ECPG_INFORMIX_NUM_OVERFLOW;
     453                 : 
     454 CBC          16 :     return ret;
     455                 : }
     456                 : 
     457                 : int
     458              14 : dectolong(decimal *np, long *lngp)
     459                 : {
     460                 :     int         ret;
     461              14 :     numeric    *nres = PGTYPESnumeric_new();
     462                 : 
     463              14 :     if (nres == NULL)
     464 UBC           0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     465                 : 
     466 CBC          14 :     if (PGTYPESnumeric_from_decimal(np, nres) != 0)
     467                 :     {
     468 UBC           0 :         PGTYPESnumeric_free(nres);
     469               0 :         return ECPG_INFORMIX_OUT_OF_MEMORY;
     470                 :     }
     471                 : 
     472 CBC          14 :     ret = PGTYPESnumeric_to_long(nres, lngp);
     473              14 :     PGTYPESnumeric_free(nres);
     474                 : 
     475              14 :     if (ret == PGTYPES_NUM_OVERFLOW)
     476 UBC           0 :         ret = ECPG_INFORMIX_NUM_OVERFLOW;
     477                 : 
     478 CBC          14 :     return ret;
     479                 : }
     480                 : 
     481                 : /* Now the date functions */
     482                 : int
     483              18 : rdatestr(date d, char *str)
     484                 : {
     485              18 :     char       *tmp = PGTYPESdate_to_asc(d);
     486                 : 
     487              18 :     if (!tmp)
     488 UBC           0 :         return ECPG_INFORMIX_DATE_CONVERT;
     489                 : 
     490                 :     /* move to user allocated buffer */
     491 CBC          18 :     strcpy(str, tmp);
     492              18 :     free(tmp);
     493                 : 
     494              18 :     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               2 : rstrdate(const char *str, date * d)
     505                 : {
     506               2 :     return rdefmtdate(d, "mm/dd/yyyy", str);
     507                 : }
     508                 : 
     509                 : void
     510 UBC           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 CBC          22 : 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              22 :     errno = 0;
     534              22 :     if (PGTYPESdate_defmt_asc(d, fmt, str) == 0)
     535              17 :         return 0;
     536                 : 
     537               5 :     switch (errno)
     538                 :     {
     539               2 :         case PGTYPES_DATE_ERR_ENOSHORTDATE:
     540               2 :             return ECPG_INFORMIX_ENOSHORTDATE;
     541               1 :         case PGTYPES_DATE_ERR_EARGS:
     542                 :         case PGTYPES_DATE_ERR_ENOTDMY:
     543               1 :             return ECPG_INFORMIX_ENOTDMY;
     544               1 :         case PGTYPES_DATE_BAD_DAY:
     545               1 :             return ECPG_INFORMIX_BAD_DAY;
     546               1 :         case PGTYPES_DATE_BAD_MONTH:
     547               1 :             return ECPG_INFORMIX_BAD_MONTH;
     548 UBC           0 :         default:
     549               0 :             return ECPG_INFORMIX_BAD_YEAR;
     550                 :     }
     551                 : }
     552                 : 
     553                 : int
     554 CBC          12 : rfmtdate(date d, const char *fmt, char *str)
     555                 : {
     556              12 :     errno = 0;
     557              12 :     if (PGTYPESdate_fmt_asc(d, fmt, str) == 0)
     558              12 :         return 0;
     559                 : 
     560 UBC           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 CBC           1 : rmdyjul(short *mdy, date * d)
     568                 : {
     569                 :     int         mdy_int[3];
     570                 : 
     571               1 :     mdy_int[0] = mdy[0];
     572               1 :     mdy_int[1] = mdy[1];
     573               1 :     mdy_int[2] = mdy[2];
     574               1 :     PGTYPESdate_mdyjul(mdy_int, d);
     575               1 :     return 0;
     576                 : }
     577                 : 
     578                 : int
     579 UBC           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 CBC          10 : initValue(long lng_val)
     678                 : {
     679                 :     int         i,
     680                 :                 j;
     681                 :     long        l,
     682                 :                 dig;
     683                 : 
     684                 :     /* set some obvious things */
     685              10 :     value.val = lng_val >= 0 ? lng_val : lng_val * (-1);
     686              10 :     value.sign = lng_val >= 0 ? '+' : '-';
     687              10 :     value.maxdigits = log10(2) * (8 * sizeof(long) - 1);
     688                 : 
     689                 :     /* determine the number of digits */
     690              10 :     i = 0;
     691              10 :     l = 1;
     692                 :     do
     693                 :     {
     694              70 :         i++;
     695              70 :         l *= 10;
     696                 :     }
     697              70 :     while ((l - 1) < value.val && l <= LONG_MAX / 10);
     698                 : 
     699              10 :     if (l <= LONG_MAX / 10)
     700                 :     {
     701              10 :         value.digits = i;
     702              10 :         l /= 10;
     703                 :     }
     704                 :     else
     705 UBC           0 :         value.digits = i + 1;
     706                 : 
     707 CBC          10 :     value.remaining = value.digits;
     708                 : 
     709                 :     /* convert the long to string */
     710              10 :     if ((value.val_string = (char *) malloc(value.digits + 1)) == NULL)
     711 UBC           0 :         return -1;
     712 CBC          10 :     dig = value.val;
     713              80 :     for (i = value.digits, j = 0; i > 0; i--, j++)
     714                 :     {
     715              70 :         value.val_string[j] = dig / l + '0';
     716              70 :         dig = dig % l;
     717              70 :         l /= 10;
     718                 :     }
     719              10 :     value.val_string[value.digits] = '\0';
     720              10 :     return 0;
     721                 : }
     722                 : 
     723                 : /* return the position of the right-most dot in some string */
     724                 : static int
     725              10 : getRightMostDot(const char *str)
     726                 : {
     727              10 :     size_t      len = strlen(str);
     728                 :     int         i,
     729                 :                 j;
     730                 : 
     731              10 :     j = 0;
     732             126 :     for (i = len - 1; i >= 0; i--)
     733                 :     {
     734             120 :         if (str[i] == '.')
     735               4 :             return len - j - 1;
     736             116 :         j++;
     737                 :     }
     738               6 :     return -1;
     739                 : }
     740                 : 
     741                 : /* And finally some misc functions */
     742                 : int
     743              10 : rfmtlong(long lng_val, const char *fmt, char *outbuf)
     744                 : {
     745              10 :     size_t      fmt_len = strlen(fmt);
     746                 :     size_t      temp_len;
     747                 :     int         i,
     748                 :                 j,              /* position in temp */
     749                 :                 k,
     750                 :                 dotpos;
     751              10 :     int         leftalign = 0,
     752              10 :                 blank = 0,
     753              10 :                 sign = 0,
     754              10 :                 entitydone = 0,
     755              10 :                 signdone = 0,
     756              10 :                 brackets_ok = 0;
     757                 :     char       *temp;
     758              10 :     char        tmp[2] = " ";
     759              10 :     char        lastfmt = ' ',
     760              10 :                 fmtchar = ' ';
     761                 : 
     762              10 :     temp = (char *) malloc(fmt_len + 1);
     763              10 :     if (!temp)
     764                 :     {
     765 UBC           0 :         errno = ENOMEM;
     766               0 :         return -1;
     767                 :     }
     768                 : 
     769                 :     /* put all info about the long in a struct */
     770 CBC          10 :     if (initValue(lng_val) == -1)
     771                 :     {
     772 UBC           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 CBC          10 :     if (strchr(fmt, (int) '<'))
     779               3 :         leftalign = 1;
     780                 : 
     781                 :     /* '(' requires ')' */
     782              10 :     if (strchr(fmt, (int) '(') && strchr(fmt, (int) ')'))
     783               1 :         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              10 :     dotpos = getRightMostDot(fmt);
     788                 : 
     789                 :     /* start to parse the format-string */
     790              10 :     temp[0] = '\0';
     791              10 :     k = value.digits - 1;       /* position in the value_string */
     792             189 :     for (i = fmt_len - 1, j = 0; i >= 0; i--, j++)
     793                 :     {
     794                 :         /* qualify, where we are in the value_string */
     795             179 :         if (k < 0)
     796                 :         {
     797              90 :             blank = 1;
     798              90 :             if (k == -1)
     799              30 :                 sign = 1;
     800              90 :             if (leftalign)
     801                 :             {
     802                 :                 /* can't use strncat(,,0) here, Solaris would freak out */
     803              23 :                 if (sign)
     804              23 :                     if (signdone)
     805                 :                     {
     806 UBC           0 :                         temp[j] = '\0';
     807               0 :                         break;
     808                 :                     }
     809                 :             }
     810                 :         }
     811                 :         /* if we're right side of the right-most dot, print '0' */
     812 CBC         179 :         if (dotpos >= 0 && dotpos <= i)
     813                 :         {
     814              11 :             if (dotpos < i)
     815                 :             {
     816               7 :                 if (fmt[i] == ')')
     817               1 :                     tmp[0] = value.sign == '-' ? ')' : ' ';
     818                 :                 else
     819               6 :                     tmp[0] = '0';
     820                 :             }
     821                 :             else
     822               4 :                 tmp[0] = '.';
     823              11 :             strcat(temp, tmp);
     824              11 :             continue;
     825                 :         }
     826                 :         /* the ',' needs special attention, if it is in the blank area */
     827             168 :         if (blank && fmt[i] == ',')
     828               4 :             fmtchar = lastfmt;
     829                 :         else
     830             164 :             fmtchar = fmt[i];
     831                 :         /* waiting for the sign */
     832             168 :         if (k < 0 && leftalign && sign && !signdone && fmtchar != '+' && fmtchar != '-')
     833              21 :             continue;
     834                 :         /* analyse this format-char */
     835             147 :         switch (fmtchar)
     836                 :         {
     837               8 :             case ',':
     838               8 :                 tmp[0] = ',';
     839               8 :                 k++;
     840               8 :                 break;
     841              24 :             case '*':
     842              24 :                 if (blank)
     843              10 :                     tmp[0] = '*';
     844                 :                 else
     845              14 :                     tmp[0] = value.val_string[k];
     846              24 :                 break;
     847              11 :             case '&':
     848              11 :                 if (blank)
     849               4 :                     tmp[0] = '0';
     850                 :                 else
     851               7 :                     tmp[0] = value.val_string[k];
     852              11 :                 break;
     853              48 :             case '#':
     854              48 :                 if (blank)
     855              30 :                     tmp[0] = ' ';
     856                 :                 else
     857              18 :                     tmp[0] = value.val_string[k];
     858              48 :                 break;
     859               6 :             case '-':
     860               6 :                 if (sign && value.sign == '-' && !signdone)
     861                 :                 {
     862               2 :                     tmp[0] = '-';
     863               2 :                     signdone = 1;
     864                 :                 }
     865               4 :                 else if (blank)
     866               3 :                     tmp[0] = ' ';
     867                 :                 else
     868               1 :                     tmp[0] = value.val_string[k];
     869               6 :                 break;
     870               8 :             case '+':
     871               8 :                 if (sign && !signdone)
     872                 :                 {
     873               3 :                     tmp[0] = value.sign;
     874               3 :                     signdone = 1;
     875                 :                 }
     876               5 :                 else if (blank)
     877               3 :                     tmp[0] = ' ';
     878                 :                 else
     879               2 :                     tmp[0] = value.val_string[k];
     880               8 :                 break;
     881               1 :             case '(':
     882               1 :                 if (sign && brackets_ok && value.sign == '-')
     883               1 :                     tmp[0] = '(';
     884 UBC           0 :                 else if (blank)
     885               0 :                     tmp[0] = ' ';
     886                 :                 else
     887               0 :                     tmp[0] = value.val_string[k];
     888 CBC           1 :                 break;
     889 UBC           0 :             case ')':
     890               0 :                 if (brackets_ok && value.sign == '-')
     891               0 :                     tmp[0] = ')';
     892                 :                 else
     893               0 :                     tmp[0] = ' ';
     894               0 :                 break;
     895 CBC          15 :             case '$':
     896              15 :                 if (blank && !entitydone)
     897                 :                 {
     898               3 :                     tmp[0] = '$';
     899               3 :                     entitydone = 1;
     900                 :                 }
     901              12 :                 else if (blank)
     902               5 :                     tmp[0] = ' ';
     903                 :                 else
     904               7 :                     tmp[0] = value.val_string[k];
     905              15 :                 break;
     906              21 :             case '<':
     907              21 :                 tmp[0] = value.val_string[k];
     908              21 :                 break;
     909               5 :             default:
     910               5 :                 tmp[0] = fmt[i];
     911                 :         }
     912             147 :         strcat(temp, tmp);
     913             147 :         lastfmt = fmt[i];
     914             147 :         k--;
     915                 :     }
     916                 :     /* safety-net */
     917              10 :     temp[fmt_len] = '\0';
     918                 : 
     919                 :     /* reverse the temp-string and put it into the outbuf */
     920              10 :     temp_len = strlen(temp);
     921              10 :     outbuf[0] = '\0';
     922             168 :     for (i = temp_len - 1; i >= 0; i--)
     923                 :     {
     924             158 :         tmp[0] = temp[i];
     925             158 :         strcat(outbuf, tmp);
     926                 :     }
     927              10 :     outbuf[temp_len] = '\0';
     928                 : 
     929                 :     /* cleaning up */
     930              10 :     free(temp);
     931              10 :     free(value.val_string);
     932                 : 
     933              10 :     return 0;
     934                 : }
     935                 : 
     936                 : void
     937               1 : rupshift(char *str)
     938                 : {
     939              16 :     for (; *str != '\0'; str++)
     940              15 :         if (islower((unsigned char) *str))
     941               9 :             *str = toupper((unsigned char) *str);
     942               1 : }
     943                 : 
     944                 : int
     945               8 : byleng(char *str, int len)
     946                 : {
     947              18 :     for (len--; str[len] && str[len] == ' '; len--);
     948               8 :     return (len + 1);
     949                 : }
     950                 : 
     951                 : void
     952               4 : ldchar(char *src, int len, char *dest)
     953                 : {
     954               4 :     int         dlen = byleng(src, len);
     955                 : 
     956               4 :     memmove(dest, src, dlen);
     957               4 :     dest[dlen] = '\0';
     958               4 : }
     959                 : 
     960                 : int
     961 UBC           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 CBC        1763 : rsetnull(int t, char *ptr)
    1018                 : {
    1019            1763 :     ECPGset_noind_null(t, ptr);
    1020            1763 :     return 0;
    1021                 : }
    1022                 : 
    1023                 : int
    1024            2746 : risnull(int t, const char *ptr)
    1025                 : {
    1026            2746 :     return ECPGis_noind_null(t, ptr);
    1027                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a