/* -----------------------------------------------------------------------
* formatting.c
*
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.69.2.1 2005/03/26 00:42:21 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.69.2.2 2007/06/29 01:52:14 tgl Exp $
*
*
* Portions Copyright (c) 1999-2003, PostgreSQL Global Development Group
#include <unistd.h>
#include <math.h>
#include <float.h>
+#include <limits.h>
#include "utils/builtins.h"
#include "utils/date.h"
* More is in float.c
* ----------
*/
-#define MAXFLOATWIDTH 64
-#define MAXDOUBLEWIDTH 128
+#define MAXFLOATWIDTH 60
+#define MAXDOUBLEWIDTH 500
/* ----------
* External (defined in PgSQL dt.c (timestamp utils))
}
/* ----------
- * Convert string to upper-string. Input string is modified in place.
+ * Convert string to upper case. Input string is modified in place.
* ----------
*/
static char *
}
/* ----------
- * Convert string to lower-string. Input string is modified in place.
+ * Convert string to lower case. Input string is modified in place.
* ----------
*/
static char *
case DCH_TZ:
if (flag == TO_CHAR && tmtcTzn(tmtc))
{
- int siz = strlen(tmtcTzn(tmtc));
-
if (arg == DCH_TZ)
strcpy(inout, tmtcTzn(tmtc));
else
{
- char *p = palloc(siz);
+ char *p = pstrdup(tmtcTzn(tmtc));
- strcpy(p, tmtcTzn(tmtc));
strcpy(inout, str_tolower(p));
pfree(p);
}
- return siz - 1;
+ return strlen(inout) - 1;
}
else if (flag == FROM_CHAR)
ereport(ERROR,
fill_str(char *str, int c, int max)
{
memset(str, c, max);
- *(str + max + 1) = '\0';
+ *(str + max) = '\0';
return str;
}
#define NUM_TOCHAR_prepare \
do { \
len = VARSIZE(fmt) - VARHDRSZ; \
- if (len <= 0) \
+ if (len <= 0 || len >= (INT_MAX-VARHDRSZ)/NUM_MAX_ITEM_SIZ) \
return DirectFunctionCall1(textin, CStringGetDatum("")); \
- result = (text *) palloc( (len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ); \
- memset(result, 0, (len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ ); \
+ result = (text *) palloc0((len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ); \
format = NUM_cache(len, &Num, VARDATA(fmt), &shouldFree); \
} while (0)
do { \
NUM_processor(format, &Num, VARDATA(result), \
numstr, plen, sign, TO_CHAR); \
- pfree(orgnum); \
\
- if (shouldFree) \
- pfree(format); \
+ if (shouldFree) \
+ pfree(format); \
\
- /*
- * for result is allocated max memory, which current format-picture\
- * needs, now it must be re-allocate to result real size \
+ /* \
+ * Convert null-terminated representation of result to standard text. \
+ * The result is usually much bigger than it needs to be, but there \
+ * seems little point in realloc'ing it smaller. \
*/ \
- if (!(len = strlen(VARDATA(result)))) \
- { \
- pfree(result); \
- PG_RETURN_NULL(); \
- } \
- \
- result_tmp = result; \
- result = (text *) palloc( len + 1 + VARHDRSZ); \
- \
- strcpy( VARDATA(result), VARDATA(result_tmp)); \
- VARATT_SIZEP(result) = len + VARHDRSZ; \
- pfree(result_tmp); \
-} while(0)
+ len = strlen(VARDATA(result)); \
+ VARATT_SIZEP(result) = len + VARHDRSZ; \
+} while (0)
/* -------------------
* NUMERIC to_number() (convert string to numeric)
len = VARSIZE(fmt) - VARHDRSZ;
- if (len <= 0)
+ if (len <= 0 || len >= INT_MAX/NUM_MAX_ITEM_SIZ)
PG_RETURN_NULL();
format = NUM_cache(len, &Num, VARDATA(fmt), &shouldFree);
text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num;
FormatNode *format;
- text *result,
- *result_tmp;
+ text *result;
bool shouldFree;
int len = 0,
plen = 0,
numstr = orgnum =
int_to_roman(DatumGetInt32(DirectFunctionCall1(numeric_int4,
NumericGetDatum(x))));
- pfree(x);
}
else
{
val = DatumGetNumeric(DirectFunctionCall2(numeric_mul,
NumericGetDatum(value),
NumericGetDatum(x)));
- pfree(x);
- pfree(a);
- pfree(b);
Num.pre += Num.multi;
}
Int32GetDatum(Num.post)));
orgnum = DatumGetCString(DirectFunctionCall1(numeric_out,
NumericGetDatum(x)));
- pfree(x);
if (*orgnum == '-')
- { /* < 0 */
+ {
sign = '-';
numstr = orgnum + 1;
}
else if (len > Num.pre)
{
- fill_str(numstr, '#', Num.pre);
+ numstr = (char *) palloc(Num.pre + Num.post + 2);
+ fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
- fill_str(numstr + 1 + Num.pre, '#', Num.post);
}
-
- if (IS_MULTI(&Num))
- pfree(val);
}
NUM_TOCHAR_finish;
text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num;
FormatNode *format;
- text *result,
- *result_tmp;
+ text *result;
bool shouldFree;
int len = 0,
plen = 0,
orgnum = DatumGetCString(DirectFunctionCall1(int4out,
Int32GetDatum(value)));
}
- len = strlen(orgnum);
if (*orgnum == '-')
- { /* < 0 */
+ {
sign = '-';
- --len;
+ orgnum++;
}
else
sign = '+';
+ len = strlen(orgnum);
if (Num.post)
{
- int i;
-
numstr = (char *) palloc(len + Num.post + 2);
- strcpy(numstr, orgnum + (*orgnum == '-' ? 1 : 0));
+ strcpy(numstr, orgnum);
*(numstr + len) = '.';
-
- for (i = len + 1; i <= len + Num.post; i++)
- *(numstr + i) = '0';
+ memset(numstr + len + 1, '0', Num.post);
*(numstr + len + Num.post + 1) = '\0';
- pfree(orgnum);
- orgnum = numstr;
}
else
- numstr = orgnum + (*orgnum == '-' ? 1 : 0);
+ numstr = orgnum;
if (Num.pre > len)
plen = Num.pre - len;
else if (len > Num.pre)
{
- fill_str(numstr, '#', Num.pre);
+ numstr = (char *) palloc(Num.pre + Num.post + 2);
+ fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
- fill_str(numstr + 1 + Num.pre, '#', Num.post);
}
}
text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num;
FormatNode *format;
- text *result,
- *result_tmp;
+ text *result;
bool shouldFree;
int len = 0,
plen = 0,
orgnum = DatumGetCString(DirectFunctionCall1(int8out,
Int64GetDatum(value)));
- len = strlen(orgnum);
if (*orgnum == '-')
- { /* < 0 */
+ {
sign = '-';
- --len;
+ orgnum++;
}
else
sign = '+';
+ len = strlen(orgnum);
if (Num.post)
{
- int i;
-
numstr = (char *) palloc(len + Num.post + 2);
- strcpy(numstr, orgnum + (*orgnum == '-' ? 1 : 0));
+ strcpy(numstr, orgnum);
*(numstr + len) = '.';
-
- for (i = len + 1; i <= len + Num.post; i++)
- *(numstr + i) = '0';
+ memset(numstr + len + 1, '0', Num.post);
*(numstr + len + Num.post + 1) = '\0';
- pfree(orgnum);
- orgnum = numstr;
}
else
- numstr = orgnum + (*orgnum == '-' ? 1 : 0);
+ numstr = orgnum;
if (Num.pre > len)
plen = Num.pre - len;
else if (len > Num.pre)
{
- fill_str(numstr, '#', Num.pre);
+ numstr = (char *) palloc(Num.pre + Num.post + 2);
+ fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
- fill_str(numstr + 1 + Num.pre, '#', Num.post);
}
}
text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num;
FormatNode *format;
- text *result,
- *result_tmp;
+ text *result;
bool shouldFree;
int len = 0,
plen = 0,
else if (len > Num.pre)
{
- fill_str(numstr, '#', Num.pre);
+ numstr = (char *) palloc(Num.pre + Num.post + 2);
+ fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
- fill_str(numstr + 1 + Num.pre, '#', Num.post);
}
}
text *fmt = PG_GETARG_TEXT_P(1);
NUMDesc Num;
FormatNode *format;
- text *result,
- *result_tmp;
+ text *result;
bool shouldFree;
int len = 0,
plen = 0,
else if (len > Num.pre)
{
- fill_str(numstr, '#', Num.pre);
+ numstr = (char *) palloc(Num.pre + Num.post + 2);
+ fill_str(numstr, '#', Num.pre + Num.post + 1);
*(numstr + Num.pre) = '.';
- fill_str(numstr + 1 + Num.pre, '#', Num.post);
}
}