1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* An abstract string datatype. 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc. 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Contributed by Mark Mitchell (mark@markmitchell.com). 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownThis file is part of GNU CC. 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownGNU CC is free software; you can redistribute it and/or modify 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownit under the terms of the GNU General Public License as published by 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownthe Free Software Foundation; either version 2, or (at your option) 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownany later version. 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownIn addition to the permissions in the GNU General Public License, the 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownFree Software Foundation gives you unlimited permission to link the 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browncompiled version of this file into combinations with other programs, 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownand to distribute those combinations without any restriction coming 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownfrom the use of this file. (The General Public License restrictions 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndo apply in other respects; for example, they cover modification of 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownthe file, and distribution when not linked into a combined 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownexecutable.) 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownGNU CC is distributed in the hope that it will be useful, 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownbut WITHOUT ANY WARRANTY; without even the implied warranty of 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownGNU General Public License for more details. 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownYou should have received a copy of the GNU General Public License 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownalong with GNU CC; see the file COPYING. If not, write to 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownthe Free Software Foundation, 51 Franklin Street - Fifth Floor, 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBoston, MA 02110-1301, USA. */ 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 /* in valgrind */ 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef HAVE_CONFIG_H 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "config.h" 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! in valgrind */ 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 /* in valgrind */ 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h> 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! in valgrind */ 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 /* in valgrind */ 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef HAVE_STRING_H 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <string.h> 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! in valgrind */ 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 /* in valgrind */ 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef HAVE_STDLIB_H 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h> 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! in valgrind */ 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 /* in valgrind */ 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libiberty.h" 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ! in valgrind */ 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "vg_libciface.h" 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "dyn-string.h" 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Performs in-place initialization of a dyn_string struct. This 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown function can be used with a dyn_string struct on the stack or 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown embedded in another object. The contents of of the string itself 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are still dynamically allocated. The string initially is capable 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of holding at least SPACE characeters, including the terminating 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown NUL. If SPACE is 0, it will silently be increated to 1. 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If RETURN_ON_ALLOCATION_FAILURE is defined and memory allocation 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fails, returns 0. Otherwise returns 1. */ 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_init (struct dyn_string *ds_struct_ptr, int space) 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We need at least one byte in which to store the terminating NUL. */ 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (space == 0) 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown space = 1; 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef RETURN_ON_ALLOCATION_FAILURE 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ds_struct_ptr->s = (char *) malloc (space); 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ds_struct_ptr->s == NULL) 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ds_struct_ptr->s = XNEWVEC (char, space); 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ds_struct_ptr->allocated = space; 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ds_struct_ptr->length = 0; 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ds_struct_ptr->s[0] = '\0'; 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1; 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Create a new dynamic string capable of holding at least SPACE 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown characters, including the terminating NUL. If SPACE is 0, it will 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be silently increased to 1. If RETURN_ON_ALLOCATION_FAILURE is 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown defined and memory allocation fails, returns NULL. Otherwise 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown returns the newly allocated string. */ 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_t 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_new (int space) 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dyn_string_t result; 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef RETURN_ON_ALLOCATION_FAILURE 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result = (dyn_string_t) malloc (sizeof (struct dyn_string)); 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (result == NULL) 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!dyn_string_init (result, space)) 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown free (result); 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result = XNEW (struct dyn_string); 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dyn_string_init (result, space); 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return result; 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Free the memory used by DS. */ 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_delete (dyn_string_t ds) 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown free (ds->s); 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown free (ds); 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Returns the contents of DS in a buffer allocated with malloc. It 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is the caller's responsibility to deallocate the buffer using free. 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DS is then set to the empty string. Deletes DS itself. */ 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchar* 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_release (dyn_string_t ds) 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Store the old buffer. */ 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown char* result = ds->s; 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The buffer is no longer owned by DS. */ 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ds->s = NULL; 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Delete DS. */ 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown free (ds); 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Return the old buffer. */ 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return result; 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Increase the capacity of DS so it can hold at least SPACE 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown characters, plus the terminating NUL. This function will not (at 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown present) reduce the capacity of DS. Returns DS on success. 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If RETURN_ON_ALLOCATION_FAILURE is defined and a memory allocation 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown operation fails, deletes DS and returns NULL. */ 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_t 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_resize (dyn_string_t ds, int space) 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int new_allocated = ds->allocated; 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Increase SPACE to hold the NUL termination. */ 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ++space; 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Increase allocation by factors of two. */ 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (space > new_allocated) 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown new_allocated *= 2; 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (new_allocated != ds->allocated) 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ds->allocated = new_allocated; 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We actually need more space. */ 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef RETURN_ON_ALLOCATION_FAILURE 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ds->s = (char *) realloc (ds->s, ds->allocated); 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ds->s == NULL) 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown free (ds); 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ds->s = XRESIZEVEC (char, ds->s, ds->allocated); 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ds; 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Sets the contents of DS to the empty string. */ 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_clear (dyn_string_t ds) 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A dyn_string always has room for at least the NUL terminator. */ 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ds->s[0] = '\0'; 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ds->length = 0; 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Makes the contents of DEST the same as the contents of SRC. DEST 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and SRC must be distinct. Returns 1 on success. On failure, if 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_copy (dyn_string_t dest, dyn_string_t src) 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dest == src) 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown abort (); 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Make room in DEST. */ 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dyn_string_resize (dest, src->length) == NULL) 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Copy DEST into SRC. */ 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown strcpy (dest->s, src->s); 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Update the size of DEST. */ 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->length = src->length; 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1; 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Copies SRC, a NUL-terminated string, into DEST. Returns 1 on 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and returns 0. */ 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_copy_cstr (dyn_string_t dest, const char *src) 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int length = strlen (src); 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Make room in DEST. */ 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dyn_string_resize (dest, length) == NULL) 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Copy DEST into SRC. */ 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown strcpy (dest->s, src); 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Update the size of DEST. */ 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->length = length; 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1; 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Inserts SRC at the beginning of DEST. DEST is expanded as 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown necessary. SRC and DEST must be distinct. Returns 1 on success. 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown returns 0. */ 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_prepend (dyn_string_t dest, dyn_string_t src) 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return dyn_string_insert (dest, 0, src); 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Inserts SRC, a NUL-terminated string, at the beginning of DEST. 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DEST is expanded as necessary. Returns 1 on success. On failure, 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_prepend_cstr (dyn_string_t dest, const char *src) 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return dyn_string_insert_cstr (dest, 0, src); 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Inserts SRC into DEST starting at position POS. DEST is expanded 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown as necessary. SRC and DEST must be distinct. Returns 1 on 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and returns 0. */ 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_insert (dyn_string_t dest, int pos, dyn_string_t src) 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i; 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (src == dest) 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown abort (); 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dyn_string_resize (dest, dest->length + src->length) == NULL) 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Make room for the insertion. Be sure to copy the NUL. */ 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = dest->length; i >= pos; --i) 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->s[i + src->length] = dest->s[i]; 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Splice in the new stuff. */ 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown strncpy (dest->s + pos, src->s, src->length); 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Compute the new length. */ 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->length += src->length; 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1; 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Inserts SRC, a NUL-terminated string, into DEST starting at 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown position POS. DEST is expanded as necessary. Returns 1 on 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown success. On failure, RETURN_ON_ALLOCATION_FAILURE, deletes DEST 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and returns 0. */ 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_insert_cstr (dyn_string_t dest, int pos, const char *src) 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i; 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int length = strlen (src); 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dyn_string_resize (dest, dest->length + length) == NULL) 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Make room for the insertion. Be sure to copy the NUL. */ 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = dest->length; i >= pos; --i) 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->s[i + length] = dest->s[i]; 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Splice in the new stuff. */ 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown strncpy (dest->s + pos, src, length); 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Compute the new length. */ 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->length += length; 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1; 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Inserts character C into DEST starting at position POS. DEST is 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown expanded as necessary. Returns 1 on success. On failure, 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_insert_char (dyn_string_t dest, int pos, int c) 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i; 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dyn_string_resize (dest, dest->length + 1) == NULL) 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Make room for the insertion. Be sure to copy the NUL. */ 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = dest->length; i >= pos; --i) 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->s[i + 1] = dest->s[i]; 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Add the new character. */ 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->s[pos] = c; 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Compute the new length. */ 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ++dest->length; 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1; 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Append S to DS, resizing DS if necessary. Returns 1 on success. 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown returns 0. */ 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_append (dyn_string_t dest, dyn_string_t s) 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dyn_string_resize (dest, dest->length + s->length) == 0) 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown strcpy (dest->s + dest->length, s->s); 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->length += s->length; 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1; 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Append the NUL-terminated string S to DS, resizing DS if necessary. 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE, 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deletes DEST and returns 0. */ 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_append_cstr (dyn_string_t dest, const char *s) 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int len = strlen (s); 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The new length is the old length plus the size of our string, plus 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown one for the null at the end. */ 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dyn_string_resize (dest, dest->length + len) == NULL) 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown strcpy (dest->s + dest->length, s); 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->length += len; 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1; 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Appends C to the end of DEST. Returns 1 on success. On failure, 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_append_char (dyn_string_t dest, int c) 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Make room for the extra character. */ 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dyn_string_resize (dest, dest->length + 1) == NULL) 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Append the character; it will overwrite the old NUL. */ 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->s[dest->length] = c; 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Add a new NUL at the end. */ 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->s[dest->length + 1] = '\0'; 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Update the length. */ 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ++(dest->length); 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1; 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Sets the contents of DEST to the substring of SRC starting at START 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and ending before END. START must be less than or equal to END, 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and both must be between zero and the length of SRC, inclusive. 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE, 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deletes DEST and returns 0. */ 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_substring (dyn_string_t dest, dyn_string_t src, 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int start, int end) 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i; 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int length = end - start; 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (start > end || start > src->length || end > src->length) 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown abort (); 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Make room for the substring. */ 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dyn_string_resize (dest, length) == NULL) 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Copy the characters in the substring, */ 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = length; --i >= 0; ) 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->s[i] = src->s[start + i]; 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* NUL-terimate the result. */ 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->s[length] = '\0'; 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Record the length of the substring. */ 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dest->length = length; 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 1; 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Returns non-zero if DS1 and DS2 have the same contents. */ 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browndyn_string_eq (dyn_string_t ds1, dyn_string_t ds2) 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If DS1 and DS2 have different lengths, they must not be the same. */ 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ds1->length != ds2->length) 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return !strcmp (ds1->s, ds2->s); 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 411