622 lines · 11.1 KB · C
RawDownload
/* $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 Str

Lines 1–500 of 622.