1998-12-14 09:11:17 +01:00
|
|
|
/*
|
1999-02-14 00:22:53 +01:00
|
|
|
* stringinfo.c
|
1997-09-07 07:04:48 +02:00
|
|
|
* These are routines that can be used to write informations to a string,
|
|
|
|
* without having to worry about string lengths, space allocation etc.
|
|
|
|
* Ideally the interface should look like the file i/o interface,
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
* Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* $Id: stringinfo.c,v 1.14 1999/02/13 23:15:36 momjian Exp $
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1998-12-14 09:11:17 +01:00
|
|
|
|
|
|
|
#include <stdio.h>
|
1996-07-09 08:22:35 +02:00
|
|
|
#include <string.h>
|
1996-11-06 09:27:16 +01:00
|
|
|
|
1998-12-14 09:11:17 +01:00
|
|
|
#include <stdarg.h>
|
|
|
|
|
1996-11-06 09:27:16 +01:00
|
|
|
#include <postgres.h>
|
|
|
|
|
|
|
|
#include <nodes/pg_list.h>
|
|
|
|
#include <lib/stringinfo.h>
|
1996-07-09 08:22:35 +02:00
|
|
|
|
1998-12-14 09:11:17 +01:00
|
|
|
/*
|
1996-07-09 08:22:35 +02:00
|
|
|
* makeStringInfo
|
|
|
|
*
|
|
|
|
* Create a StringInfoData & return a pointer to it.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
StringInfo
|
|
|
|
makeStringInfo()
|
|
|
|
{
|
1997-09-08 04:41:22 +02:00
|
|
|
StringInfo res;
|
1998-11-08 20:22:24 +01:00
|
|
|
int size;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
res = (StringInfo) palloc(sizeof(StringInfoData));
|
|
|
|
if (res == NULL)
|
1998-01-07 22:07:04 +01:00
|
|
|
elog(ERROR, "makeStringInfo: Out of memory!");
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1998-11-08 20:22:24 +01:00
|
|
|
size = 256; /* initial default size */
|
1997-09-07 07:04:48 +02:00
|
|
|
res->data = palloc(size);
|
|
|
|
if (res->data == NULL)
|
|
|
|
{
|
1998-01-07 22:07:04 +01:00
|
|
|
elog(ERROR,
|
1998-11-08 20:22:24 +01:00
|
|
|
"makeStringInfo: Out of memory! (%d bytes requested)", size);
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
|
|
|
res->maxlen = size;
|
|
|
|
res->len = 0;
|
1998-11-08 20:22:24 +01:00
|
|
|
/* Make sure the string is empty initially. */
|
1997-09-07 07:04:48 +02:00
|
|
|
res->data[0] = '\0';
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return res;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
1998-12-14 09:11:17 +01:00
|
|
|
/*
|
1996-07-09 08:22:35 +02:00
|
|
|
* appendStringInfo
|
|
|
|
*
|
|
|
|
* append to the current 'StringInfo' a new string.
|
|
|
|
* If there is not enough space in the current 'data', then reallocate
|
|
|
|
* some more...
|
|
|
|
*
|
|
|
|
* NOTE: if we reallocate space, we pfree the old one!
|
1998-12-14 09:11:17 +01:00
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
void
|
1998-12-14 09:11:17 +01:00
|
|
|
appendStringInfo(StringInfo str, const char *fmt,...)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1998-12-14 09:11:17 +01:00
|
|
|
int buflen,
|
1998-11-08 20:22:24 +01:00
|
|
|
newlen,
|
|
|
|
needed;
|
1998-12-14 09:11:17 +01:00
|
|
|
char *s,
|
|
|
|
buffer[512];
|
|
|
|
|
|
|
|
va_list args;
|
|
|
|
va_start(args, fmt);
|
|
|
|
buflen = vsnprintf(buffer, 512, fmt, args);
|
|
|
|
va_end(args);
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1998-01-06 19:53:02 +01:00
|
|
|
Assert(str != NULL);
|
1998-12-14 09:11:17 +01:00
|
|
|
if (buflen == 0)
|
|
|
|
strcpy(buffer, "<>");
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/*
|
1997-09-07 07:04:48 +02:00
|
|
|
* do we have enough space to append the new string? (don't forget to
|
|
|
|
* count the null string terminating char!) If no, then reallocate
|
|
|
|
* some more.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1998-11-08 20:22:24 +01:00
|
|
|
needed = str->len + buflen + 1;
|
|
|
|
if (needed > str->maxlen)
|
1997-09-07 07:04:48 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
/*
|
|
|
|
* how much more space to allocate ? Let's say double the current
|
|
|
|
* space... However we must check if this is enough!
|
|
|
|
*/
|
1998-11-08 20:22:24 +01:00
|
|
|
newlen = 2 * str->maxlen;
|
|
|
|
while (needed > newlen)
|
1997-09-07 07:04:48 +02:00
|
|
|
newlen = 2 * newlen;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* allocate enough space.
|
|
|
|
*/
|
|
|
|
s = palloc(newlen);
|
|
|
|
if (s == NULL)
|
|
|
|
{
|
1998-01-07 22:07:04 +01:00
|
|
|
elog(ERROR,
|
1998-12-14 09:11:17 +01:00
|
|
|
"appendStringInfo: Out of memory (%d bytes requested)", newlen);
|
1997-09-07 07:04:48 +02:00
|
|
|
}
|
1998-11-08 20:22:24 +01:00
|
|
|
/*
|
|
|
|
* transfer the data. strcpy() would work, but is probably a tad
|
|
|
|
* slower than memcpy(), and since we know the string length...
|
|
|
|
*/
|
|
|
|
memcpy(s, str->data, str->len + 1);
|
1997-09-07 07:04:48 +02:00
|
|
|
pfree(str->data);
|
|
|
|
str->maxlen = newlen;
|
|
|
|
str->data = s;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
/*
|
1997-09-07 07:04:48 +02:00
|
|
|
* OK, we have enough space now, append 'buffer' at the end of the
|
1998-11-08 20:22:24 +01:00
|
|
|
* string & update the string length. NOTE: strcat() would work,
|
|
|
|
* but is certainly slower than just memcpy'ing the data to the right
|
|
|
|
* place.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
1998-11-08 20:22:24 +01:00
|
|
|
memcpy(str->data + str->len, buffer, buflen + 1);
|
1997-09-07 07:04:48 +02:00
|
|
|
str->len += buflen;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|