OSDN Git Service

Minor improvements to stringinfo package to make it more
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 31 Aug 1999 01:28:37 +0000 (01:28 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 31 Aug 1999 01:28:37 +0000 (01:28 +0000)
robust, since it's about to get used much more heavily.

src/backend/commands/explain.c
src/backend/lib/stringinfo.c
src/backend/nodes/outfuncs.c
src/backend/port/snprintf.c
src/include/lib/stringinfo.h

index 47cc693..07caedd 100644 (file)
@@ -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 -
index e98a5c5..d25a2a0 100644 (file)
@@ -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);
+       }
 }
 
 /*------------------------
index 226dbb1..13e32ed 100644 (file)
@@ -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
 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
index e6ee698..95a79a5 100644 (file)
@@ -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
index da806aa..afdad2f 100644 (file)
@@ -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 */