mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-06 15:24:56 +08:00
Added rfmtlong compatibility function.
This commit is contained in:
parent
3ad406bbc9
commit
299fbb4b37
@ -1396,6 +1396,14 @@ Thu May 1 14:54:41 CEST 2003
|
||||
|
||||
- Enable more Informix shortcuts.
|
||||
- Added option '-i' to parse files included via cpp diretive as well.
|
||||
|
||||
Fri May 2 16:37:06 CEST 2003
|
||||
|
||||
- Fixed double definition of compat_mode.
|
||||
|
||||
Tue May 6 11:51:33 CEST 2003
|
||||
|
||||
- Added rfmtlong compatibility function.
|
||||
- Set ecpg version to 2.12.0.
|
||||
- Set ecpg library to 3.4.2.
|
||||
- Set pgtypes library to 1.0.0
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <ecpg_informix.h>
|
||||
@ -400,10 +401,211 @@ intoasc(Interval *i, char *str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
rfmt.c - description
|
||||
-------------------
|
||||
begin : Wed Apr 2 2003
|
||||
copyright : (C) 2003 by Carsten Wolff
|
||||
email : carsten.wolff@credativ.de
|
||||
***************************************************************************/
|
||||
|
||||
static struct {
|
||||
long val;
|
||||
int maxdigits;
|
||||
int digits;
|
||||
int remaining;
|
||||
char sign;
|
||||
char *val_string;
|
||||
} value;
|
||||
|
||||
/**
|
||||
* initialize the struct, wich holds the different forms
|
||||
* of the long value
|
||||
*/
|
||||
static void initValue(long lng_val) {
|
||||
int i, div, dig;
|
||||
char tmp[2] = " ";
|
||||
|
||||
// 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
|
||||
for(i=1; i <= value.maxdigits; i++) {
|
||||
if ((int)(value.val / pow(10, i)) != 0) {
|
||||
value.digits = i+1;
|
||||
}
|
||||
}
|
||||
value.remaining = value.digits;
|
||||
|
||||
// convert the long to string
|
||||
value.val_string = (char *)malloc(value.digits + 1);
|
||||
for(i=value.digits; i > 0; i--) {
|
||||
div = pow(10,i);
|
||||
dig = (value.val % div) / (div / 10);
|
||||
tmp[0] = (char)(dig + 48);
|
||||
strcat(value.val_string, tmp);
|
||||
}
|
||||
// safety-net
|
||||
value.val_string[value.digits] = '\0';
|
||||
// clean up
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* return the position oft the right-most dot in some string */
|
||||
static int getRightMostDot(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 lvalue, char *format, char *outbuf)
|
||||
rfmtlong(long lng_val, char *fmt, char *outbuf)
|
||||
{
|
||||
size_t fmt_len = strlen(fmt);
|
||||
size_t temp_len;
|
||||
int i, j, k, dotpos;
|
||||
int leftalign = 0, blank = 0, sign = 0, entity = 0,
|
||||
entitydone = 0, signdone = 0, brackets_ok = 0;
|
||||
char temp[fmt_len+1], tmp[2] = " ", lastfmt = ' ', fmtchar = ' ';
|
||||
|
||||
// put all info about the long in a struct
|
||||
initValue(lng_val);
|
||||
|
||||
// '<' 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 formatstring
|
||||
temp[0] = '\0';
|
||||
j = 0; // position in temp
|
||||
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) {
|
||||
if (leftalign) {
|
||||
// can't use strncat(,,0) here, Solaris would freek out
|
||||
temp[j] = '\0';
|
||||
break;
|
||||
}
|
||||
blank = 1;
|
||||
if (k == -2) {
|
||||
entity = 1;
|
||||
}
|
||||
else if (k == -1) {
|
||||
sign = 1;
|
||||
}
|
||||
}
|
||||
// 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];
|
||||
// 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 '<':
|
||||
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;
|
||||
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(tmp);
|
||||
free(value.val_string);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user