summaryrefslogtreecommitdiff
path: root/vstring.c
diff options
context:
space:
mode:
Diffstat (limited to 'vstring.c')
-rw-r--r--vstring.c232
1 files changed, 232 insertions, 0 deletions
diff --git a/vstring.c b/vstring.c
new file mode 100644
index 0000000..7ab52cc
--- /dev/null
+++ b/vstring.c
@@ -0,0 +1,232 @@
+/*
+* $Id: vstring.c 558 2007-06-15 19:17:02Z elliotth $
+*
+* Copyright (c) 1998-2002, Darren Hiebert
+*
+* This source code is released for free distribution under the terms of the
+* GNU General Public License.
+*
+* This module contains functions supporting resizeable strings.
+*/
+
+/*
+* INCLUDE FILES
+*/
+#include "general.h" /* must always come first */
+
+#include <limits.h> /* to define INT_MAX */
+#include <string.h>
+#include <ctype.h>
+
+#include "debug.h"
+#include "routines.h"
+#include "vstring.h"
+
+/*
+* DATA DEFINITIONS
+*/
+static const size_t vStringInitialSize = 32;
+
+/*
+* FUNCTION DEFINITIONS
+*/
+
+static void vStringResize (vString *const string, const size_t newSize)
+{
+ char *const newBuffer = xRealloc (string->buffer, newSize, char);
+
+ string->size = newSize;
+ string->buffer = newBuffer;
+}
+
+/*
+* External interface
+*/
+
+extern boolean vStringAutoResize (vString *const string)
+{
+ boolean ok = TRUE;
+
+ if (string->size <= INT_MAX / 2)
+ {
+ const size_t newSize = string->size * 2;
+
+ vStringResize (string, newSize);
+ }
+ return ok;
+}
+
+extern void vStringClear (vString *const string)
+{
+ string->length = 0;
+ string->buffer [0] = '\0';
+ DebugStatement ( memset (string->buffer, 0, string->size); )
+}
+
+extern void vStringDelete (vString *const string)
+{
+ if (string != NULL)
+ {
+ if (string->buffer != NULL)
+ eFree (string->buffer);
+ eFree (string);
+ }
+}
+
+extern vString *vStringNew (void)
+{
+ vString *const string = xMalloc (1, vString);
+
+ string->length = 0;
+ string->size = vStringInitialSize;
+ string->buffer = xMalloc (string->size, char);
+
+ vStringClear (string);
+
+ return string;
+}
+
+#ifndef VSTRING_PUTC_MACRO
+extern void vStringPut (vString *const string, const int c)
+{
+ if (string->length + 1 == string->size) /* check for buffer overflow */
+ vStringAutoResize (string);
+
+ string->buffer [string->length] = c;
+ if (c != '\0')
+ string->buffer [++string->length] = '\0';
+}
+#endif
+
+extern void vStringCatS (vString *const string, const char *const s)
+{
+#if 1
+ const size_t len = strlen (s);
+ while (string->length + len + 1 >= string->size)/* check for buffer overflow */
+ vStringAutoResize (string);
+ strcpy (string->buffer + string->length, s);
+ string->length += len;
+#else
+ const char *p = s;
+ do
+ vStringPut (string, *p);
+ while (*p++ != '\0');
+#endif
+}
+
+extern vString *vStringNewCopy (const vString *const string)
+{
+ vString *vs = vStringNew ();
+ vStringCatS (vs, string->buffer);
+ return vs;
+}
+
+extern vString *vStringNewInit (const char *const s)
+{
+ vString *vs = vStringNew ();
+ vStringCatS (vs, s);
+ return vs;
+}
+
+extern void vStringNCatS (
+ vString *const string, const char *const s, const size_t length)
+{
+ const char *p = s;
+ size_t remain = length;
+
+ while (*p != '\0' && remain > 0)
+ {
+ vStringPut (string, *p);
+ --remain;
+ ++p;
+ }
+ vStringTerminate (string);
+}
+
+/* Strip trailing newline from string.
+ */
+extern void vStringStripNewline (vString *const string)
+{
+ const size_t final = string->length - 1;
+ if (string->buffer [final] == '\n')
+ {
+ string->buffer [final] = '\0';
+ string->length--;
+ }
+}
+
+/* Strip leading white space from string.
+ */
+extern void vStringStripLeading (vString *const string)
+{
+ while (isspace ((int) string->buffer [0]) && string->length > 0)
+ {
+ size_t i;
+ for (i = 1 ; i < string->length ; ++i)
+ string->buffer [i - 1] = string->buffer [i];
+ --string->length;
+ string->buffer [string->length] = '\0';
+ }
+}
+
+/* Strip trailing white space from string.
+ */
+extern void vStringStripTrailing (vString *const string)
+{
+ while (isspace ((int) string->buffer [string->length - 1]) &&
+ string->length > 0)
+ {
+ string->length--;
+ string->buffer [string->length] = '\0';
+ }
+}
+
+/* Chop last character from string.
+ */
+extern void vStringChop (vString *const string)
+{
+ if (string->length > 0)
+ {
+ --string->length;
+ string->buffer [string->length] = '\0';
+ }
+}
+
+extern void vStringCopyS (vString *const string, const char *const s)
+{
+ vStringClear (string);
+ vStringCatS (string, s);
+}
+
+extern void vStringNCopyS (
+ vString *const string, const char *const s, const size_t length)
+{
+ vStringClear (string);
+ vStringNCatS (string, s, length);
+}
+
+extern void vStringCopyToLower (vString *const dest, const vString *const src)
+{
+ const size_t length = src->length;
+ const char *s = src->buffer;
+ char *d;
+ size_t i;
+
+ if (dest->size < src->size)
+ vStringResize (dest, src->size);
+ d = dest->buffer;
+ for (i = 0 ; i < length ; ++i)
+ {
+ int c = s [i];
+
+ d [i] = tolower (c);
+ }
+ d [i] = '\0';
+}
+
+extern void vStringSetLength (vString *const string)
+{
+ string->length = strlen (string->buffer);
+}
+
+/* vi:set tabstop=4 shiftwidth=4: */