1 /* $Id: Str.c,v 1.8 2002/12/24 17:20:46 ukai Exp $ */
3 * String manipulation library for Boehm GC
5 * (C) Copyright 1998-1999 by Akinori Ito
7 * This software may be redistributed freely for this purpose, in full
8 * or in part, provided that this entire copyright notice is included
9 * on any copies of this software and applications and derivations thereof.
11 * This software is provided on an "as is" basis, without warranty of any
12 * kind, either expressed or implied, as to any matter including, but not
13 * limited to warranty of fitness of purpose, or merchantability, or
14 * results obtained from use of this software.
21 #ifdef __EMX__ /* or include "fm.h" for HAVE_BCOPY? */
27 #define INITIAL_STR_SIZE 32
30 /* This is obsolete, because "Str" can handle a '\0' character now. */
31 #define STR_LENGTH_CHECK(x) if (((x)->ptr==0&&(x)->length!=0)||(strlen((x)->ptr)!=(x)->length))abort();
32 #else /* not STR_DEBUG */
33 #define STR_LENGTH_CHECK(x)
34 #endif /* not STR_DEBUG */
39 Str x = GC_MALLOC(sizeof(struct _Str));
40 x->ptr = GC_MALLOC_ATOMIC(INITIAL_STR_SIZE);
42 x->area_size = INITIAL_STR_SIZE;
50 Str x = GC_MALLOC(sizeof(struct _Str));
51 x->ptr = GC_MALLOC_ATOMIC(n + 1);
66 x = GC_MALLOC(sizeof(struct _Str));
68 x->ptr = GC_MALLOC_ATOMIC(n);
71 bcopy((void *)p, (void *)x->ptr, n);
76 Strnew_m_charp(char *p, ...)
84 p = va_arg(ap, char *);
90 Strnew_charp_n(char *p, int n)
95 return Strnew_size(n);
96 x = GC_MALLOC(sizeof(struct _Str));
97 x->ptr = GC_MALLOC_ATOMIC(n + 1);
100 bcopy((void *)p, (void *)x->ptr, n);
108 Str n = Strnew_size(s->length);
129 Strcopy(Str x, Str y)
133 if (x->area_size < y->length + 1) {
135 x->ptr = GC_MALLOC_ATOMIC(y->length + 1);
136 x->area_size = y->length + 1;
138 bcopy((void *)y->ptr, (void *)x->ptr, y->length + 1);
139 x->length = y->length;
143 Strcopy_charp(Str x, char *y)
153 if (x->area_size < len + 1) {
155 x->ptr = GC_MALLOC_ATOMIC(len + 1);
156 x->area_size = len + 1;
158 bcopy((void *)y, (void *)x->ptr, len + 1);
163 Strcopy_charp_n(Str x, char *y, int n)
172 if (x->area_size < len + 1) {
174 x->ptr = GC_MALLOC_ATOMIC(len + 1);
175 x->area_size = len + 1;
177 bcopy((void *)y, (void *)x->ptr, n);
183 Strcat_charp_n(Str x, char *y, int n)
190 newlen = x->length + n + 1;
191 if (x->area_size < newlen) {
193 newlen = newlen * 3 / 2;
194 x->ptr = GC_MALLOC_ATOMIC(newlen);
195 x->area_size = newlen;
196 bcopy((void *)old, (void *)x->ptr, x->length);
199 bcopy((void *)y, (void *)&x->ptr[x->length], n);
201 x->ptr[x->length] = '\0';
208 Strcat_charp_n(x, y->ptr, y->length);
212 Strcat_charp(Str x, char *y)
216 Strcat_charp_n(x, y, strlen(y));
220 Strcat_m_charp(Str x, ...)
226 while ((p = va_arg(ap, char *)) != NULL)
227 Strcat_charp_n(x, p, strlen(p));
235 newlen = x->length * 6 / 5;
236 if (newlen == x->length)
238 x->ptr = GC_MALLOC_ATOMIC(newlen);
239 x->area_size = newlen;
240 bcopy((void *)old, (void *)x->ptr, x->length);
245 Strsubstr(Str s, int beg, int len)
252 if (beg >= s->length)
254 for (i = 0; i < len && beg + i < s->length; i++)
255 Strcat_char(new_s, s->ptr[beg + i]);
264 for (i = 0; i < s->length; i++)
265 s->ptr[i] = TOLOWER(s->ptr[i]);
273 for (i = 0; i < s->length; i++)
274 s->ptr[i] = TOUPPER(s->ptr[i]);
281 while ((s->ptr[s->length - 1] == '\n' || s->ptr[s->length - 1] == '\r') &&
285 s->ptr[s->length] = '\0';
289 Strinsert_char(Str s, int pos, char c)
293 if (pos < 0 || s->length < pos)
295 if (s->length + 2 > s->area_size)
297 for (i = s->length; i > pos; i--)
298 s->ptr[i] = s->ptr[i - 1];
299 s->ptr[++s->length] = '\0';
304 Strinsert_charp(Str s, int pos, char *p)
308 Strinsert_char(s, pos++, *(p++));
312 Strdelete(Str s, int pos, int n)
316 if (s->length <= pos + n) {
321 for (i = pos; i < s->length - n; i++)
322 s->ptr[i] = s->ptr[i + n];
328 Strtruncate(Str s, int pos)
336 Strshrink(Str s, int n)
339 if (n >= s->length) {
345 s->ptr[s->length] = '\0';
350 Strremovefirstspaces(Str s)
355 for (i = 0; i < s->length && IS_SPACE(s->ptr[i]); i++) ;
362 Strremovetrailingspaces(Str s)
367 for (i = s->length - 1; i >= 0 && IS_SPACE(s->ptr[i]); i--) ;
369 s->ptr[i + 1] = '\0';
373 Stralign_left(Str s, int width)
379 if (s->length >= width)
381 n = Strnew_size(width);
383 for (i = s->length; i < width; i++)
389 Stralign_right(Str s, int width)
395 if (s->length >= width)
397 n = Strnew_size(width);
398 for (i = s->length; i < width; i++)
405 Stralign_center(Str s, int width)
411 if (s->length >= width)
413 n = Strnew_size(width);
414 w = (width - s->length) / 2;
415 for (i = 0; i < w; i++)
418 for (i = w + s->length; i < width; i++)
428 Sprintf(char *fmt, ...)
431 int status = SP_NORMAL;
438 for (f = fmt; *f; f++) {
451 /* conversion char. */
469 vi = va_arg(ap, int);
470 len += (p > 0) ? p : 10;
477 vd = va_arg(ap, double);
478 len += (p > 0) ? p : 15;
482 vi = va_arg(ap, int);
485 vs = va_arg(ap, char *);
487 len += (p > vi) ? p : vi;
490 vp = va_arg(ap, void *);
494 vp = va_arg(ap, void *);
499 else if (IS_DIGIT(*f))
500 p = p * 10 + *f - '0';
503 else if (*f == '%') {
517 s = Strnew_size(len * 2);
519 vsprintf(s->ptr, fmt, ap);
521 s->length = strlen(s->ptr);
522 if (s->length > len * 2) {
523 fprintf(stderr, "Sprintf: string too long\n");
536 if (feof(f) || ferror(f))
552 if (feof(f) || ferror(f))