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