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:
parent
f4add18557
commit
130e372b5d
@ -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 -
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------
|
/*------------------------
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user