diff options
Diffstat (limited to 'apps/interpreters/bas/str.c')
-rw-r--r-- | apps/interpreters/bas/str.c | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/apps/interpreters/bas/str.c b/apps/interpreters/bas/str.c new file mode 100644 index 000000000..1491d80d8 --- /dev/null +++ b/apps/interpreters/bas/str.c @@ -0,0 +1,261 @@ +/* Dyanamic strings. */ +/* #includes */ /*{{{C}}}*//*{{{*/ +#include "config.h" + +#include <assert.h> +#include <ctype.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "str.h" + +#ifdef USE_DMALLOC +#include "dmalloc.h" +#endif +/*}}}*/ + +int cistrcmp(const char *s, const char *r) /*{{{*/ +{ + assert(s!=(char*)0); + assert(r!=(char*)0); + while (*s && tolower(*s)==tolower(*r)) { ++s; ++r; }; + return ((tolower(*s)-tolower(*r))); +} +/*}}}*/ + +struct String *String_new(struct String *this) /*{{{*/ +{ + assert(this!=(struct String*)0); + this->length=0; + this->character=(char*)0; + this->field=(struct StringField*)0; + return this; +} +/*}}}*/ +void String_destroy(struct String *this) /*{{{*/ +{ + assert(this!=(struct String*)0); + if (this->field) String_leaveField(this); + if (this->length) free(this->character); +} +/*}}}*/ +int String_joinField(struct String *this, struct StringField *field, char *character, size_t length) /*{{{*/ +{ + struct String **n; + + assert(this!=(struct String*)0); + if (this->field) String_leaveField(this); + this->field=field; + if ((n=(struct String**)realloc(field->refStrings,sizeof(struct String*)*(field->refCount+1)))==(struct String**)0) return -1; + field->refStrings=n; + field->refStrings[field->refCount]=this; + ++field->refCount; + if (this->length) free(this->character); + this->character=character; + this->length=length; + return 0; +} +/*}}}*/ +void String_leaveField(struct String *this) /*{{{*/ +{ + struct StringField *field; + int i; + struct String **ref; + + assert(this!=(struct String*)0); + field=this->field; + assert(field!=(struct StringField*)0); + for (i=0,ref=field->refStrings; i<field->refCount; ++i,++ref) + { + if (*ref==this) + { + int further=--field->refCount-i; + + if (further) memmove(ref,ref+1,further*sizeof(struct String**)); + this->character=(char*)0; + this->length=0; + this->field=(struct StringField*)0; + return; + } + } + assert(0); +} +/*}}}*/ +struct String *String_clone(struct String *this, const struct String *original) /*{{{*/ +{ + assert(this!=(struct String*)0); + String_new(this); + String_appendString(this,original); + return this; +} +/*}}}*/ +int String_size(struct String *this, size_t length) /*{{{*/ +{ + char *n; + + assert(this!=(struct String*)0); + if (this->field) String_leaveField(this); + if (length) + { + if (length>this->length) + { + if ((n=realloc(this->character,length+1))==(char*)0) return -1; + this->character=n; + } + this->character[length]='\0'; + } + else + { + if (this->length) free(this->character); + this->character=(char*)0; + } + this->length=length; + return 0; +} +/*}}}*/ +int String_appendString(struct String *this, const struct String *app) /*{{{*/ +{ + size_t oldlength=this->length; + + if (this->field) String_leaveField(this); + if (app->length==0) return 0; + if (String_size(this,this->length+app->length)==-1) return -1; + memcpy(this->character+oldlength,app->character,app->length); + return 0; +} +/*}}}*/ +int String_appendChar(struct String *this, char ch) /*{{{*/ +{ + size_t oldlength=this->length; + + if (this->field) String_leaveField(this); + if (String_size(this,this->length+1)==-1) return -1; + this->character[oldlength]=ch; + return 0; +} +/*}}}*/ +int String_appendChars(struct String *this, const char *ch) /*{{{*/ +{ + size_t oldlength=this->length; + size_t chlen=strlen(ch); + + if (this->field) String_leaveField(this); + if (String_size(this,this->length+chlen)==-1) return -1; + memcpy(this->character+oldlength,ch,chlen); + return 0; +} +/*}}}*/ +int String_appendPrintf(struct String *this, const char *fmt, ...) /*{{{*/ +{ + char buf[1024]; + size_t l,j; + va_list ap; + + if (this->field) String_leaveField(this); + va_start(ap, fmt); + l=vsprintf(buf,fmt,ap); + va_end(ap); + j=this->length; + if (String_size(this,j+l)==-1) return -1; + memcpy(this->character+j,buf,l); + return 0; +} +/*}}}*/ +int String_insertChar(struct String *this, size_t where, char ch) /*{{{*/ +{ + size_t oldlength=this->length; + + if (this->field) String_leaveField(this); + assert(where<oldlength); + if (String_size(this,this->length+1)==-1) return -1; + memmove(this->character+where+1,this->character+where,oldlength-where); + this->character[where]=ch; + return 0; +} +/*}}}*/ +int String_delete(struct String *this, size_t where, size_t len) /*{{{*/ +{ + size_t oldlength=this->length; + + if (this->field) String_leaveField(this); + assert(where<oldlength); + assert(len>0); + if ((where+len)<oldlength) memmove(this->character+where,this->character+where+len,oldlength-where-len); + this->character[this->length-=len]='\0'; + return 0; +} +/*}}}*/ +void String_ucase(struct String *this) /*{{{*/ +{ + size_t i; + + for (i=0; i<this->length; ++i) this->character[i]=toupper(this->character[i]); +} +/*}}}*/ +void String_lcase(struct String *this) /*{{{*/ +{ + size_t i; + + for (i=0; i<this->length; ++i) this->character[i]=tolower(this->character[i]); +} +/*}}}*/ +int String_cmp(const struct String *this, const struct String *s) /*{{{*/ +{ + size_t pos; + int res; + const char *thisch,*sch; + + for (pos=0,thisch=this->character,sch=s->character; pos<this->length && pos<s->length; ++pos,++thisch,++sch) + { + if ((res=(*thisch-*sch))) return res; + } + return (this->length-s->length); +} +/*}}}*/ +void String_lset(struct String *this, const struct String *s) /*{{{*/ +{ + size_t copy; + + copy=(this->length<s->length ? this->length : s->length); + if (copy) memcpy(this->character,s->character,copy); + if (copy<this->length) memset(this->character+copy,' ',this->length-copy); +} +/*}}}*/ +void String_rset(struct String *this, const struct String *s) /*{{{*/ +{ + size_t copy; + + copy=(this->length<s->length ? this->length : s->length); + if (copy) memcpy(this->character+this->length-copy,s->character,copy); + if (copy<this->length) memset(this->character,' ',this->length-copy); +} +/*}}}*/ +void String_set(struct String *this, size_t pos, const struct String *s, size_t length) /*{{{*/ +{ + if (this->length>=pos) + { + if (this->length<(pos+length)) length=this->length-pos; + if (length) memcpy(this->character+pos,s->character,length); + } +} +/*}}}*/ + +struct StringField *StringField_new(struct StringField *this) /*{{{*/ +{ + this->refStrings=(struct String**)0; + this->refCount=0; + return this; +} +/*}}}*/ +void StringField_destroy(struct StringField *this) /*{{{*/ +{ + int i; + + for (i=this->refCount; i>0; ) String_leaveField(this->refStrings[--i]); + this->refCount=-1; + free(this->refStrings); +} +/*}}}*/ |