Commit 130e372b authored by Tom Lane's avatar Tom Lane

Minor improvements to stringinfo package to make it more

robust, since it's about to get used much more heavily.
parent f4add185
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* *
* Copyright (c) 1994-5, Regents of the University of California * Copyright (c) 1994-5, Regents of the University of California
* *
* $Id: explain.c,v 1.45 1999/08/16 23:47:23 tgl Exp $ * $Id: explain.c,v 1.46 1999/08/31 01:28:28 tgl Exp $
* *
*/ */
...@@ -31,6 +31,9 @@ static char *Explain_PlanToString(Plan *plan, ExplainState *es); ...@@ -31,6 +31,9 @@ static char *Explain_PlanToString(Plan *plan, ExplainState *es);
static void printLongNotice(const char *header, const char *message); static void printLongNotice(const char *header, const char *message);
static void ExplainOneQuery(Query *query, bool verbose, CommandDest dest); static void ExplainOneQuery(Query *query, bool verbose, CommandDest dest);
/* Convert a null string pointer into "<>" */
#define stringStringInfo(s) (((s) == NULL) ? "<>" : (s))
/* /*
* ExplainQuery - * ExplainQuery -
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: stringinfo.c,v 1.20 1999/07/17 20:16:59 momjian Exp $ * $Id: stringinfo.c,v 1.21 1999/08/31 01:28:25 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "postgres.h" #include "postgres.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
#ifdef NOT_USED
/* /*
* makeStringInfo * makeStringInfo
* *
...@@ -36,7 +35,6 @@ makeStringInfo(void) ...@@ -36,7 +35,6 @@ makeStringInfo(void)
return res; return res;
} }
#endif
/* /*
* initStringInfo * initStringInfo
...@@ -49,7 +47,7 @@ initStringInfo(StringInfo str) ...@@ -49,7 +47,7 @@ initStringInfo(StringInfo str)
{ {
int size = 256; /* initial default buffer size */ int size = 256; /* initial default buffer size */
str->data = palloc(size); str->data = (char *) palloc(size);
if (str->data == NULL) if (str->data == NULL)
elog(ERROR, elog(ERROR,
"initStringInfo: Out of memory (%d bytes requested)", size); "initStringInfo: Out of memory (%d bytes requested)", size);
...@@ -68,7 +66,6 @@ static void ...@@ -68,7 +66,6 @@ static void
enlargeStringInfo(StringInfo str, int needed) enlargeStringInfo(StringInfo str, int needed)
{ {
int newlen; int newlen;
char *newdata;
needed += str->len + 1; /* total space required now */ needed += str->len + 1; /* total space required now */
if (needed <= str->maxlen) if (needed <= str->maxlen)
...@@ -84,15 +81,11 @@ enlargeStringInfo(StringInfo str, int needed) ...@@ -84,15 +81,11 @@ enlargeStringInfo(StringInfo str, int needed)
while (needed > newlen) while (needed > newlen)
newlen = 2 * newlen; newlen = 2 * newlen;
newdata = palloc(newlen); str->data = (char *) repalloc(str->data, newlen);
if (newdata == NULL) if (str->data == NULL)
elog(ERROR, elog(ERROR,
"enlargeStringInfo: Out of memory (%d bytes requested)", newlen); "enlargeStringInfo: Out of memory (%d bytes requested)", newlen);
/* OK, transfer data into new buffer, and release old buffer */
memcpy(newdata, str->data, str->len + 1);
pfree(str->data);
str->data = newdata;
str->maxlen = newlen; str->maxlen = newlen;
} }
...@@ -103,29 +96,41 @@ enlargeStringInfo(StringInfo str, int needed) ...@@ -103,29 +96,41 @@ enlargeStringInfo(StringInfo str, int needed)
* and append it to whatever is already in str. More space is allocated * and append it to whatever is already in str. More space is allocated
* to str if necessary. This is sort of like a combination of sprintf and * to str if necessary. This is sort of like a combination of sprintf and
* strcat. * strcat.
*
* CAUTION: the current implementation has a 1K limit on the amount of text
* generated in a single call (not on the total string length).
*/ */
void void
appendStringInfo(StringInfo str, const char *fmt,...) appendStringInfo(StringInfo str, const char *fmt,...)
{ {
va_list args; va_list args;
char buffer[1024]; int avail,
int buflen; nprinted;
Assert(str != NULL); Assert(str != NULL);
va_start(args, fmt); for (;;)
buflen = vsnprintf(buffer, sizeof(buffer), fmt, args); {
va_end(args); /*----------
* Try to format the given string into the available space;
/* Make more room if needed */ * but if there's hardly any space, don't bother trying,
enlargeStringInfo(str, buflen); * just fall through to enlarge the buffer first.
*----------
/* OK, append the data, including the trailing null */ */
memcpy(str->data + str->len, buffer, buflen + 1); avail = str->maxlen - str->len - 1;
str->len += buflen; if (avail > 16)
{
va_start(args, fmt);
nprinted = vsnprintf(str->data + str->len, avail,
fmt, args);
va_end(args);
if (nprinted < avail-1)
{
/* Success. Note nprinted does not include trailing null. */
str->len += nprinted;
break;
}
}
/* Double the buffer size and try again. */
enlargeStringInfo(str, str->maxlen);
}
} }
/*------------------------ /*------------------------
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: outfuncs.c,v 1.94 1999/08/21 03:48:58 tgl Exp $ * $Id: outfuncs.c,v 1.95 1999/08/31 01:28:32 tgl Exp $
* *
* NOTES * NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which * Every (plan) node in POSTGRES has an associated "out" routine which
...@@ -42,6 +42,10 @@ ...@@ -42,6 +42,10 @@
static void _outDatum(StringInfo str, Datum value, Oid type); static void _outDatum(StringInfo str, Datum value, Oid type);
static void _outNode(StringInfo str, void *obj); static void _outNode(StringInfo str, void *obj);
/* Convert a null string pointer into "<>" */
#define stringStringInfo(s) (((s) == NULL) ? "<>" : (s))
/* /*
* _outIntList - * _outIntList -
* converts a List of integers * converts a List of integers
......
...@@ -74,7 +74,7 @@ typedef unsigned long ulong_long; ...@@ -74,7 +74,7 @@ typedef unsigned long ulong_long;
* causing nast effects. * causing nast effects.
**************************************************************/ **************************************************************/
/*static char _id[] = "$Id: snprintf.c,v 1.25 1999/07/17 20:17:28 momjian Exp $";*/ /*static char _id[] = "$Id: snprintf.c,v 1.26 1999/08/31 01:28:37 tgl Exp $";*/
static char *end; static char *end;
static int SnprfOverflow; static int SnprfOverflow;
...@@ -98,14 +98,14 @@ snprintf(char *str, size_t count, const char *fmt,...) ...@@ -98,14 +98,14 @@ snprintf(char *str, size_t count, const char *fmt,...)
int int
vsnprintf(char *str, size_t count, const char *fmt, va_list args) vsnprintf(char *str, size_t count, const char *fmt, va_list args)
{ {
str[0] = 0; str[0] = '\0';
end = str + count - 1; end = str + count - 1;
SnprfOverflow = 0; SnprfOverflow = 0;
dopr(str, fmt, args); dopr(str, fmt, args);
if (count > 0) if (count > 0)
end[0] = 0; end[0] = '\0';
if (SnprfOverflow) if (SnprfOverflow)
elog(NOTICE, "vsnprintf overflow, len = %d, str = %s", elog(DEBUG, "vsnprintf overflow, len = %d, str = %s",
count, str); count, str);
return strlen(str); return strlen(str);
} }
...@@ -152,6 +152,7 @@ dopr(char *buffer, const char *format, va_list args) ...@@ -152,6 +152,7 @@ dopr(char *buffer, const char *format, va_list args)
{ {
case 0: case 0:
dostr("**end of format**", 0); dostr("**end of format**", 0);
*output = '\0';
return; return;
case '-': case '-':
ljust = 1; ljust = 1;
...@@ -287,7 +288,7 @@ dopr(char *buffer, const char *format, va_list args) ...@@ -287,7 +288,7 @@ dopr(char *buffer, const char *format, va_list args)
break; break;
} }
} }
*output = 0; *output = '\0';
} }
static void static void
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: stringinfo.h,v 1.13 1999/05/26 12:56:27 momjian Exp $ * $Id: stringinfo.h,v 1.14 1999/08/31 01:28:21 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -60,13 +60,11 @@ typedef StringInfoData *StringInfo; ...@@ -60,13 +60,11 @@ typedef StringInfoData *StringInfo;
*------------------------- *-------------------------
*/ */
#ifdef NOT_USED
/*------------------------ /*------------------------
* makeStringInfo * makeStringInfo
* Create an empty 'StringInfoData' & return a pointer to it. * Create an empty 'StringInfoData' & return a pointer to it.
*/ */
extern StringInfo makeStringInfo(void); extern StringInfo makeStringInfo(void);
#endif
/*------------------------ /*------------------------
* initStringInfo * initStringInfo
...@@ -81,8 +79,6 @@ extern void initStringInfo(StringInfo str); ...@@ -81,8 +79,6 @@ extern void initStringInfo(StringInfo str);
* and append it to whatever is already in str. More space is allocated * and append it to whatever is already in str. More space is allocated
* to str if necessary. This is sort of like a combination of sprintf and * to str if necessary. This is sort of like a combination of sprintf and
* strcat. * strcat.
* CAUTION: the current implementation has a 1K limit on the amount of text
* generated in a single call (not on the total string length).
*/ */
extern void appendStringInfo(StringInfo str, const char *fmt,...); extern void appendStringInfo(StringInfo str, const char *fmt,...);
...@@ -101,11 +97,4 @@ extern void appendStringInfoChar(StringInfo str, char ch); ...@@ -101,11 +97,4 @@ extern void appendStringInfoChar(StringInfo str, char ch);
extern void appendBinaryStringInfo(StringInfo str, extern void appendBinaryStringInfo(StringInfo str,
const char *data, int datalen); const char *data, int datalen);
/*------------------------
* stringStringInfo
* Return the string itself or "<>" if it is NULL.
* This is just a convenience macro used by many callers of appendStringInfo.
*/
#define stringStringInfo(s) (((s) == NULL) ? "<>" : (s))
#endif /* STRINGINFO_H */ #endif /* STRINGINFO_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment