From: Tom Lane Date: Tue, 31 Aug 1999 01:28:37 +0000 (+0000) Subject: Minor improvements to stringinfo package to make it more X-Git-Tag: REL9_0_0~24885 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=130e372b5d55fcd8201518adc9025a5cb0f13b56;p=pg-rex%2Fsyncrep.git Minor improvements to stringinfo package to make it more robust, since it's about to get used much more heavily. --- diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 47cc693e9f..07caedde8b 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -4,7 +4,7 @@ * * 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 ExplainOneQuery(Query *query, bool verbose, CommandDest dest); +/* Convert a null string pointer into "<>" */ +#define stringStringInfo(s) (((s) == NULL) ? "<>" : (s)) + /* * ExplainQuery - diff --git a/src/backend/lib/stringinfo.c b/src/backend/lib/stringinfo.c index e98a5c5f4d..d25a2a00a7 100644 --- a/src/backend/lib/stringinfo.c +++ b/src/backend/lib/stringinfo.c @@ -8,7 +8,7 @@ * * 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 "lib/stringinfo.h" -#ifdef NOT_USED /* * makeStringInfo * @@ -36,7 +35,6 @@ makeStringInfo(void) return res; } -#endif /* * initStringInfo @@ -49,7 +47,7 @@ initStringInfo(StringInfo str) { int size = 256; /* initial default buffer size */ - str->data = palloc(size); + str->data = (char *) palloc(size); if (str->data == NULL) elog(ERROR, "initStringInfo: Out of memory (%d bytes requested)", size); @@ -68,7 +66,6 @@ static void enlargeStringInfo(StringInfo str, int needed) { int newlen; - char *newdata; needed += str->len + 1; /* total space required now */ if (needed <= str->maxlen) @@ -84,15 +81,11 @@ enlargeStringInfo(StringInfo str, int needed) while (needed > newlen) newlen = 2 * newlen; - newdata = palloc(newlen); - if (newdata == NULL) + str->data = (char *) repalloc(str->data, newlen); + if (str->data == NULL) 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; } @@ -103,29 +96,41 @@ enlargeStringInfo(StringInfo str, int needed) * 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 * 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 appendStringInfo(StringInfo str, const char *fmt,...) { va_list args; - char buffer[1024]; - int buflen; + int avail, + nprinted; Assert(str != NULL); - va_start(args, fmt); - buflen = vsnprintf(buffer, sizeof(buffer), fmt, args); - va_end(args); - - /* Make more room if needed */ - enlargeStringInfo(str, buflen); - - /* OK, append the data, including the trailing null */ - memcpy(str->data + str->len, buffer, buflen + 1); - str->len += buflen; + for (;;) + { + /*---------- + * Try to format the given string into the available space; + * but if there's hardly any space, don't bother trying, + * just fall through to enlarge the buffer first. + *---------- + */ + avail = str->maxlen - str->len - 1; + 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); + } } /*------------------------ diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 226dbb1cef..13e32ed54f 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -5,7 +5,7 @@ * * 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 * 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 _outNode(StringInfo str, void *obj); +/* Convert a null string pointer into "<>" */ +#define stringStringInfo(s) (((s) == NULL) ? "<>" : (s)) + + /* * _outIntList - * converts a List of integers diff --git a/src/backend/port/snprintf.c b/src/backend/port/snprintf.c index e6ee698e66..95a79a504d 100644 --- a/src/backend/port/snprintf.c +++ b/src/backend/port/snprintf.c @@ -74,7 +74,7 @@ typedef unsigned long ulong_long; * 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 int SnprfOverflow; @@ -98,14 +98,14 @@ snprintf(char *str, size_t count, const char *fmt,...) int vsnprintf(char *str, size_t count, const char *fmt, va_list args) { - str[0] = 0; + str[0] = '\0'; end = str + count - 1; SnprfOverflow = 0; dopr(str, fmt, args); if (count > 0) - end[0] = 0; + end[0] = '\0'; if (SnprfOverflow) - elog(NOTICE, "vsnprintf overflow, len = %d, str = %s", + elog(DEBUG, "vsnprintf overflow, len = %d, str = %s", count, str); return strlen(str); } @@ -152,6 +152,7 @@ dopr(char *buffer, const char *format, va_list args) { case 0: dostr("**end of format**", 0); + *output = '\0'; return; case '-': ljust = 1; @@ -287,7 +288,7 @@ dopr(char *buffer, const char *format, va_list args) break; } } - *output = 0; + *output = '\0'; } static void diff --git a/src/include/lib/stringinfo.h b/src/include/lib/stringinfo.h index da806aa433..afdad2f8d3 100644 --- a/src/include/lib/stringinfo.h +++ b/src/include/lib/stringinfo.h @@ -9,7 +9,7 @@ * * 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 * Create an empty 'StringInfoData' & return a pointer to it. */ extern StringInfo makeStringInfo(void); -#endif /*------------------------ * initStringInfo @@ -81,8 +79,6 @@ extern void initStringInfo(StringInfo str); * 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 * 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,...); @@ -101,11 +97,4 @@ extern void appendStringInfoChar(StringInfo str, char ch); extern void appendBinaryStringInfo(StringInfo str, 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 */