Minor improvements to stringinfo package to make it more

robust, since it's about to get used much more heavily.
This commit is contained in:
Tom Lane 1999-08-31 01:28:37 +00:00
parent f4add18557
commit 130e372b5d
5 changed files with 48 additions and 46 deletions

View File

@ -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);
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 -

View File

@ -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 @@
#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)
return res; return res;
} }
#endif
/* /*
* initStringInfo * initStringInfo
@ -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
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)
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)
* 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);
}
} }
/*------------------------ /*------------------------

View File

@ -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 @@
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

View File

@ -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,...)
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)
{ {
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)
break; break;
} }
} }
*output = 0; *output = '\0';
} }
static void static void

View File

@ -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;
*------------------------- *-------------------------
*/ */
#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);
* 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);
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 */