8 #include <ecpg_informix.h>
9 #include <pgtypes_error.h>
10 #include <pgtypes_date.h>
13 char *ECPGalloc(long, int);
16 deccall2(decimal * arg1, decimal * arg2, int (*ptr) (numeric *, numeric *))
22 if ((a1 = PGTYPESnumeric_new()) == NULL)
25 if ((a2 = PGTYPESnumeric_new()) == NULL)
27 PGTYPESnumeric_free(a1);
31 if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
33 PGTYPESnumeric_free(a1);
34 PGTYPESnumeric_free(a2);
38 if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
40 PGTYPESnumeric_free(a1);
41 PGTYPESnumeric_free(a2);
47 PGTYPESnumeric_free(a1);
48 PGTYPESnumeric_free(a2);
54 deccall3(decimal * arg1, decimal * arg2, decimal * result, int (*ptr) (numeric *, numeric *, numeric *))
61 if (risnull(CDECIMALTYPE, (char *) arg1) || risnull(CDECIMALTYPE, (char *) arg2))
63 rsetnull(CDECIMALTYPE, (char *) result);
67 if ((a1 = PGTYPESnumeric_new()) == NULL)
70 if ((a2 = PGTYPESnumeric_new()) == NULL)
72 PGTYPESnumeric_free(a1);
76 if ((nres = PGTYPESnumeric_new()) == NULL)
78 PGTYPESnumeric_free(a1);
79 PGTYPESnumeric_free(a2);
83 if (PGTYPESnumeric_from_decimal(arg1, a1) != 0)
85 PGTYPESnumeric_free(a1);
86 PGTYPESnumeric_free(a2);
87 PGTYPESnumeric_free(nres);
91 if (PGTYPESnumeric_from_decimal(arg2, a2) != 0)
93 PGTYPESnumeric_free(a1);
94 PGTYPESnumeric_free(a2);
95 PGTYPESnumeric_free(nres);
99 i = (*ptr) (a1, a2, nres);
101 if (i == 0) /* No error */
102 PGTYPESnumeric_to_decimal(nres, result);
104 PGTYPESnumeric_free(nres);
105 PGTYPESnumeric_free(a1);
106 PGTYPESnumeric_free(a2);
111 /* we start with the numeric functions */
113 decadd(decimal * arg1, decimal * arg2, decimal * sum)
115 deccall3(arg1, arg2, sum, PGTYPESnumeric_add);
117 if (errno == PGTYPES_NUM_OVERFLOW)
126 deccmp(decimal * arg1, decimal * arg2)
128 return (deccall2(arg1, arg2, PGTYPESnumeric_cmp));
132 deccopy(decimal * src, decimal * target)
134 memcpy(target, src, sizeof(decimal));
138 strndup(const char *str, size_t len)
140 int real_len = strlen(str);
141 int use_len = (real_len > len) ? len : real_len;
143 char *new = malloc(use_len + 1);
147 memcpy(new, str, use_len);
157 deccvasc(char *cp, int len, decimal * np)
159 char *str = strndup(cp, len); /* decimal_in always converts the
164 if (risnull(CSTRINGTYPE, cp))
166 rsetnull(CDECIMALTYPE, (char *) np);
174 result = PGTYPESnumeric_from_asc(str, NULL);
179 case PGTYPES_NUM_OVERFLOW:
182 case PGTYPES_NUM_BAD_NUMERIC:
192 if (PGTYPESnumeric_to_decimal(result, np) != 0)
204 deccvdbl(double dbl, decimal * np)
206 numeric *nres = PGTYPESnumeric_new();
209 if (risnull(CDOUBLETYPE, (char *) &dbl))
211 rsetnull(CDECIMALTYPE, (char *) np);
218 result = PGTYPESnumeric_from_double(dbl, nres);
220 result = PGTYPESnumeric_to_decimal(nres, np);
222 PGTYPESnumeric_free(nres);
227 deccvint(int in, decimal * np)
229 numeric *nres = PGTYPESnumeric_new();
232 if (risnull(CINTTYPE, (char *) &in))
234 rsetnull(CDECIMALTYPE, (char *) np);
241 result = PGTYPESnumeric_from_int(in, nres);
243 result = PGTYPESnumeric_to_decimal(nres, np);
245 PGTYPESnumeric_free(nres);
250 deccvlong(long lng, decimal * np)
252 numeric *nres = PGTYPESnumeric_new();
255 if (risnull(CLONGTYPE, (char *) &lng))
257 rsetnull(CDECIMALTYPE, (char *) np);
264 result = PGTYPESnumeric_from_long(lng, nres);
266 result = PGTYPESnumeric_to_decimal(nres, np);
268 PGTYPESnumeric_free(nres);
273 decdiv(decimal * n1, decimal * n2, decimal * n3)
275 int i = deccall3(n1, n2, n3, PGTYPESnumeric_div);
280 case PGTYPES_NUM_DIVIDE_ZERO:
283 case PGTYPES_NUM_OVERFLOW:
295 decmul(decimal * n1, decimal * n2, decimal * n3)
297 int i = deccall3(n1, n2, n3, PGTYPESnumeric_mul);
302 case PGTYPES_NUM_OVERFLOW:
314 decsub(decimal * n1, decimal * n2, decimal * n3)
316 int i = deccall3(n1, n2, n3, PGTYPESnumeric_sub);
321 case PGTYPES_NUM_OVERFLOW:
333 dectoasc(decimal * np, char *cp, int len, int right)
336 numeric *nres = PGTYPESnumeric_new();
341 if (risnull(CDECIMALTYPE, (char *) np))
343 rsetnull(CSTRINGTYPE, (char *) cp);
347 if (PGTYPESnumeric_from_decimal(np, nres) != 0)
351 str = PGTYPESnumeric_to_asc(nres, right);
353 str = PGTYPESnumeric_to_asc(nres, 0);
355 PGTYPESnumeric_free(nres);
360 * TODO: have to take care of len here and create exponatial notion if
363 strncpy(cp, str, len);
370 dectodbl(decimal * np, double *dblp)
372 numeric *nres = PGTYPESnumeric_new();
378 if (PGTYPESnumeric_from_decimal(np, nres) != 0)
381 i = PGTYPESnumeric_to_double(nres, dblp);
382 PGTYPESnumeric_free(nres);
388 dectoint(decimal * np, int *ip)
391 numeric *nres = PGTYPESnumeric_new();
396 if (PGTYPESnumeric_from_decimal(np, nres) != 0)
399 ret = PGTYPESnumeric_to_int(nres, ip);
401 if (ret == PGTYPES_NUM_OVERFLOW)
408 dectolong(decimal * np, long *lngp)
411 numeric *nres = PGTYPESnumeric_new();;
416 if (PGTYPESnumeric_from_decimal(np, nres) != 0)
419 ret = PGTYPESnumeric_to_long(nres, lngp);
421 if (ret == PGTYPES_NUM_OVERFLOW)
427 /* Now the date functions */
429 rdatestr(Date d, char *str)
431 char *tmp = PGTYPESdate_to_asc(d);
436 /* move to user allocated buffer */
444 rstrdate(char *str, Date * d)
446 Date dat = PGTYPESdate_from_asc(str, NULL);
448 if (errno != PGTYPES_DATE_BAD_DATE && dat == 0)
458 PGTYPESdate_today(d);
463 rjulmdy(Date d, short mdy[3])
467 PGTYPESdate_julmdy(d, mdy_int);
468 mdy[0] = (short) mdy_int[0];
469 mdy[1] = (short) mdy_int[1];
470 mdy[2] = (short) mdy_int[2];
475 rdefmtdate(Date * d, char *fmt, char *str)
477 /* TODO: take care of DBCENTURY environment variable */
478 /* PGSQL functions allow all centuries */
480 if (PGTYPESdate_defmt_asc(d, fmt, str) == 0)
485 case PGTYPES_DATE_ERR_ENOSHORTDATE:
487 case PGTYPES_DATE_ERR_EARGS:
488 case PGTYPES_DATE_ERR_ENOTDMY:
490 case PGTYPES_DATE_BAD_DAY:
492 case PGTYPES_DATE_BAD_MONTH:
500 rfmtdate(Date d, char *fmt, char *str)
502 if (PGTYPESdate_fmt_asc(d, fmt, str) == 0)
512 rmdyjul(short mdy[3], Date * d)
519 PGTYPESdate_mdyjul(mdy_int, d);
526 return (PGTYPESdate_dayofweek(d));
529 /* And the datetime stuff */
532 dtcurrent(timestamp *ts)
534 PGTYPEStimestamp_current(ts);
538 dtcvasc(char *str, timestamp *ts)
542 char **endptr = &str;
544 ts_tmp = PGTYPEStimestamp_from_asc(str, endptr);
550 /* extra characters exist at the end */
554 /* everything went fine */
561 dtsub(timestamp *ts1, timestamp *ts2, interval *iv)
563 return PGTYPEStimestamp_sub(ts1, ts2, iv);
567 dttoasc(timestamp *ts, char *output)
569 char *asctime = PGTYPEStimestamp_to_asc(*ts);
571 strcpy(output, asctime);
577 dttofmtasc(timestamp *ts, char *output, int str_len, char *fmtstr)
579 return PGTYPEStimestamp_fmt_asc(ts, output, str_len, fmtstr);
583 intoasc(interval *i, char *str)
585 str = PGTYPESinterval_to_asc(i);
593 /***************************************************************************
596 begin : Wed Apr 2 2003
597 copyright : (C) 2003 by Carsten Wolff
598 email : carsten.wolff@credativ.de
599 ***************************************************************************/
612 * initialize the struct, wich holds the different forms
616 initValue(long lng_val)
623 /* set some obvious things */
624 value.val = lng_val >= 0 ? lng_val : lng_val * (-1);
625 value.sign = lng_val >= 0 ? '+' : '-';
626 value.maxdigits = log10(2) * (8 * sizeof(long) - 1);
628 /* determine the number of digits */
629 for (i = 1; i <= value.maxdigits; i++)
631 if ((int) (value.val / pow(10, i)) != 0)
632 value.digits = i + 1;
634 value.remaining = value.digits;
636 /* convert the long to string */
637 value.val_string = (char *) malloc(value.digits + 1);
638 for (i = value.digits; i > 0; i--)
641 dig = (value.val % div) / (div / 10);
642 tmp[0] = (char) (dig + 48);
643 strcat(value.val_string, tmp);
646 value.val_string[value.digits] = '\0';
651 /* return the position oft the right-most dot in some string */
653 getRightMostDot(char *str)
655 size_t len = strlen(str);
660 for (i = len - 1; i >= 0; i--)
669 /* And finally some misc functions */
671 rfmtlong(long lng_val, char *fmt, char *outbuf)
673 size_t fmt_len = strlen(fmt);
691 temp = (char *) malloc(fmt_len + 1);
693 /* put all info about the long in a struct */
696 /* '<' is the only format, where we have to align left */
697 if (strchr(fmt, (int) '<'))
700 /* '(' requires ')' */
701 if (strchr(fmt, (int) '(') && strchr(fmt, (int) ')'))
704 /* get position of the right-most dot in the format-string */
705 /* and fill the temp-string wit '0's up to there. */
706 dotpos = getRightMostDot(fmt);
708 /* start to parse the formatstring */
710 j = 0; /* position in temp */
711 k = value.digits - 1; /* position in the value_string */
712 for (i = fmt_len - 1, j = 0; i >= 0; i--, j++)
714 /* qualify, where we are in the value_string */
719 /* can't use strncat(,,0) here, Solaris would freek out */
729 /* if we're right side of the right-most dot, print '0' */
730 if (dotpos >= 0 && dotpos <= i)
735 tmp[0] = value.sign == '-' ? ')' : ' ';
744 /* the ',' needs special attention, if it is in the blank area */
745 if (blank && fmt[i] == ',')
749 /* analyse this format-char */
760 tmp[0] = value.val_string[k];
766 tmp[0] = value.val_string[k];
772 tmp[0] = value.val_string[k];
775 tmp[0] = value.val_string[k];
778 if (sign && value.sign == '-' && !signdone)
786 tmp[0] = value.val_string[k];
789 if (sign && !signdone)
797 tmp[0] = value.val_string[k];
800 if (sign && brackets_ok && value.sign == '-')
805 tmp[0] = value.val_string[k];
808 if (brackets_ok && value.sign == '-')
814 if (blank && !entitydone)
822 tmp[0] = value.val_string[k];
832 temp[fmt_len] = '\0';
834 /* reverse the temp-string and put it into the outbuf */
835 temp_len = strlen(temp);
837 for (i = temp_len - 1; i >= 0; i--)
842 outbuf[temp_len] = '\0';
846 free(value.val_string);
854 for (; *str != '\0'; str++)
856 *str = toupper(*str);
861 byleng(char *str, int len)
863 for (len--; str[len] && str[len] == ' '; len--);
868 ldchar(char *src, int len, char *dest)
870 memmove(dest, src, len);
875 rgetmsg(int msgnum, char *s, int maxsize)
881 rtypalign(int offset, int type)
887 rtypmsize(int type, int len)
893 rtypwidth(int sqltype, int sqllen)
899 dtcvfmtasc(char *inbuf, char *fmtstr, dtime_t * dtvalue)
901 return PGTYPEStimestamp_defmt_asc(inbuf, fmtstr, dtvalue);
904 static struct var_list
908 struct var_list *next;
912 ECPG_informix_set_var(int number, void *pointer, int lineno)
914 struct var_list *ptr;
916 for (ptr = ivlist; ptr != NULL; ptr = ptr->next)
918 if (ptr->number == number)
920 /* already known => just change pointer value */
921 ptr->pointer = pointer;
926 /* a new one has to be added */
927 ptr = (struct var_list *) ECPGalloc(sizeof(struct var_list), lineno);
928 ptr->number = number;
929 ptr->pointer = pointer;
935 ECPG_informix_get_var(int number)
937 struct var_list *ptr;
939 for (ptr = ivlist; ptr != NULL && ptr->number != number; ptr = ptr->next);
940 return (ptr) ? ptr->pointer : NULL;
944 rsetnull(int t, char *ptr)
946 ECPGset_informix_null(t, ptr);
951 risnull(int t, char *ptr)
953 return (ECPGis_informix_null(t, ptr));