Age Owner 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
6347 bruce 48 CBC 247 : deccall2(decimal *arg1, decimal *arg2, int (*ptr) (numeric *, numeric *))
49 : {
50 : numeric *a1,
51 : *a2;
52 : int i;
53 :
7222 meskes 54 247 : if ((a1 = PGTYPESnumeric_new()) == NULL)
7139 meskes 55 UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
56 :
7222 meskes 57 CBC 247 : if ((a2 = PGTYPESnumeric_new()) == NULL)
58 : {
7222 meskes 59 UBC 0 : PGTYPESnumeric_free(a1);
7139 60 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
61 : }
62 :
7222 meskes 63 CBC 247 : if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
64 : {
7222 meskes 65 UBC 0 : PGTYPESnumeric_free(a1);
66 0 : PGTYPESnumeric_free(a2);
7139 67 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
68 : }
69 :
7222 meskes 70 CBC 247 : if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
71 : {
7222 meskes 72 UBC 0 : PGTYPESnumeric_free(a1);
73 0 : PGTYPESnumeric_free(a2);
7139 74 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
75 : }
76 :
7188 bruce 77 CBC 247 : i = (*ptr) (a1, a2);
78 :
7222 meskes 79 247 : PGTYPESnumeric_free(a1);
80 247 : PGTYPESnumeric_free(a2);
81 :
2061 peter_e 82 247 : return i;
83 : }
84 :
85 : static int
6347 bruce 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 : */
7101 meskes 97 901 : if (risnull(CDECIMALTYPE, (char *) arg1) || risnull(CDECIMALTYPE, (char *) arg2))
7214 98 116 : return 0;
99 :
7222 100 785 : if ((a1 = PGTYPESnumeric_new()) == NULL)
7139 meskes 101 UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
102 :
7222 meskes 103 CBC 785 : if ((a2 = PGTYPESnumeric_new()) == NULL)
104 : {
7222 meskes 105 UBC 0 : PGTYPESnumeric_free(a1);
7139 106 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
107 : }
108 :
7222 meskes 109 CBC 785 : if ((nres = PGTYPESnumeric_new()) == NULL)
110 : {
7222 meskes 111 UBC 0 : PGTYPESnumeric_free(a1);
112 0 : PGTYPESnumeric_free(a2);
7139 113 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
114 : }
115 :
7222 meskes 116 CBC 785 : if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
117 : {
7222 meskes 118 UBC 0 : PGTYPESnumeric_free(a1);
119 0 : PGTYPESnumeric_free(a2);
120 0 : PGTYPESnumeric_free(nres);
7139 121 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
122 : }
123 :
7222 meskes 124 CBC 785 : if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
125 : {
7222 meskes 126 UBC 0 : PGTYPESnumeric_free(a1);
127 0 : PGTYPESnumeric_free(a2);
128 0 : PGTYPESnumeric_free(nres);
7139 129 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
130 : }
131 :
7188 bruce 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 */
6965 meskes 138 771 : rsetnull(CDECIMALTYPE, (char *) result);
7222 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 :
2061 peter_e 146 785 : return i;
147 : }
148 :
149 : /* we start with the numeric functions */
150 : int
6347 bruce 151 226 : decadd(decimal *arg1, decimal *arg2, decimal *sum)
152 : {
6081 meskes 153 226 : errno = 0;
7222 154 226 : deccall3(arg1, arg2, sum, PGTYPESnumeric_add);
155 :
156 226 : if (errno == PGTYPES_NUM_OVERFLOW)
7139 157 62 : return ECPG_INFORMIX_NUM_OVERFLOW;
6081 158 164 : else if (errno == PGTYPES_NUM_UNDERFLOW)
7139 meskes 159 UBC 0 : return ECPG_INFORMIX_NUM_UNDERFLOW;
6081 meskes 160 CBC 164 : else if (errno != 0)
6081 meskes 161 UBC 0 : return -1;
162 : else
7188 bruce 163 CBC 164 : return 0;
164 : }
165 :
166 : int
6347 167 247 : deccmp(decimal *arg1, decimal *arg2)
168 : {
2061 peter_e 169 247 : return deccall2(arg1, arg2, PGTYPESnumeric_cmp);
170 : }
171 :
172 : void
6347 bruce 173 UBC 0 : deccopy(decimal *src, decimal *target)
174 : {
7152 meskes 175 0 : memcpy(target, src, sizeof(decimal));
7315 176 0 : }
177 :
178 : int
1986 peter_e 179 CBC 16 : deccvasc(const char *cp, int len, decimal *np)
180 : {
181 : char *str;
6031 bruce 182 16 : int ret = 0;
183 : numeric *result;
184 :
7142 meskes 185 16 : rsetnull(CDECIMALTYPE, (char *) np);
7215 186 16 : if (risnull(CSTRINGTYPE, cp))
7215 meskes 187 UBC 0 : return 0;
188 :
1060 tgl 189 CBC 16 : str = pnstrdup(cp, len); /* decimal_in always converts the complete
190 : * string */
7315 meskes 191 16 : if (!str)
7139 meskes 192 UBC 0 : ret = ECPG_INFORMIX_NUM_UNDERFLOW;
193 : else
194 : {
6081 meskes 195 CBC 16 : errno = 0;
7304 196 16 : result = PGTYPESnumeric_from_asc(str, NULL);
197 16 : if (!result)
198 : {
7315 199 1 : switch (errno)
200 : {
7188 bruce 201 UBC 0 : case PGTYPES_NUM_OVERFLOW:
7139 meskes 202 0 : ret = ECPG_INFORMIX_NUM_OVERFLOW;
7188 bruce 203 0 : break;
7188 bruce 204 CBC 1 : case PGTYPES_NUM_BAD_NUMERIC:
7139 meskes 205 1 : ret = ECPG_INFORMIX_BAD_NUMERIC;
7188 bruce 206 1 : break;
7188 bruce 207 UBC 0 : default:
7139 meskes 208 0 : ret = ECPG_INFORMIX_BAD_EXPONENT;
7188 bruce 209 0 : break;
210 : }
211 : }
212 : else
213 : {
5624 bruce 214 CBC 15 : int i = PGTYPESnumeric_to_decimal(result, np);
215 :
4938 meskes 216 15 : PGTYPESnumeric_free(result);
5717 217 15 : if (i != 0)
218 1 : ret = ECPG_INFORMIX_NUM_OVERFLOW;
219 : }
220 : }
221 :
7222 222 16 : free(str);
7315 223 16 : return ret;
224 : }
225 :
226 : int
6347 bruce 227 UBC 0 : deccvdbl(double dbl, decimal *np)
228 : {
229 : numeric *nres;
7188 230 0 : int result = 1;
231 :
7142 meskes 232 0 : rsetnull(CDECIMALTYPE, (char *) np);
7188 bruce 233 0 : if (risnull(CDOUBLETYPE, (char *) &dbl))
7214 meskes 234 0 : return 0;
235 :
6136 236 0 : nres = PGTYPESnumeric_new();
7222 237 0 : if (nres == NULL)
7139 238 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
239 :
7222 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);
2061 peter_e 245 0 : return result;
246 : }
247 :
248 : int
6347 bruce 249 CBC 14 : deccvint(int in, decimal *np)
250 : {
251 : numeric *nres;
7188 252 14 : int result = 1;
253 :
7142 meskes 254 14 : rsetnull(CDECIMALTYPE, (char *) np);
7188 bruce 255 14 : if (risnull(CINTTYPE, (char *) &in))
7214 meskes 256 UBC 0 : return 0;
257 :
6136 meskes 258 CBC 14 : nres = PGTYPESnumeric_new();
7222 259 14 : if (nres == NULL)
7139 meskes 260 UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
261 :
7222 meskes 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);
2061 peter_e 267 14 : return result;
268 : }
269 :
270 : int
6347 bruce 271 11 : deccvlong(long lng, decimal *np)
272 : {
273 : numeric *nres;
7188 274 11 : int result = 1;
275 :
7142 meskes 276 11 : rsetnull(CDECIMALTYPE, (char *) np);
7188 bruce 277 11 : if (risnull(CLONGTYPE, (char *) &lng))
7214 meskes 278 UBC 0 : return 0;
279 :
6136 meskes 280 CBC 11 : nres = PGTYPESnumeric_new();
7222 281 11 : if (nres == NULL)
7139 meskes 282 UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
283 :
7222 meskes 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);
2061 peter_e 289 11 : return result;
290 : }
291 :
292 : int
6347 bruce 293 225 : decdiv(decimal *n1, decimal *n2, decimal *result)
294 : {
295 : int i;
296 :
6081 meskes 297 225 : errno = 0;
7101 298 225 : i = deccall3(n1, n2, result, PGTYPESnumeric_div);
299 :
7315 300 225 : if (i != 0)
301 14 : switch (errno)
302 : {
7188 bruce 303 14 : case PGTYPES_NUM_DIVIDE_ZERO:
7139 meskes 304 14 : return ECPG_INFORMIX_DIVIDE_ZERO;
305 : break;
7188 bruce 306 UBC 0 : case PGTYPES_NUM_OVERFLOW:
7139 meskes 307 0 : return ECPG_INFORMIX_NUM_OVERFLOW;
308 : break;
7188 bruce 309 0 : default:
7139 meskes 310 0 : return ECPG_INFORMIX_NUM_UNDERFLOW;
311 : break;
312 : }
313 :
7222 meskes 314 CBC 211 : return 0;
315 : }
316 :
317 : int
6347 bruce 318 225 : decmul(decimal *n1, decimal *n2, decimal *result)
319 : {
320 : int i;
321 :
6081 meskes 322 225 : errno = 0;
7101 323 225 : i = deccall3(n1, n2, result, PGTYPESnumeric_mul);
324 :
7315 325 225 : if (i != 0)
7315 meskes 326 UBC 0 : switch (errno)
327 : {
7188 bruce 328 0 : case PGTYPES_NUM_OVERFLOW:
7139 meskes 329 0 : return ECPG_INFORMIX_NUM_OVERFLOW;
330 : break;
7188 bruce 331 0 : default:
7139 meskes 332 0 : return ECPG_INFORMIX_NUM_UNDERFLOW;
333 : break;
334 : }
335 :
7222 meskes 336 CBC 225 : return 0;
337 : }
338 :
339 : int
6347 bruce 340 225 : decsub(decimal *n1, decimal *n2, decimal *result)
341 : {
342 : int i;
343 :
6081 meskes 344 225 : errno = 0;
7101 345 225 : i = deccall3(n1, n2, result, PGTYPESnumeric_sub);
346 :
7315 347 225 : if (i != 0)
7315 meskes 348 UBC 0 : switch (errno)
349 : {
7188 bruce 350 0 : case PGTYPES_NUM_OVERFLOW:
7139 meskes 351 0 : return ECPG_INFORMIX_NUM_OVERFLOW;
352 : break;
7188 bruce 353 0 : default:
7139 meskes 354 0 : return ECPG_INFORMIX_NUM_UNDERFLOW;
355 : break;
356 : }
357 :
7222 meskes 358 CBC 225 : return 0;
359 : }
360 :
361 : int
6347 bruce 362 939 : dectoasc(decimal *np, char *cp, int len, int right)
363 : {
364 : char *str;
365 : numeric *nres;
366 :
7142 meskes 367 939 : rsetnull(CSTRINGTYPE, (char *) cp);
7188 bruce 368 939 : if (risnull(CDECIMALTYPE, (char *) np))
7215 meskes 369 140 : return 0;
370 :
6136 371 799 : nres = PGTYPESnumeric_new();
372 799 : if (nres == NULL)
6136 meskes 373 UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
374 :
7222 meskes 375 CBC 799 : if (PGTYPESnumeric_from_decimal(np, nres) != 0)
376 : {
6136 meskes 377 UBC 0 : PGTYPESnumeric_free(nres);
7139 378 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
379 : }
380 :
7315 meskes 381 CBC 799 : if (right >= 0)
7222 382 78 : str = PGTYPESnumeric_to_asc(nres, right);
383 : else
7101 384 721 : str = PGTYPESnumeric_to_asc(nres, nres->dscale);
385 :
7222 386 799 : PGTYPESnumeric_free(nres);
7315 387 799 : if (!str)
7315 meskes 388 UBC 0 : return -1;
389 :
390 : /*
391 : * TODO: have to take care of len here and create exponential notation if
392 : * necessary
393 : */
6081 meskes 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
6347 bruce 413 13 : dectodbl(decimal *np, double *dblp)
414 : {
415 : int i;
6136 meskes 416 13 : numeric *nres = PGTYPESnumeric_new();
417 :
7222 418 13 : if (nres == NULL)
7139 meskes 419 UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
420 :
7222 meskes 421 CBC 13 : if (PGTYPESnumeric_from_decimal(np, nres) != 0)
422 : {
6136 meskes 423 UBC 0 : PGTYPESnumeric_free(nres);
7139 424 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
425 : }
426 :
7222 meskes 427 CBC 13 : i = PGTYPESnumeric_to_double(nres, dblp);
428 13 : PGTYPESnumeric_free(nres);
429 :
430 13 : return i;
431 : }
432 :
433 : int
6347 bruce 434 16 : dectoint(decimal *np, int *ip)
435 : {
436 : int ret;
7152 meskes 437 16 : numeric *nres = PGTYPESnumeric_new();
438 :
7222 439 16 : if (nres == NULL)
7139 meskes 440 UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
441 :
7222 meskes 442 CBC 16 : if (PGTYPESnumeric_from_decimal(np, nres) != 0)
443 : {
6136 meskes 444 UBC 0 : PGTYPESnumeric_free(nres);
7139 445 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
446 : }
447 :
7222 meskes 448 CBC 16 : ret = PGTYPESnumeric_to_int(nres, ip);
6131 449 16 : PGTYPESnumeric_free(nres);
450 :
7315 451 16 : if (ret == PGTYPES_NUM_OVERFLOW)
7139 meskes 452 UBC 0 : ret = ECPG_INFORMIX_NUM_OVERFLOW;
453 :
7315 meskes 454 CBC 16 : return ret;
455 : }
456 :
457 : int
6347 bruce 458 14 : dectolong(decimal *np, long *lngp)
459 : {
460 : int ret;
6136 meskes 461 14 : numeric *nres = PGTYPESnumeric_new();
462 :
7222 463 14 : if (nres == NULL)
7139 meskes 464 UBC 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
465 :
7222 meskes 466 CBC 14 : if (PGTYPESnumeric_from_decimal(np, nres) != 0)
467 : {
6136 meskes 468 UBC 0 : PGTYPESnumeric_free(nres);
7139 469 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
470 : }
471 :
7222 meskes 472 CBC 14 : ret = PGTYPESnumeric_to_long(nres, lngp);
6136 473 14 : PGTYPESnumeric_free(nres);
474 :
7315 475 14 : if (ret == PGTYPES_NUM_OVERFLOW)
7139 meskes 476 UBC 0 : ret = ECPG_INFORMIX_NUM_OVERFLOW;
477 :
7315 meskes 478 CBC 14 : return ret;
479 : }
480 :
481 : /* Now the date functions */
482 : int
7151 483 18 : rdatestr(date d, char *str)
484 : {
7188 bruce 485 18 : char *tmp = PGTYPESdate_to_asc(d);
486 :
7315 meskes 487 18 : if (!tmp)
7139 meskes 488 UBC 0 : return ECPG_INFORMIX_DATE_CONVERT;
489 :
490 : /* move to user allocated buffer */
7207 meskes 491 CBC 18 : strcpy(str, tmp);
492 18 : free(tmp);
493 :
7315 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
1986 peter_e 504 2 : rstrdate(const char *str, date * d)
505 : {
6081 meskes 506 2 : return rdefmtdate(d, "mm/dd/yyyy", str);
507 : }
508 :
509 : void
6385 bruce 510 UBC 0 : rtoday(date * d)
511 : {
7315 meskes 512 0 : PGTYPESdate_today(d);
513 0 : }
514 :
515 : int
801 tgl 516 0 : rjulmdy(date d, short *mdy)
517 : {
518 : int mdy_int[3];
519 :
7206 meskes 520 0 : PGTYPESdate_julmdy(d, mdy_int);
7188 bruce 521 0 : mdy[0] = (short) mdy_int[0];
522 0 : mdy[1] = (short) mdy_int[1];
523 0 : mdy[2] = (short) mdy_int[2];
7315 meskes 524 0 : return 0;
525 : }
526 :
527 : int
1986 peter_e 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 :
6081 meskes 533 22 : errno = 0;
7313 534 22 : if (PGTYPESdate_defmt_asc(d, fmt, str) == 0)
7315 535 17 : return 0;
536 :
537 5 : switch (errno)
538 : {
7188 bruce 539 2 : case PGTYPES_DATE_ERR_ENOSHORTDATE:
7139 meskes 540 2 : return ECPG_INFORMIX_ENOSHORTDATE;
7315 541 1 : case PGTYPES_DATE_ERR_EARGS:
542 : case PGTYPES_DATE_ERR_ENOTDMY:
7139 543 1 : return ECPG_INFORMIX_ENOTDMY;
7188 bruce 544 1 : case PGTYPES_DATE_BAD_DAY:
7139 meskes 545 1 : return ECPG_INFORMIX_BAD_DAY;
7188 bruce 546 1 : case PGTYPES_DATE_BAD_MONTH:
7139 meskes 547 1 : return ECPG_INFORMIX_BAD_MONTH;
7188 bruce 548 UBC 0 : default:
7139 meskes 549 0 : return ECPG_INFORMIX_BAD_YEAR;
550 : }
551 : }
552 :
553 : int
1986 peter_e 554 CBC 12 : rfmtdate(date d, const char *fmt, char *str)
555 : {
6081 meskes 556 12 : errno = 0;
7313 557 12 : if (PGTYPESdate_fmt_asc(d, fmt, str) == 0)
7315 558 12 : return 0;
559 :
7315 meskes 560 UBC 0 : if (errno == ENOMEM)
7139 561 0 : return ECPG_INFORMIX_OUT_OF_MEMORY;
562 :
563 0 : return ECPG_INFORMIX_DATE_CONVERT;
564 : }
565 :
566 : int
801 tgl 567 CBC 1 : rmdyjul(short *mdy, date * d)
568 : {
569 : int mdy_int[3];
570 :
7206 meskes 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);
7315 575 1 : return 0;
576 : }
577 :
578 : int
7151 meskes 579 UBC 0 : rdayofweek(date d)
580 : {
2061 peter_e 581 0 : return PGTYPESdate_dayofweek(d);
582 : }
583 :
584 : /* And the datetime stuff */
585 :
586 : void
6385 bruce 587 0 : dtcurrent(timestamp * ts)
588 : {
7188 589 0 : PGTYPEStimestamp_current(ts);
7315 meskes 590 0 : }
591 :
592 : int
6385 bruce 593 0 : dtcvasc(char *str, timestamp * ts)
594 : {
595 : timestamp ts_tmp;
596 : int i;
7188 597 0 : char **endptr = &str;
598 :
6081 meskes 599 0 : errno = 0;
7188 bruce 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 */
7139 meskes 608 0 : return ECPG_INFORMIX_EXTRA_CHARS;
609 : }
610 : /* TODO: other Informix error codes missing */
611 :
612 : /* everything went fine */
7188 bruce 613 0 : *ts = ts_tmp;
614 :
7315 meskes 615 0 : return 0;
616 : }
617 :
618 : int
6081 619 0 : dtcvfmtasc(char *inbuf, char *fmtstr, timestamp * dtvalue)
620 : {
621 0 : return PGTYPEStimestamp_defmt_asc(inbuf, fmtstr, dtvalue);
622 : }
623 :
624 : int
6385 bruce 625 0 : dtsub(timestamp * ts1, timestamp * ts2, interval * iv)
626 : {
7313 meskes 627 0 : return PGTYPEStimestamp_sub(ts1, ts2, iv);
628 : }
629 :
630 : int
6385 bruce 631 0 : dttoasc(timestamp * ts, char *output)
632 : {
7188 633 0 : char *asctime = PGTYPEStimestamp_to_asc(*ts);
634 :
635 0 : strcpy(output, asctime);
7207 meskes 636 0 : free(asctime);
7315 637 0 : return 0;
638 : }
639 :
640 : int
6385 bruce 641 0 : dttofmtasc(timestamp * ts, char *output, int str_len, char *fmtstr)
642 : {
7313 meskes 643 0 : return PGTYPEStimestamp_fmt_asc(ts, output, str_len, fmtstr);
644 : }
645 :
646 : int
6385 bruce 647 0 : intoasc(interval * i, char *str)
648 : {
649 : char *tmp;
650 :
6081 meskes 651 0 : errno = 0;
2858 652 0 : tmp = PGTYPESinterval_to_asc(i);
653 :
654 0 : if (!tmp)
7313 655 0 : return -errno;
656 :
2858 657 0 : memcpy(str, tmp, strlen(tmp));
658 0 : free(tmp);
7315 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
6797 bruce 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
6797 bruce 705 UBC 0 : value.digits = i + 1;
706 :
6797 bruce 707 CBC 10 : value.remaining = value.digits;
708 :
709 : /* convert the long to string */
5624 710 10 : if ((value.val_string = (char *) malloc(value.digits + 1)) == NULL)
5667 meskes 711 UBC 0 : return -1;
6797 bruce 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';
5667 meskes 720 10 : return 0;
721 : }
722 :
723 : /* return the position of the right-most dot in some string */
724 : static int
1986 peter_e 725 10 : getRightMostDot(const char *str)
726 : {
7188 bruce 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;
7278 meskes 736 116 : j++;
737 : }
738 6 : return -1;
739 : }
740 :
741 : /* And finally some misc functions */
742 : int
1986 peter_e 743 10 : rfmtlong(long lng_val, const char *fmt, char *outbuf)
744 : {
7188 bruce 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);
5272 meskes 763 10 : if (!temp)
764 : {
5272 meskes 765 UBC 0 : errno = ENOMEM;
766 0 : return -1;
767 : }
768 :
769 : /* put all info about the long in a struct */
5272 meskes 770 CBC 10 : if (initValue(lng_val) == -1)
771 : {
5272 meskes 772 UBC 0 : free(temp);
5667 773 0 : errno = ENOMEM;
774 0 : return -1;
775 : }
776 :
777 : /* '<' is the only format, where we have to align left */
7188 bruce 778 CBC 10 : if (strchr(fmt, (int) '<'))
7278 meskes 779 3 : leftalign = 1;
780 :
781 : /* '(' requires ')' */
7188 bruce 782 10 : if (strchr(fmt, (int) '(') && strchr(fmt, (int) ')'))
7278 meskes 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';
7188 bruce 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 : {
7278 meskes 797 90 : blank = 1;
4966 798 90 : if (k == -1)
7278 799 30 : sign = 1;
6081 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 : {
6081 meskes 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' */
7188 bruce 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
7278 meskes 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 */
7188 bruce 827 168 : if (blank && fmt[i] == ',')
828 4 : fmtchar = lastfmt;
829 : else
830 164 : fmtchar = fmt[i];
831 : /* waiting for the sign */
6081 meskes 832 168 : if (k < 0 && leftalign && sign && !signdone && fmtchar != '+' && fmtchar != '-')
833 21 : continue;
834 : /* analyse this format-char */
7188 bruce 835 147 : switch (fmtchar)
836 : {
7278 meskes 837 8 : case ',':
838 8 : tmp[0] = ',';
839 8 : k++;
840 8 : break;
841 24 : case '*':
7188 bruce 842 24 : if (blank)
843 10 : tmp[0] = '*';
844 : else
845 14 : tmp[0] = value.val_string[k];
7278 meskes 846 24 : break;
847 11 : case '&':
7188 bruce 848 11 : if (blank)
849 4 : tmp[0] = '0';
850 : else
851 7 : tmp[0] = value.val_string[k];
7278 meskes 852 11 : break;
853 48 : case '#':
7188 bruce 854 48 : if (blank)
855 30 : tmp[0] = ' ';
856 : else
857 18 : tmp[0] = value.val_string[k];
7278 meskes 858 48 : break;
859 6 : case '-':
7188 bruce 860 6 : if (sign && value.sign == '-' && !signdone)
861 : {
7278 meskes 862 2 : tmp[0] = '-';
863 2 : signdone = 1;
864 : }
7188 bruce 865 4 : else if (blank)
866 3 : tmp[0] = ' ';
867 : else
868 1 : tmp[0] = value.val_string[k];
7278 meskes 869 6 : break;
870 8 : case '+':
7188 bruce 871 8 : if (sign && !signdone)
872 : {
7278 meskes 873 3 : tmp[0] = value.sign;
874 3 : signdone = 1;
875 : }
7188 bruce 876 5 : else if (blank)
877 3 : tmp[0] = ' ';
878 : else
879 2 : tmp[0] = value.val_string[k];
7278 meskes 880 8 : break;
881 1 : case '(':
7188 bruce 882 1 : if (sign && brackets_ok && value.sign == '-')
883 1 : tmp[0] = '(';
7188 bruce 884 UBC 0 : else if (blank)
885 0 : tmp[0] = ' ';
886 : else
887 0 : tmp[0] = value.val_string[k];
7278 meskes 888 CBC 1 : break;
7278 meskes 889 UBC 0 : case ')':
7188 bruce 890 0 : if (brackets_ok && value.sign == '-')
891 0 : tmp[0] = ')';
892 : else
893 0 : tmp[0] = ' ';
7278 meskes 894 0 : break;
7278 meskes 895 CBC 15 : case '$':
7188 bruce 896 15 : if (blank && !entitydone)
897 : {
7278 meskes 898 3 : tmp[0] = '$';
899 3 : entitydone = 1;
900 : }
7188 bruce 901 12 : else if (blank)
902 5 : tmp[0] = ' ';
903 : else
904 7 : tmp[0] = value.val_string[k];
7278 meskes 905 15 : break;
6081 906 21 : case '<':
907 21 : tmp[0] = value.val_string[k];
908 21 : break;
7188 bruce 909 5 : default:
910 5 : tmp[0] = fmt[i];
911 : }
7278 meskes 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';
7188 bruce 922 168 : for (i = temp_len - 1; i >= 0; i--)
923 : {
7278 meskes 924 158 : tmp[0] = temp[i];
7188 bruce 925 158 : strcat(outbuf, tmp);
926 : }
7278 meskes 927 10 : outbuf[temp_len] = '\0';
928 :
929 : /* cleaning up */
7191 tgl 930 10 : free(temp);
7278 meskes 931 10 : free(value.val_string);
932 :
7315 933 10 : return 0;
934 : }
935 :
936 : void
7270 937 1 : rupshift(char *str)
938 : {
939 16 : for (; *str != '\0'; str++)
7035 tgl 940 15 : if (islower((unsigned char) *str))
941 9 : *str = toupper((unsigned char) *str);
7270 meskes 942 1 : }
943 :
944 : int
945 8 : byleng(char *str, int len)
946 : {
7188 bruce 947 18 : for (len--; str[len] && str[len] == ' '; len--);
948 8 : return (len + 1);
949 : }
950 :
951 : void
7270 meskes 952 4 : ldchar(char *src, int len, char *dest)
953 : {
6031 bruce 954 4 : int dlen = byleng(src, len);
955 :
6081 meskes 956 4 : memmove(dest, src, dlen);
957 4 : dest[dlen] = '\0';
7270 958 4 : }
959 :
960 : int
7315 meskes 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
7270 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
7240 994 0 : ECPG_informix_set_var(int number, void *pointer, int lineno)
995 : {
4821 996 0 : ECPGset_var(number, pointer, lineno);
7240 997 0 : }
998 :
999 : void *
1000 0 : ECPG_informix_get_var(int number)
1001 : {
4821 1002 0 : return ECPGget_var(number);
1003 : }
1004 :
1005 : void
4986 1006 0 : ECPG_informix_reset_sqlca(void)
1007 : {
1008 0 : struct sqlca_t *sqlca = ECPGget_sqlca();
1009 :
2855 1010 0 : if (sqlca == NULL)
1011 0 : return;
1012 :
4986 1013 0 : memcpy((char *) sqlca, (char *) &sqlca_init, sizeof(struct sqlca_t));
1014 : }
1015 :
1016 : int
7188 bruce 1017 CBC 1763 : rsetnull(int t, char *ptr)
1018 : {
6860 meskes 1019 1763 : ECPGset_noind_null(t, ptr);
7228 1020 1763 : return 0;
1021 : }
1022 :
1023 : int
1986 peter_e 1024 2746 : risnull(int t, const char *ptr)
1025 : {
2061 1026 2746 : return ECPGis_noind_null(t, ptr);
1027 : }
|