lib/dystring.c

Go to the documentation of this file.
00001 /* dystring - dynamically resizing string. 
00002  *
00003  * This file is copyright 2002 Jim Kent, but license is hereby
00004  * granted for all use - public, private or commercial. */
00005 
00006 #include "common.h"
00007 #include "dystring.h"
00008 
00009 static char const rcsid[] = "$Id: dystring.c,v 1.22 2006/02/02 16:24:24 kent Exp $";
00010 
00011 struct dyString *newDyString(int initialBufSize)
00012 /* Allocate dynamic string with initial buffer size.  (Pass zero for default) */
00013 {
00014 struct dyString *ds;
00015 AllocVar(ds);
00016 if (initialBufSize == 0)
00017     initialBufSize = 512;
00018 ds->string = needMem(initialBufSize+1);
00019 ds->bufSize = initialBufSize;
00020 return ds;
00021 }
00022 
00023 void freeDyString(struct dyString **pDs)
00024 /* Free up dynamic string. */
00025 {
00026 struct dyString *ds;
00027 if ((ds = *pDs) != NULL)
00028     {
00029     freeMem(ds->string);
00030     freez(pDs);
00031     }
00032 }
00033 
00034 char *dyStringCannibalize(struct dyString **pDy)
00035 /* Kill dyString, but return the string it is wrapping
00036  * (formerly dy->string).  This should be free'd at your
00037  * convenience. */
00038 {
00039 char *s;
00040 struct dyString *ds = *pDy;
00041 assert(ds != NULL);
00042 s = ds->string;
00043 freez(pDy);
00044 return s;
00045 }
00046 
00047 void freeDyStringList(struct dyString **pDs)
00048 /* free up a list of dyStrings */
00049 {
00050 struct dyString *ds, *next;
00051 for(ds = *pDs; ds != NULL; ds = next)
00052     {
00053     next = ds->next;
00054     freeDyString(&ds);
00055     }
00056 *pDs = NULL;
00057 }
00058 
00059 static void dyStringExpandBuf(struct dyString *ds, int newSize)
00060 /* Expand buffer to new size. */
00061 {
00062 ds->string = needMoreMem(ds->string, ds->stringSize+1, newSize+1);
00063 ds->bufSize = newSize;
00064 }
00065 
00066 void dyStringBumpBufSize(struct dyString *ds, int size)
00067 /* Force dyString buffer to be at least given size. */
00068 {
00069 if (ds->bufSize < size)
00070     dyStringExpandBuf(ds, size);
00071 }
00072 
00073 void dyStringAppendN(struct dyString *ds, char *string, int stringSize)
00074 /* Append string of given size to end of string. */
00075 {
00076 int oldSize = ds->stringSize;
00077 int newSize = oldSize + stringSize;
00078 int newAllocSize = newSize + oldSize;
00079 char *buf;
00080 if (newSize > ds->bufSize)
00081     dyStringExpandBuf(ds,newAllocSize);
00082 buf = ds->string;
00083 memcpy(buf+oldSize, string, stringSize);
00084 ds->stringSize = newSize;
00085 buf[newSize] = 0;
00086 }
00087 
00088 char dyStringAppendC(struct dyString *ds, char c)
00089 /* Append char to end of string. */
00090 {
00091 char *s;
00092 if (ds->stringSize >= ds->bufSize)
00093      dyStringExpandBuf(ds, ds->bufSize+256);
00094 s = ds->string + ds->stringSize++;
00095 *s++ = c;
00096 *s = 0;
00097 return c;
00098 }
00099 
00100 void dyStringAppendMultiC(struct dyString *ds, char c, int n)
00101 /* Append N copies of char to end of string. */ 
00102 {
00103 int oldSize = ds->stringSize;
00104 int newSize = oldSize + n;
00105 int newAllocSize = newSize + oldSize;
00106 char *buf;
00107 if (newSize > ds->bufSize)
00108     dyStringExpandBuf(ds,newAllocSize);
00109 buf = ds->string;
00110 memset(buf+oldSize, c, n);
00111 ds->stringSize = newSize;
00112 buf[newSize] = 0;
00113 }
00114 
00115 void dyStringAppend(struct dyString *ds, char *string)
00116 /* Append zero terminated string to end of dyString. */
00117 {
00118 dyStringAppendN(ds, string, strlen(string));
00119 }
00120 
00121 void dyStringAppendEscapeQuotes(struct dyString *dy, char *string, 
00122         char quot, char esc)
00123 /* Append escaped-for-quotation version of string to dy. */
00124 {
00125 char c;
00126 char *s = string;
00127 while ((c = *s++) != 0)
00128      {
00129      if (c == quot)
00130          dyStringAppendC(dy, esc);
00131      dyStringAppendC(dy, c);
00132      }
00133 }
00134 
00135 void dyStringVaPrintf(struct dyString *ds, char *format, va_list args)
00136 /* VarArgs Printf to end of dyString. */
00137 {
00138 /* attempt to format the string in the current space.  If there
00139  * is not enough room, increase the buffer size and try again */
00140 int avail, sz;
00141 while (TRUE) 
00142     {
00143     va_list argscp;
00144     va_copy(argscp, args);
00145     avail = ds->bufSize - ds->stringSize;
00146     if (avail <= 0)
00147         {
00148         /* Don't pass zero sized buffers to vsnprintf, because who knows
00149          * if the library function will handle it. */
00150         dyStringExpandBuf(ds, ds->bufSize+ds->bufSize);
00151         avail = ds->bufSize - ds->stringSize;
00152         }
00153     sz = vsnprintf(ds->string + ds->stringSize, avail, format, argscp);
00154     va_end(argscp);
00155 
00156     /* note that some version return -1 if too small */
00157     if ((sz < 0) || (sz >= avail))
00158         dyStringExpandBuf(ds, ds->bufSize+ds->bufSize);
00159     else
00160         {
00161         ds->stringSize += sz;
00162         break;
00163         }
00164     }
00165 }
00166 
00167 void dyStringPrintf(struct dyString *ds, char *format, ...)
00168 /*  Printf to end of dyString. */
00169 {
00170 va_list args;
00171 va_start(args, format);
00172 dyStringVaPrintf(ds, format, args);
00173 va_end(args);
00174 }
00175 
00176 struct dyString * dyStringSub(char *orig, char *in, char *out)
00177 /* Make up a duplicate of orig with all occurences of in substituted
00178  * with out. */
00179 {
00180 int inLen = strlen(in), outLen = strlen(out), origLen = strlen(orig);
00181 struct dyString *dy = newDyString(origLen + 2*outLen);
00182 char *s, *e;
00183 
00184 if (orig == NULL) return NULL;
00185 for (s = orig; ;)
00186     {
00187     e = stringIn(in, s);
00188     if (e == NULL) 
00189         {
00190         e = orig + origLen;
00191         dyStringAppendN(dy, s, e - s);
00192         break;
00193         }
00194     else
00195         {
00196         dyStringAppendN(dy, s, e - s);
00197         dyStringAppendN(dy, out, outLen);
00198         s = e + inLen;
00199         }
00200     }
00201 return dy;
00202 }
00203 
00204 void dyStringResize(struct dyString *ds, int newSize)
00205 /* resize a string, if the string expands, blanks are appended */
00206 {
00207 int oldSize = ds->stringSize;
00208 if (newSize > oldSize)
00209     {
00210     /* grow */
00211     if (newSize > ds->bufSize)
00212         dyStringExpandBuf(ds, newSize + ds->stringSize);
00213     memset(ds->string+newSize, ' ', newSize);
00214     }
00215 ds->string[newSize] = '\0';
00216 ds->stringSize = newSize;
00217 }

Generated on Tue Dec 25 18:39:30 2007 for blat by  doxygen 1.5.2