/* $Id: Str.c,v 1.8 2002/12/24 17:20:46 ukai Exp $ *//* * String manipulation library for Boehm GC * * (C) Copyright 1998-1999 by Akinori Ito * * This software may be redistributed freely for this purpose, in full * or in part, provided that this entire copyright notice is included * on any copies of this software and applications and derivations thereof. * * This software is provided on an "as is" basis, without warranty of any * kind, either expressed or implied, as to any matter including, but not * limited to warranty of fitness of purpose, or merchantability, or * results obtained from use of this software. */#include <stdio.h>#include <stdlib.h>#include <gc.h>#include <stdarg.h>#include <string.h>#ifdef __EMX__ /* or include "fm.h" for HAVE_BCOPY? */#include <strings.h>#endif#include "Str.h"#include "myctype.h" #define INITIAL_STR_SIZE 32 #ifdef STR_DEBUG/* This is obsolete, because "Str" can handle a '\0' character now. */#define STR_LENGTH_CHECK(x) if (((x)->ptr==0&&(x)->length!=0)||(strlen((x)->ptr)!=(x)->length))abort();#else /* not STR_DEBUG */#define STR_LENGTH_CHECK(x)#endif /* not STR_DEBUG */ StrStrnew(){ Str x = GC_MALLOC(sizeof(struct _Str)); if (x == NULL) exit(1); x->ptr = GC_MALLOC_ATOMIC(INITIAL_STR_SIZE); if (x->ptr == NULL) exit(1); x->ptr[0] = '\0'; x->area_size = INITIAL_STR_SIZE; x->length = 0; return x;} StrStrnew_size(int n){ Str x = GC_MALLOC(sizeof(struct _Str)); if (x == NULL) exit(1); if (n < 0 || n >= STR_SIZE_MAX) n = STR_SIZE_MAX - 1; else if (n + 1 < INITIAL_STR_SIZE) n = INITIAL_STR_SIZE - 1; x->ptr = GC_MALLOC_ATOMIC(n + 1); if (x->ptr == NULL) exit(1); x->ptr[0] = '\0'; x->area_size = n + 1; x->length = 0; return x;} StrStrnew_charp(const char *p){ Str x; int n, len; if (p == NULL) return Strnew(); x = GC_MALLOC(sizeof(struct _Str)); if (x == NULL) exit(1); n = strlen(p) + 1; if (n <= 0 || n > STR_SIZE_MAX) n = STR_SIZE_MAX; len = n - 1; if (n < INITIAL_STR_SIZE) n = INITIAL_STR_SIZE; x->ptr = GC_MALLOC_ATOMIC(n); if (x->ptr == NULL) exit(1); x->area_size = n; x->length = len; bcopy((void *)p, (void *)x->ptr, len); x->ptr[x->length] = '\0'; return x;} StrStrnew_m_charp(const char *p, ...){ va_list ap; Str r = Strnew(); va_start(ap, p); while (p != NULL) { Strcat_charp(r, p); p = va_arg(ap, char *); } va_end(ap); return r;} StrStrnew_charp_n(const char *p, int n){ Str x; int len; if (p == NULL) return Strnew_size(n); x = GC_MALLOC(sizeof(struct _Str)); if (x == NULL) exit(1); if (n < 0 || n >= STR_SIZE_MAX) n = STR_SIZE_MAX - 1; len = n; if (n + 1 < INITIAL_STR_SIZE) n = INITIAL_STR_SIZE - 1; x->ptr = GC_MALLOC_ATOMIC(n + 1); if (x->ptr == NULL) exit(1); x->area_size = n + 1; x->length = len; bcopy((void *)p, (void *)x->ptr, len); x->ptr[x->length] = '\0'; return x;} StrStrdup(Str s){ Str n = Strnew_size(s->length); STR_LENGTH_CHECK(s); Strcopy(n, s); return n;} voidStrclear(Str s){ s->length = 0; s->ptr[0] = '\0';} voidStrfree(Str x){ GC_free(x->ptr); GC_free(x);} voidStrcopy(Str x, Str y){ STR_LENGTH_CHECK(x); STR_LENGTH_CHECK(y); if (x->area_size < y->length + 1) { x->ptr = GC_REALLOC(x->ptr, y->length + 1); if (x->ptr == NULL) exit(1); x->area_size = y->length + 1; } bcopy((void *)y->ptr, (void *)x->ptr, y->length + 1); x->length = y->length;} voidStrcopy_charp(Str x, const char *y){ int len; STR_LENGTH_CHECK(x); if (y == NULL) { x->length = 0; x->ptr[0] = '\0'; return; } len = strlen(y); if (len < 0 || len >= STR_SIZE_MAX) len = STR_SIZE_MAX - 1; if (x->area_size < len + 1) { x->ptr = GC_REALLOC(x->ptr, len + 1); if (x->ptr == NULL) exit(1); x->area_size = len + 1; } bcopy((void *)y, (void *)x->ptr, len); x->ptr[len] = '\0'; x->length = len;} voidStrcopy_charp_n(Str x, const char *y, int n){ int len = n; STR_LENGTH_CHECK(x); if (y == NULL) { x->length = 0; x->ptr[0] = '\0'; return; } if (len < 0 || len >= STR_SIZE_MAX) len = STR_SIZE_MAX - 1; if (x->area_size < len + 1) { x->ptr = GC_REALLOC(x->ptr, len + 1); if (x->ptr == NULL) exit(1); x->area_size = len + 1; } bcopy((void *)y, (void *)x->ptr, len); x->ptr[len] = '\0'; x->length = len;} voidStrcat_charp_n(Str x, const char *y, int n){ int newlen; STR_LENGTH_CHECK(x); if (y == NULL || n == 0) return; if (n < 0) n = STR_SIZE_MAX - 1; newlen = x->length + n + 1; if (newlen <= 0 || newlen > STR_SIZE_MAX) { newlen = STR_SIZE_MAX; n = newlen - x->length - 1; if (n <= 0) return; } if (x->area_size < newlen) { newlen += newlen / 2; if (newlen <= 0 || newlen > STR_SIZE_MAX) newlen = STR_SIZE_MAX; x->ptr = GC_REALLOC(x->ptr, newlen); if (x->ptr == NULL) exit(1); x->area_size = newlen; } bcopy((void *)y, (void *)&x->ptr[x->length], n); x->length += n; x->ptr[x->length] = '\0';} voidStrcat(Str x, Str y){ STR_LENGTH_CHECK(y); Strcat_charp_n(x, y->ptr, y->length);} voidStrcat_charp(Str x, const char *y){ if (y == NULL) return; Strcat_charp_n(x, y, strlen(y));} voidStrcat_m_charp(Str x, ...){ va_list ap; char *p; va_start(ap, x); while ((p = va_arg(ap, char *)) != NULL) Strcat_charp_n(x, p, strlen(p)); va_end(ap);} voidStrgrow(Str x){ int newlen, addlen; if (x->area_size < 8192) addlen = x->area_size; else addlen = x->area_size / 2; if (addlen < INITIAL_STR_SIZE) addlen = INITIAL_STR_SIZE; newlen = x->area_size + addlen; if (newlen <= 0 || newlen > STR_SIZE_MAX) { newlen = STR_SIZE_MAX; if (x->length + 1 >= newlen) x->length = newlen - 2; } if (x->area_size < newlen) { x->ptr = GC_REALLOC(x->ptr, newlen); if (x->ptr == NULL) exit(1); x->area_size = newlen; } x->ptr[x->length] = '\0';} StrStrsubstr(Str s, int beg, int len){ Str new_s; int i; STR_LENGTH_CHECK(s); new_s = Strnew(); if (beg >= s->length) return new_s; for (i = 0; i < len && beg + i < s->length; i++) Strcat_char(new_s, s->ptr[beg + i]); return new_s;} voidStrlower(Str s){ int i; STR_LENGTH_CHECK(s); for (i = 0; i < s->length; i++) s->ptr[i] = TOLOWER(s->ptr[i]);} voidStrupper(Str s){ int i; STR_LENGTH_CHECK(s); for (i = 0; i < s->length; i++) s->ptr[i] = TOUPPER(s->ptr[i]);} voidStrchop(Str s){ STR_LENGTH_CHECK(s); while (s->length > 0 && (s->ptr[s->length - 1] == '\n' || s->ptr[s->length - 1] == '\r')) { s->length--; } s->ptr[s->length] = '\0';} voidStrinsert_char(Str s, int pos, char c){ int i; STR_LENGTH_CHECK(s); if (pos < 0 || s->length < pos) return; if (s->length + 2 > s->area_size) Strgrow(s); if (s->length < pos) return; for (i = s->length; i > pos; i--) s->ptr[i] = s->ptr[i - 1]; s->ptr[++s->length] = '\0'; s->ptr[pos] = c;} voidStrinsert_charp(Str s, int pos, const char *p){ STR_LENGTH_CHECK(s); while (*p) Strinsert_char(s, pos++, *(p++));} voidStrdelete(Str s, int pos, int n){ int i; STR_LENGTH_CHECK(s); if (pos < 0 || s->length < pos) return; if (n < 0) n = STR_SIZE_MAX - pos - 1; if (s->length <= pos + n) { s->ptr[pos] = '\0'; s->length = pos; return; } for (i = pos; i < s->length - n; i++) s->ptr[i] = s->ptr[i + n]; s->ptr[i] = '\0'; s->length = i;} voidStrtruncate(Str s, int pos){ STR_LENGTH_CHECK(s); if (pos < 0 || s->length < pos) return; s->ptr[pos] = '\0'; s->length = pos;} voidStrshrink(Str s, int n){ STR_LENGTH_CHECK(s); if (n >= s->length) { s->length = 0; s->ptr[0] = '\0'; } else if (n > 0) { s->length -= n; s->ptr[s->length] = '\0'; }} voidStrremovefirstspaces(Str s){ int i; STR_LENGTH_CHECK(s); for (i = 0; i < s->length && IS_SPACE(s->ptr[i]); i++) ; if (i == 0) return; Strdelete(s, 0, i);} voidStrremovetrailingspaces(Str s){ int i; STR_LENGTH_CHECK(s); for (i = s->length - 1; i >= 0 && IS_SPACE(s->ptr[i]); i--) ; s->length = i + 1; s->ptr[i + 1] = '\0';} StrStralign_left(Str s, int width){ Str n; int i; STR_LENGTH_CHECK(s); if (s->length >= width) return Strdup(s); n = Strnew_size(width); Strcopy(n, s); for (i = s->length; i < width; i++) Strcat_char(n, ' '); return n;} StrStralign_right(Str s, int width){ Str n; int i; STR_LENGTH_CHECK(s); if (s->length >= width) return Strdup(s); n = Strnew_size(width); for (i = s->length; i < width; i++) Strcat_char(n, ' '); Strcat(n, s); return n;} StrStralign_center(Str s, int width){ Str n; int i, w; STR_LENGTH_CHECK(s); if (s->length >= width) return Strdup(s); n = Strnew_size(width); w = (width - s->length) / 2; for (i = 0; i < w; i++) Strcat_char(n, ' '); Strcat(n, s); for (i = w + s->length; i < width; i++) Strcat_char(n, ' '); return n;} #define SP_NORMAL 0#define SP_PREC 1#define SP_PREC2 2 StrLines 1–500 of 622. Load more
/* $Id: Str.c,v 1.8 2002/12/24 17:20:46 ukai Exp $ */ /* * String manipulation library for Boehm GC * * (C) Copyright 1998-1999 by Akinori Ito * * This software may be redistributed freely for this purpose, in full * or in part, provided that this entire copyright notice is included * on any copies of this software and applications and derivations thereof. * * This software is provided on an "as is" basis, without warranty of any * kind, either expressed or implied, as to any matter including, but not * limited to warranty of fitness of purpose, or merchantability, or * results obtained from use of this software. */ #include <stdio.h> #include <stdlib.h> #include <gc.h> #include <stdarg.h> #include <string.h> #ifdef __EMX__ /* or include "fm.h" for HAVE_BCOPY? */ #include <strings.h> #endif #include "Str.h" #include "myctype.h" #define INITIAL_STR_SIZE 32 #ifdef STR_DEBUG /* This is obsolete, because "Str" can handle a '\0' character now. */ #define STR_LENGTH_CHECK(x) if (((x)->ptr==0&&(x)->length!=0)||(strlen((x)->ptr)!=(x)->length))abort(); #else /* not STR_DEBUG */ #define STR_LENGTH_CHECK(x) #endif /* not STR_DEBUG */ Str Strnew() { Str x = GC_MALLOC(sizeof(struct _Str)); if (x == NULL) exit(1); x->ptr = GC_MALLOC_ATOMIC(INITIAL_STR_SIZE); if (x->ptr == NULL) exit(1); x->ptr[0] = '\0'; x->area_size = INITIAL_STR_SIZE; x->length = 0; return x; } Str Strnew_size(int n) { Str x = GC_MALLOC(sizeof(struct _Str)); if (x == NULL) exit(1); if (n < 0 || n >= STR_SIZE_MAX) n = STR_SIZE_MAX - 1; else if (n + 1 < INITIAL_STR_SIZE) n = INITIAL_STR_SIZE - 1; x->ptr = GC_MALLOC_ATOMIC(n + 1); if (x->ptr == NULL) exit(1); x->ptr[0] = '\0'; x->area_size = n + 1; x->length = 0; return x; } Str Strnew_charp(const char *p) { Str x; int n, len; if (p == NULL) return Strnew(); x = GC_MALLOC(sizeof(struct _Str)); if (x == NULL) exit(1); n = strlen(p) + 1; if (n <= 0 || n > STR_SIZE_MAX) n = STR_SIZE_MAX; len = n - 1; if (n < INITIAL_STR_SIZE) n = INITIAL_STR_SIZE; x->ptr = GC_MALLOC_ATOMIC(n); if (x->ptr == NULL) exit(1); x->area_size = n; x->length = len; bcopy((void *)p, (void *)x->ptr, len); x->ptr[x->length] = '\0'; return x; } Str Strnew_m_charp(const char *p, ...) { va_list ap; Str r = Strnew(); va_start(ap, p); while (p != NULL) { Strcat_charp(r, p); p = va_arg(ap, char *); } va_end(ap); return r; } Str Strnew_charp_n(const char *p, int n) { Str x; int len; if (p == NULL) return Strnew_size(n); x = GC_MALLOC(sizeof(struct _Str)); if (x == NULL) exit(1); if (n < 0 || n >= STR_SIZE_MAX) n = STR_SIZE_MAX - 1; len = n; if (n + 1 < INITIAL_STR_SIZE) n = INITIAL_STR_SIZE - 1; x->ptr = GC_MALLOC_ATOMIC(n + 1); if (x->ptr == NULL) exit(1); x->area_size = n + 1; x->length = len; bcopy((void *)p, (void *)x->ptr, len); x->ptr[x->length] = '\0'; return x; } Str Strdup(Str s) { Str n = Strnew_size(s->length); STR_LENGTH_CHECK(s); Strcopy(n, s); return n; } void Strclear(Str s) { s->length = 0; s->ptr[0] = '\0'; } void Strfree(Str x) { GC_free(x->ptr); GC_free(x); } void Strcopy(Str x, Str y) { STR_LENGTH_CHECK(x); STR_LENGTH_CHECK(y); if (x->area_size < y->length + 1) { x->ptr = GC_REALLOC(x->ptr, y->length + 1); if (x->ptr == NULL) exit(1); x->area_size = y->length + 1; } bcopy((void *)y->ptr, (void *)x->ptr, y->length + 1); x->length = y->length; } void Strcopy_charp(Str x, const char *y) { int len; STR_LENGTH_CHECK(x); if (y == NULL) { x->length = 0; x->ptr[0] = '\0'; return; } len = strlen(y); if (len < 0 || len >= STR_SIZE_MAX) len = STR_SIZE_MAX - 1; if (x->area_size < len + 1) { x->ptr = GC_REALLOC(x->ptr, len + 1); if (x->ptr == NULL) exit(1); x->area_size = len + 1; } bcopy((void *)y, (void *)x->ptr, len); x->ptr[len] = '\0'; x->length = len; } void Strcopy_charp_n(Str x, const char *y, int n) { int len = n; STR_LENGTH_CHECK(x); if (y == NULL) { x->length = 0; x->ptr[0] = '\0'; return; } if (len < 0 || len >= STR_SIZE_MAX) len = STR_SIZE_MAX - 1; if (x->area_size < len + 1) { x->ptr = GC_REALLOC(x->ptr, len + 1); if (x->ptr == NULL) exit(1); x->area_size = len + 1; } bcopy((void *)y, (void *)x->ptr, len); x->ptr[len] = '\0'; x->length = len; } void Strcat_charp_n(Str x, const char *y, int n) { int newlen; STR_LENGTH_CHECK(x); if (y == NULL || n == 0) return; if (n < 0) n = STR_SIZE_MAX - 1; newlen = x->length + n + 1; if (newlen <= 0 || newlen > STR_SIZE_MAX) { newlen = STR_SIZE_MAX; n = newlen - x->length - 1; if (n <= 0) return; } if (x->area_size < newlen) { newlen += newlen / 2; if (newlen <= 0 || newlen > STR_SIZE_MAX) newlen = STR_SIZE_MAX; x->ptr = GC_REALLOC(x->ptr, newlen); if (x->ptr == NULL) exit(1); x->area_size = newlen; } bcopy((void *)y, (void *)&x->ptr[x->length], n); x->length += n; x->ptr[x->length] = '\0'; } void Strcat(Str x, Str y) { STR_LENGTH_CHECK(y); Strcat_charp_n(x, y->ptr, y->length); } void Strcat_charp(Str x, const char *y) { if (y == NULL) return; Strcat_charp_n(x, y, strlen(y)); } void Strcat_m_charp(Str x, ...) { va_list ap; char *p; va_start(ap, x); while ((p = va_arg(ap, char *)) != NULL) Strcat_charp_n(x, p, strlen(p)); va_end(ap); } void Strgrow(Str x) { int newlen, addlen; if (x->area_size < 8192) addlen = x->area_size; else addlen = x->area_size / 2; if (addlen < INITIAL_STR_SIZE) addlen = INITIAL_STR_SIZE; newlen = x->area_size + addlen; if (newlen <= 0 || newlen > STR_SIZE_MAX) { newlen = STR_SIZE_MAX; if (x->length + 1 >= newlen) x->length = newlen - 2; } if (x->area_size < newlen) { x->ptr = GC_REALLOC(x->ptr, newlen); if (x->ptr == NULL) exit(1); x->area_size = newlen; } x->ptr[x->length] = '\0'; } Str Strsubstr(Str s, int beg, int len) { Str new_s; int i; STR_LENGTH_CHECK(s); new_s = Strnew(); if (beg >= s->length) return new_s; for (i = 0; i < len && beg + i < s->length; i++) Strcat_char(new_s, s->ptr[beg + i]); return new_s; } void Strlower(Str s) { int i; STR_LENGTH_CHECK(s); for (i = 0; i < s->length; i++) s->ptr[i] = TOLOWER(s->ptr[i]); } void Strupper(Str s) { int i; STR_LENGTH_CHECK(s); for (i = 0; i < s->length; i++) s->ptr[i] = TOUPPER(s->ptr[i]); } void Strchop(Str s) { STR_LENGTH_CHECK(s); while (s->length > 0 && (s->ptr[s->length - 1] == '\n' || s->ptr[s->length - 1] == '\r')) { s->length--; } s->ptr[s->length] = '\0'; } void Strinsert_char(Str s, int pos, char c) { int i; STR_LENGTH_CHECK(s); if (pos < 0 || s->length < pos) return; if (s->length + 2 > s->area_size) Strgrow(s); if (s->length < pos) return; for (i = s->length; i > pos; i--) s->ptr[i] = s->ptr[i - 1]; s->ptr[++s->length] = '\0'; s->ptr[pos] = c; } void Strinsert_charp(Str s, int pos, const char *p) { STR_LENGTH_CHECK(s); while (*p) Strinsert_char(s, pos++, *(p++)); } void Strdelete(Str s, int pos, int n) { int i; STR_LENGTH_CHECK(s); if (pos < 0 || s->length < pos) return; if (n < 0) n = STR_SIZE_MAX - pos - 1; if (s->length <= pos + n) { s->ptr[pos] = '\0'; s->length = pos; return; } for (i = pos; i < s->length - n; i++) s->ptr[i] = s->ptr[i + n]; s->ptr[i] = '\0'; s->length = i; } void Strtruncate(Str s, int pos) { STR_LENGTH_CHECK(s); if (pos < 0 || s->length < pos) return; s->ptr[pos] = '\0'; s->length = pos; } void Strshrink(Str s, int n) { STR_LENGTH_CHECK(s); if (n >= s->length) { s->length = 0; s->ptr[0] = '\0'; } else if (n > 0) { s->length -= n; s->ptr[s->length] = '\0'; } } void Strremovefirstspaces(Str s) { int i; STR_LENGTH_CHECK(s); for (i = 0; i < s->length && IS_SPACE(s->ptr[i]); i++) ; if (i == 0) return; Strdelete(s, 0, i); } void Strremovetrailingspaces(Str s) { int i; STR_LENGTH_CHECK(s); for (i = s->length - 1; i >= 0 && IS_SPACE(s->ptr[i]); i--) ; s->length = i + 1; s->ptr[i + 1] = '\0'; } Str Stralign_left(Str s, int width) { Str n; int i; STR_LENGTH_CHECK(s); if (s->length >= width) return Strdup(s); n = Strnew_size(width); Strcopy(n, s); for (i = s->length; i < width; i++) Strcat_char(n, ' '); return n; } Str Stralign_right(Str s, int width) { Str n; int i; STR_LENGTH_CHECK(s); if (s->length >= width) return Strdup(s); n = Strnew_size(width); for (i = s->length; i < width; i++) Strcat_char(n, ' '); Strcat(n, s); return n; } Str Stralign_center(Str s, int width) { Str n; int i, w; STR_LENGTH_CHECK(s); if (s->length >= width) return Strdup(s); n = Strnew_size(width); w = (width - s->length) / 2; for (i = 0; i < w; i++) Strcat_char(n, ' '); Strcat(n, s); for (i = w + s->length; i < width; i++) Strcat_char(n, ' '); return n; } #define SP_NORMAL 0 #define SP_PREC 1 #define SP_PREC2 2 Str