// clang-format off /* * $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 "third_party/ctags/general.h" /* must always come first */ #include "libc/limits.h" #include "libc/sysv/consts/_posix.h" #include "libc/sysv/consts/iov.h" #include "libc/sysv/consts/limits.h" #include "libc/sysv/consts/xopen.h" #include "libc/thread/thread.h" /* to define INT_MAX */ #include "libc/mem/alg.h" #include "libc/str/str.h" #include "libc/str/str.h" #include "third_party/ctags/debug.h" #include "third_party/ctags/routines.h" #include "third_party/ctags/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: */