| /* src/interfaces/ecpg/compatlib/informix.c */ |
| |
| #define POSTGRES_ECPG_INTERNAL |
| #include "postgres_fe.h" |
| |
| #include <math.h> |
| #include <ctype.h> |
| #include <limits.h> |
| |
| #include "ecpg_informix.h" |
| #include "ecpgerrno.h" |
| #include "ecpgtype.h" |
| #include "pgtypes_date.h" |
| #include "pgtypes_error.h" |
| #include "pgtypes_numeric.h" |
| #include "sqlca.h" |
| #include "sqltypes.h" |
| |
| /* this is also defined in ecpglib/misc.c, by defining it twice we don't have to export the symbol */ |
| |
| static struct sqlca_t sqlca_init = |
| { |
| { |
| 'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' ' |
| }, |
| sizeof(struct sqlca_t), |
| 0, |
| { |
| 0, |
| { |
| 0 |
| } |
| }, |
| { |
| 'N', 'O', 'T', ' ', 'S', 'E', 'T', ' ' |
| }, |
| { |
| 0, 0, 0, 0, 0, 0 |
| }, |
| { |
| 0, 0, 0, 0, 0, 0, 0, 0 |
| }, |
| { |
| '0', '0', '0', '0', '0' |
| } |
| }; |
| static int |
| deccall2(decimal *arg1, decimal *arg2, int (*ptr) (numeric *, numeric *)) |
| { |
| numeric *a1, |
| *a2; |
| int i; |
| |
| if ((a1 = PGTYPESnumeric_new()) == NULL) |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| |
| if ((a2 = PGTYPESnumeric_new()) == NULL) |
| { |
| PGTYPESnumeric_free(a1); |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| } |
| |
| if (PGTYPESnumeric_from_decimal(arg1, a1) != 0) |
| { |
| PGTYPESnumeric_free(a1); |
| PGTYPESnumeric_free(a2); |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| } |
| |
| if (PGTYPESnumeric_from_decimal(arg2, a2) != 0) |
| { |
| PGTYPESnumeric_free(a1); |
| PGTYPESnumeric_free(a2); |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| } |
| |
| i = (*ptr) (a1, a2); |
| |
| PGTYPESnumeric_free(a1); |
| PGTYPESnumeric_free(a2); |
| |
| return i; |
| } |
| |
| static int |
| deccall3(decimal *arg1, decimal *arg2, decimal *result, int (*ptr) (numeric *, numeric *, numeric *)) |
| { |
| numeric *a1, |
| *a2, |
| *nres; |
| int i; |
| |
| /* |
| * we must NOT set the result to NULL here because it may be the same |
| * variable as one of the arguments |
| */ |
| if (risnull(CDECIMALTYPE, (char *) arg1) || risnull(CDECIMALTYPE, (char *) arg2)) |
| return 0; |
| |
| if ((a1 = PGTYPESnumeric_new()) == NULL) |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| |
| if ((a2 = PGTYPESnumeric_new()) == NULL) |
| { |
| PGTYPESnumeric_free(a1); |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| } |
| |
| if ((nres = PGTYPESnumeric_new()) == NULL) |
| { |
| PGTYPESnumeric_free(a1); |
| PGTYPESnumeric_free(a2); |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| } |
| |
| if (PGTYPESnumeric_from_decimal(arg1, a1) != 0) |
| { |
| PGTYPESnumeric_free(a1); |
| PGTYPESnumeric_free(a2); |
| PGTYPESnumeric_free(nres); |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| } |
| |
| if (PGTYPESnumeric_from_decimal(arg2, a2) != 0) |
| { |
| PGTYPESnumeric_free(a1); |
| PGTYPESnumeric_free(a2); |
| PGTYPESnumeric_free(nres); |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| } |
| |
| i = (*ptr) (a1, a2, nres); |
| |
| if (i == 0) /* No error */ |
| { |
| |
| /* set the result to null in case it errors out later */ |
| rsetnull(CDECIMALTYPE, (char *) result); |
| PGTYPESnumeric_to_decimal(nres, result); |
| } |
| |
| PGTYPESnumeric_free(nres); |
| PGTYPESnumeric_free(a1); |
| PGTYPESnumeric_free(a2); |
| |
| return i; |
| } |
| |
| /* we start with the numeric functions */ |
| int |
| decadd(decimal *arg1, decimal *arg2, decimal *sum) |
| { |
| errno = 0; |
| deccall3(arg1, arg2, sum, PGTYPESnumeric_add); |
| |
| if (errno == PGTYPES_NUM_OVERFLOW) |
| return ECPG_INFORMIX_NUM_OVERFLOW; |
| else if (errno == PGTYPES_NUM_UNDERFLOW) |
| return ECPG_INFORMIX_NUM_UNDERFLOW; |
| else if (errno != 0) |
| return -1; |
| else |
| return 0; |
| } |
| |
| int |
| deccmp(decimal *arg1, decimal *arg2) |
| { |
| return deccall2(arg1, arg2, PGTYPESnumeric_cmp); |
| } |
| |
| void |
| deccopy(decimal *src, decimal *target) |
| { |
| memcpy(target, src, sizeof(decimal)); |
| } |
| |
| int |
| deccvasc(const char *cp, int len, decimal *np) |
| { |
| char *str; |
| int ret = 0; |
| numeric *result; |
| |
| rsetnull(CDECIMALTYPE, (char *) np); |
| if (risnull(CSTRINGTYPE, cp)) |
| return 0; |
| |
| str = pnstrdup(cp, len); /* decimal_in always converts the complete |
| * string */ |
| if (!str) |
| ret = ECPG_INFORMIX_NUM_UNDERFLOW; |
| else |
| { |
| errno = 0; |
| result = PGTYPESnumeric_from_asc(str, NULL); |
| if (!result) |
| { |
| switch (errno) |
| { |
| case PGTYPES_NUM_OVERFLOW: |
| ret = ECPG_INFORMIX_NUM_OVERFLOW; |
| break; |
| case PGTYPES_NUM_BAD_NUMERIC: |
| ret = ECPG_INFORMIX_BAD_NUMERIC; |
| break; |
| default: |
| ret = ECPG_INFORMIX_BAD_EXPONENT; |
| break; |
| } |
| } |
| else |
| { |
| int i = PGTYPESnumeric_to_decimal(result, np); |
| |
| PGTYPESnumeric_free(result); |
| if (i != 0) |
| ret = ECPG_INFORMIX_NUM_OVERFLOW; |
| } |
| } |
| |
| free(str); |
| return ret; |
| } |
| |
| int |
| deccvdbl(double dbl, decimal *np) |
| { |
| numeric *nres; |
| int result = 1; |
| |
| rsetnull(CDECIMALTYPE, (char *) np); |
| if (risnull(CDOUBLETYPE, (char *) &dbl)) |
| return 0; |
| |
| nres = PGTYPESnumeric_new(); |
| if (nres == NULL) |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| |
| result = PGTYPESnumeric_from_double(dbl, nres); |
| if (result == 0) |
| result = PGTYPESnumeric_to_decimal(nres, np); |
| |
| PGTYPESnumeric_free(nres); |
| return result; |
| } |
| |
| int |
| deccvint(int in, decimal *np) |
| { |
| numeric *nres; |
| int result = 1; |
| |
| rsetnull(CDECIMALTYPE, (char *) np); |
| if (risnull(CINTTYPE, (char *) &in)) |
| return 0; |
| |
| nres = PGTYPESnumeric_new(); |
| if (nres == NULL) |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| |
| result = PGTYPESnumeric_from_int(in, nres); |
| if (result == 0) |
| result = PGTYPESnumeric_to_decimal(nres, np); |
| |
| PGTYPESnumeric_free(nres); |
| return result; |
| } |
| |
| int |
| deccvlong(long lng, decimal *np) |
| { |
| numeric *nres; |
| int result = 1; |
| |
| rsetnull(CDECIMALTYPE, (char *) np); |
| if (risnull(CLONGTYPE, (char *) &lng)) |
| return 0; |
| |
| nres = PGTYPESnumeric_new(); |
| if (nres == NULL) |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| |
| result = PGTYPESnumeric_from_long(lng, nres); |
| if (result == 0) |
| result = PGTYPESnumeric_to_decimal(nres, np); |
| |
| PGTYPESnumeric_free(nres); |
| return result; |
| } |
| |
| int |
| decdiv(decimal *n1, decimal *n2, decimal *result) |
| { |
| int i; |
| |
| errno = 0; |
| i = deccall3(n1, n2, result, PGTYPESnumeric_div); |
| |
| if (i != 0) |
| switch (errno) |
| { |
| case PGTYPES_NUM_DIVIDE_ZERO: |
| return ECPG_INFORMIX_DIVIDE_ZERO; |
| break; |
| case PGTYPES_NUM_OVERFLOW: |
| return ECPG_INFORMIX_NUM_OVERFLOW; |
| break; |
| default: |
| return ECPG_INFORMIX_NUM_UNDERFLOW; |
| break; |
| } |
| |
| return 0; |
| } |
| |
| int |
| decmul(decimal *n1, decimal *n2, decimal *result) |
| { |
| int i; |
| |
| errno = 0; |
| i = deccall3(n1, n2, result, PGTYPESnumeric_mul); |
| |
| if (i != 0) |
| switch (errno) |
| { |
| case PGTYPES_NUM_OVERFLOW: |
| return ECPG_INFORMIX_NUM_OVERFLOW; |
| break; |
| default: |
| return ECPG_INFORMIX_NUM_UNDERFLOW; |
| break; |
| } |
| |
| return 0; |
| } |
| |
| int |
| decsub(decimal *n1, decimal *n2, decimal *result) |
| { |
| int i; |
| |
| errno = 0; |
| i = deccall3(n1, n2, result, PGTYPESnumeric_sub); |
| |
| if (i != 0) |
| switch (errno) |
| { |
| case PGTYPES_NUM_OVERFLOW: |
| return ECPG_INFORMIX_NUM_OVERFLOW; |
| break; |
| default: |
| return ECPG_INFORMIX_NUM_UNDERFLOW; |
| break; |
| } |
| |
| return 0; |
| } |
| |
| int |
| dectoasc(decimal *np, char *cp, int len, int right) |
| { |
| char *str; |
| numeric *nres; |
| |
| rsetnull(CSTRINGTYPE, (char *) cp); |
| if (risnull(CDECIMALTYPE, (char *) np)) |
| return 0; |
| |
| nres = PGTYPESnumeric_new(); |
| if (nres == NULL) |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| |
| if (PGTYPESnumeric_from_decimal(np, nres) != 0) |
| { |
| PGTYPESnumeric_free(nres); |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| } |
| |
| if (right >= 0) |
| str = PGTYPESnumeric_to_asc(nres, right); |
| else |
| str = PGTYPESnumeric_to_asc(nres, nres->dscale); |
| |
| PGTYPESnumeric_free(nres); |
| if (!str) |
| return -1; |
| |
| /* |
| * TODO: have to take care of len here and create exponential notation if |
| * necessary |
| */ |
| if ((int) (strlen(str) + 1) > len) |
| { |
| if (len > 1) |
| { |
| cp[0] = '*'; |
| cp[1] = '\0'; |
| } |
| free(str); |
| return -1; |
| } |
| else |
| { |
| strcpy(cp, str); |
| free(str); |
| return 0; |
| } |
| } |
| |
| int |
| dectodbl(decimal *np, double *dblp) |
| { |
| int i; |
| numeric *nres = PGTYPESnumeric_new(); |
| |
| if (nres == NULL) |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| |
| if (PGTYPESnumeric_from_decimal(np, nres) != 0) |
| { |
| PGTYPESnumeric_free(nres); |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| } |
| |
| i = PGTYPESnumeric_to_double(nres, dblp); |
| PGTYPESnumeric_free(nres); |
| |
| return i; |
| } |
| |
| int |
| dectoint(decimal *np, int *ip) |
| { |
| int ret; |
| numeric *nres = PGTYPESnumeric_new(); |
| |
| if (nres == NULL) |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| |
| if (PGTYPESnumeric_from_decimal(np, nres) != 0) |
| { |
| PGTYPESnumeric_free(nres); |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| } |
| |
| ret = PGTYPESnumeric_to_int(nres, ip); |
| PGTYPESnumeric_free(nres); |
| |
| if (ret == PGTYPES_NUM_OVERFLOW) |
| ret = ECPG_INFORMIX_NUM_OVERFLOW; |
| |
| return ret; |
| } |
| |
| int |
| dectolong(decimal *np, long *lngp) |
| { |
| int ret; |
| numeric *nres = PGTYPESnumeric_new(); |
| |
| if (nres == NULL) |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| |
| if (PGTYPESnumeric_from_decimal(np, nres) != 0) |
| { |
| PGTYPESnumeric_free(nres); |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| } |
| |
| ret = PGTYPESnumeric_to_long(nres, lngp); |
| PGTYPESnumeric_free(nres); |
| |
| if (ret == PGTYPES_NUM_OVERFLOW) |
| ret = ECPG_INFORMIX_NUM_OVERFLOW; |
| |
| return ret; |
| } |
| |
| /* Now the date functions */ |
| int |
| rdatestr(date d, char *str) |
| { |
| char *tmp = PGTYPESdate_to_asc(d); |
| |
| if (!tmp) |
| return ECPG_INFORMIX_DATE_CONVERT; |
| |
| /* move to user allocated buffer */ |
| strcpy(str, tmp); |
| free(tmp); |
| |
| return 0; |
| } |
| |
| /* |
| * |
| * the input for this function is mmddyyyy and any non-numeric |
| * character can be used as a separator |
| * |
| */ |
| int |
| rstrdate(const char *str, date * d) |
| { |
| return rdefmtdate(d, "mm/dd/yyyy", str); |
| } |
| |
| void |
| rtoday(date * d) |
| { |
| PGTYPESdate_today(d); |
| } |
| |
| int |
| rjulmdy(date d, short *mdy) |
| { |
| int mdy_int[3]; |
| |
| PGTYPESdate_julmdy(d, mdy_int); |
| mdy[0] = (short) mdy_int[0]; |
| mdy[1] = (short) mdy_int[1]; |
| mdy[2] = (short) mdy_int[2]; |
| return 0; |
| } |
| |
| int |
| rdefmtdate(date * d, const char *fmt, const char *str) |
| { |
| /* TODO: take care of DBCENTURY environment variable */ |
| /* PGSQL functions allow all centuries */ |
| |
| errno = 0; |
| if (PGTYPESdate_defmt_asc(d, fmt, str) == 0) |
| return 0; |
| |
| switch (errno) |
| { |
| case PGTYPES_DATE_ERR_ENOSHORTDATE: |
| return ECPG_INFORMIX_ENOSHORTDATE; |
| case PGTYPES_DATE_ERR_EARGS: |
| case PGTYPES_DATE_ERR_ENOTDMY: |
| return ECPG_INFORMIX_ENOTDMY; |
| case PGTYPES_DATE_BAD_DAY: |
| return ECPG_INFORMIX_BAD_DAY; |
| case PGTYPES_DATE_BAD_MONTH: |
| return ECPG_INFORMIX_BAD_MONTH; |
| default: |
| return ECPG_INFORMIX_BAD_YEAR; |
| } |
| } |
| |
| int |
| rfmtdate(date d, const char *fmt, char *str) |
| { |
| errno = 0; |
| if (PGTYPESdate_fmt_asc(d, fmt, str) == 0) |
| return 0; |
| |
| if (errno == ENOMEM) |
| return ECPG_INFORMIX_OUT_OF_MEMORY; |
| |
| return ECPG_INFORMIX_DATE_CONVERT; |
| } |
| |
| int |
| rmdyjul(short *mdy, date * d) |
| { |
| int mdy_int[3]; |
| |
| mdy_int[0] = mdy[0]; |
| mdy_int[1] = mdy[1]; |
| mdy_int[2] = mdy[2]; |
| PGTYPESdate_mdyjul(mdy_int, d); |
| return 0; |
| } |
| |
| int |
| rdayofweek(date d) |
| { |
| return PGTYPESdate_dayofweek(d); |
| } |
| |
| /* And the datetime stuff */ |
| |
| void |
| dtcurrent(timestamp * ts) |
| { |
| PGTYPEStimestamp_current(ts); |
| } |
| |
| int |
| dtcvasc(char *str, timestamp * ts) |
| { |
| timestamp ts_tmp; |
| int i; |
| char **endptr = &str; |
| |
| errno = 0; |
| ts_tmp = PGTYPEStimestamp_from_asc(str, endptr); |
| i = errno; |
| if (i) |
| /* TODO: rewrite to Informix error codes */ |
| return i; |
| if (**endptr) |
| { |
| /* extra characters exist at the end */ |
| return ECPG_INFORMIX_EXTRA_CHARS; |
| } |
| /* TODO: other Informix error codes missing */ |
| |
| /* everything went fine */ |
| *ts = ts_tmp; |
| |
| return 0; |
| } |
| |
| int |
| dtcvfmtasc(char *inbuf, char *fmtstr, timestamp * dtvalue) |
| { |
| return PGTYPEStimestamp_defmt_asc(inbuf, fmtstr, dtvalue); |
| } |
| |
| int |
| dtsub(timestamp * ts1, timestamp * ts2, interval * iv) |
| { |
| return PGTYPEStimestamp_sub(ts1, ts2, iv); |
| } |
| |
| int |
| dttoasc(timestamp * ts, char *output) |
| { |
| char *asctime = PGTYPEStimestamp_to_asc(*ts); |
| |
| strcpy(output, asctime); |
| free(asctime); |
| return 0; |
| } |
| |
| int |
| dttofmtasc(timestamp * ts, char *output, int str_len, char *fmtstr) |
| { |
| return PGTYPEStimestamp_fmt_asc(ts, output, str_len, fmtstr); |
| } |
| |
| int |
| intoasc(interval * i, char *str) |
| { |
| char *tmp; |
| |
| errno = 0; |
| tmp = PGTYPESinterval_to_asc(i); |
| |
| if (!tmp) |
| return -errno; |
| |
| memcpy(str, tmp, strlen(tmp)); |
| free(tmp); |
| return 0; |
| } |
| |
| static struct |
| { |
| long val; |
| int maxdigits; |
| int digits; |
| int remaining; |
| char sign; |
| char *val_string; |
| } value; |
| |
| /** |
| * initialize the struct, which holds the different forms |
| * of the long value |
| */ |
| static int |
| initValue(long lng_val) |
| { |
| int i, |
| j; |
| long l, |
| dig; |
| |
| /* set some obvious things */ |
| value.val = lng_val >= 0 ? lng_val : lng_val * (-1); |
| value.sign = lng_val >= 0 ? '+' : '-'; |
| value.maxdigits = log10(2) * (8 * sizeof(long) - 1); |
| |
| /* determine the number of digits */ |
| i = 0; |
| l = 1; |
| do |
| { |
| i++; |
| l *= 10; |
| } |
| while ((l - 1) < value.val && l <= LONG_MAX / 10); |
| |
| if (l <= LONG_MAX / 10) |
| { |
| value.digits = i; |
| l /= 10; |
| } |
| else |
| value.digits = i + 1; |
| |
| value.remaining = value.digits; |
| |
| /* convert the long to string */ |
| if ((value.val_string = (char *) malloc(value.digits + 1)) == NULL) |
| return -1; |
| dig = value.val; |
| for (i = value.digits, j = 0; i > 0; i--, j++) |
| { |
| value.val_string[j] = dig / l + '0'; |
| dig = dig % l; |
| l /= 10; |
| } |
| value.val_string[value.digits] = '\0'; |
| return 0; |
| } |
| |
| /* return the position of the right-most dot in some string */ |
| static int |
| getRightMostDot(const char *str) |
| { |
| size_t len = strlen(str); |
| int i, |
| j; |
| |
| j = 0; |
| for (i = len - 1; i >= 0; i--) |
| { |
| if (str[i] == '.') |
| return len - j - 1; |
| j++; |
| } |
| return -1; |
| } |
| |
| /* And finally some misc functions */ |
| int |
| rfmtlong(long lng_val, const char *fmt, char *outbuf) |
| { |
| size_t fmt_len = strlen(fmt); |
| size_t temp_len; |
| int i, |
| j, /* position in temp */ |
| k, |
| dotpos; |
| int leftalign = 0, |
| blank = 0, |
| sign = 0, |
| entitydone = 0, |
| signdone = 0, |
| brackets_ok = 0; |
| char *temp; |
| char tmp[2] = " "; |
| char lastfmt = ' ', |
| fmtchar = ' '; |
| |
| temp = (char *) malloc(fmt_len + 1); |
| if (!temp) |
| { |
| errno = ENOMEM; |
| return -1; |
| } |
| |
| /* put all info about the long in a struct */ |
| if (initValue(lng_val) == -1) |
| { |
| free(temp); |
| errno = ENOMEM; |
| return -1; |
| } |
| |
| /* '<' is the only format, where we have to align left */ |
| if (strchr(fmt, (int) '<')) |
| leftalign = 1; |
| |
| /* '(' requires ')' */ |
| if (strchr(fmt, (int) '(') && strchr(fmt, (int) ')')) |
| brackets_ok = 1; |
| |
| /* get position of the right-most dot in the format-string */ |
| /* and fill the temp-string wit '0's up to there. */ |
| dotpos = getRightMostDot(fmt); |
| |
| /* start to parse the format-string */ |
| temp[0] = '\0'; |
| k = value.digits - 1; /* position in the value_string */ |
| for (i = fmt_len - 1, j = 0; i >= 0; i--, j++) |
| { |
| /* qualify, where we are in the value_string */ |
| if (k < 0) |
| { |
| blank = 1; |
| if (k == -1) |
| sign = 1; |
| if (leftalign) |
| { |
| /* can't use strncat(,,0) here, Solaris would freak out */ |
| if (sign) |
| if (signdone) |
| { |
| temp[j] = '\0'; |
| break; |
| } |
| } |
| } |
| /* if we're right side of the right-most dot, print '0' */ |
| if (dotpos >= 0 && dotpos <= i) |
| { |
| if (dotpos < i) |
| { |
| if (fmt[i] == ')') |
| tmp[0] = value.sign == '-' ? ')' : ' '; |
| else |
| tmp[0] = '0'; |
| } |
| else |
| tmp[0] = '.'; |
| strcat(temp, tmp); |
| continue; |
| } |
| /* the ',' needs special attention, if it is in the blank area */ |
| if (blank && fmt[i] == ',') |
| fmtchar = lastfmt; |
| else |
| fmtchar = fmt[i]; |
| /* waiting for the sign */ |
| if (k < 0 && leftalign && sign && !signdone && fmtchar != '+' && fmtchar != '-') |
| continue; |
| /* analyse this format-char */ |
| switch (fmtchar) |
| { |
| case ',': |
| tmp[0] = ','; |
| k++; |
| break; |
| case '*': |
| if (blank) |
| tmp[0] = '*'; |
| else |
| tmp[0] = value.val_string[k]; |
| break; |
| case '&': |
| if (blank) |
| tmp[0] = '0'; |
| else |
| tmp[0] = value.val_string[k]; |
| break; |
| case '#': |
| if (blank) |
| tmp[0] = ' '; |
| else |
| tmp[0] = value.val_string[k]; |
| break; |
| case '-': |
| if (sign && value.sign == '-' && !signdone) |
| { |
| tmp[0] = '-'; |
| signdone = 1; |
| } |
| else if (blank) |
| tmp[0] = ' '; |
| else |
| tmp[0] = value.val_string[k]; |
| break; |
| case '+': |
| if (sign && !signdone) |
| { |
| tmp[0] = value.sign; |
| signdone = 1; |
| } |
| else if (blank) |
| tmp[0] = ' '; |
| else |
| tmp[0] = value.val_string[k]; |
| break; |
| case '(': |
| if (sign && brackets_ok && value.sign == '-') |
| tmp[0] = '('; |
| else if (blank) |
| tmp[0] = ' '; |
| else |
| tmp[0] = value.val_string[k]; |
| break; |
| case ')': |
| if (brackets_ok && value.sign == '-') |
| tmp[0] = ')'; |
| else |
| tmp[0] = ' '; |
| break; |
| case '$': |
| if (blank && !entitydone) |
| { |
| tmp[0] = '$'; |
| entitydone = 1; |
| } |
| else if (blank) |
| tmp[0] = ' '; |
| else |
| tmp[0] = value.val_string[k]; |
| break; |
| case '<': |
| tmp[0] = value.val_string[k]; |
| break; |
| default: |
| tmp[0] = fmt[i]; |
| } |
| strcat(temp, tmp); |
| lastfmt = fmt[i]; |
| k--; |
| } |
| /* safety-net */ |
| temp[fmt_len] = '\0'; |
| |
| /* reverse the temp-string and put it into the outbuf */ |
| temp_len = strlen(temp); |
| outbuf[0] = '\0'; |
| for (i = temp_len - 1; i >= 0; i--) |
| { |
| tmp[0] = temp[i]; |
| strcat(outbuf, tmp); |
| } |
| outbuf[temp_len] = '\0'; |
| |
| /* cleaning up */ |
| free(temp); |
| free(value.val_string); |
| |
| return 0; |
| } |
| |
| void |
| rupshift(char *str) |
| { |
| for (; *str != '\0'; str++) |
| if (islower((unsigned char) *str)) |
| *str = toupper((unsigned char) *str); |
| } |
| |
| int |
| byleng(char *str, int len) |
| { |
| for (len--; str[len] && str[len] == ' '; len--); |
| return (len + 1); |
| } |
| |
| void |
| ldchar(char *src, int len, char *dest) |
| { |
| int dlen = byleng(src, len); |
| |
| memmove(dest, src, dlen); |
| dest[dlen] = '\0'; |
| } |
| |
| int |
| rgetmsg(int msgnum, char *s, int maxsize) |
| { |
| (void) msgnum; /* keep the compiler quiet */ |
| (void) s; /* keep the compiler quiet */ |
| (void) maxsize; /* keep the compiler quiet */ |
| return 0; |
| } |
| |
| int |
| rtypalign(int offset, int type) |
| { |
| (void) offset; /* keep the compiler quiet */ |
| (void) type; /* keep the compiler quiet */ |
| return 0; |
| } |
| |
| int |
| rtypmsize(int type, int len) |
| { |
| (void) type; /* keep the compiler quiet */ |
| (void) len; /* keep the compiler quiet */ |
| return 0; |
| } |
| |
| int |
| rtypwidth(int sqltype, int sqllen) |
| { |
| (void) sqltype; /* keep the compiler quiet */ |
| (void) sqllen; /* keep the compiler quiet */ |
| return 0; |
| } |
| |
| void |
| ECPG_informix_set_var(int number, void *pointer, int lineno) |
| { |
| ECPGset_var(number, pointer, lineno); |
| } |
| |
| void * |
| ECPG_informix_get_var(int number) |
| { |
| return ECPGget_var(number); |
| } |
| |
| void |
| ECPG_informix_reset_sqlca(void) |
| { |
| struct sqlca_t *sqlca = ECPGget_sqlca(); |
| |
| if (sqlca == NULL) |
| return; |
| |
| memcpy((char *) sqlca, (char *) &sqlca_init, sizeof(struct sqlca_t)); |
| } |
| |
| int |
| rsetnull(int t, char *ptr) |
| { |
| ECPGset_noind_null(t, ptr); |
| return 0; |
| } |
| |
| int |
| risnull(int t, const char *ptr) |
| { |
| return ECPGis_noind_null(t, ptr); |
| } |