/* $Id: str.c,v 1.10 2003/07/31 21:17:19 mastermind Exp $ */
/*
* Copyright (c) 1998-2003, Alexander Marx
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
*/
#define __easy_eSTR_C
#include "str.h"
/* --- Public Functions --------------------------------------------------- */
eSTR *va_newSTR(const char *s, ...)
{
va_list strs;
eSTR *str=NULL;
const char *t;
long len=0;
va_start(strs, s);
while(t=va_arg(strs, const char *)) {
len+=strlen(t);
}
va_end(strs);
if(str=malloc(sizeof(*str))) {
init(str);
if(str->str=malloc(strlen(s)+len+1)) {
strcpy(str->str, s);
va_start(strs, s);
while(t=va_arg(strs, const char *))
strcat(str->str, t);
va_end(strs);
str->len=strlen(s)+len;
} else {
free(str);
str=NULL;
}
}
return str;
}
eSTR *newSTR(const char *s)
{
eSTR *str=NULL;
if(str=malloc(sizeof(*str))) {
init(str);
if(s) {
if(str->str=malloc(strlen(s)+1)) {
strcpy(str->str, s);
str->len=strlen(s);
} else {
free(str);
str=NULL;
}
}
}
return str;
}
eSTR *clrSTR(eSTR *str)
{
if(str)
destroy(str);
return str;
}
eSTR *cpySTR(eSTR *dest_str, const eSTR *src_str)
{
eSTR tmp_str;
if(dest_str && src_str && (dest_str!=src_str)) {
if(copy(&tmp_str, src_str)) {
destroy(dest_str);
*dest_str=tmp_str;
return dest_str;
}
}
return NULL;
}
eSTR *dupSTR(const eSTR *src_str)
{
eSTR *str=NULL;
if(src_str) {
if(str=malloc(sizeof(*str))) {
if(!copy(str, src_str)) {
free(str);
str=NULL;
}
}
}
return str;
}
eSTR *setSTR(eSTR *str, const char *s)
{
char *t;
if(str) {
if(s) {
if(t=malloc(strlen(s)+1)) {
strcpy(t, s);
destroy(str);
str->str=t;
str->len=strlen(s);
} else
return NULL;
} else
destroy(str);
}
return str;
}
eSTR *spcSTR(unsigned long len)
{
eSTR *str=NULL;
if(len) {
if(str=malloc(sizeof(*str))) {
init(str);
if(str->str=malloc(len+1)) {
memset(str->str, ' ', len);
str->str[len]='\0';
str->len=len;
} else {
free(str);
str=NULL;
}
}
}
return str;
}
void freeSTR(eSTR *str)
{
if(str) {
destroy(str);
free(str);
}
}
char *strSTR(const eSTR *str)
{
return str ? str->str : NULL;
}
long lenSTR(const eSTR *str)
{
return str ? str->len : 0;
}
int putSTR(const eSTR *str, FILE *fh)
{
int rc=0;
if(fh && str && str->str)
rc=fprintf(fh, "%s", str->str);
return rc;
}
int putsSTR(const eSTR *str, FILE *fh)
{
int rc=0;
if(fh) {
if(str && str->str)
rc=fprintf(fh, "%s", str->str);
rc+=fprintf(fh, "\n");
}
return rc;
}
eSTR *getSTR(FILE *fh)
{
int c;
char *buffer=NULL;
eSTR *str=NULL;
long len=-1;
if(fh) {
if(feof(fh))
return NULL;
if(str=newSTR(NULL)) {
if(buffer=malloc(eSTR_BLOCK_SIZE)) {
buffer[eSTR_BLOCK_SIZE-1]='\0';
for(;;) {
c=fgetc(fh);
len++;
buffer[len]=(char)c;
if(c=='\0' || c==EOF) {
buffer[len]='\0';
if(catSTR(str, buffer))
break;
else {
freeSTR(str);
str=NULL;
break;
}
}
if(len==(eSTR_BLOCK_SIZE-2)) {
if(!catSTR(str, buffer)) {
freeSTR(str);
str=NULL;
break;
} else {
len=-1;
}
}
}
free(buffer);
} else {
freeSTR(str);
str=NULL;
}
}
}
return str;
}
eSTR *getlineSTR(FILE *fh)
{
int c;
char *buffer=NULL;
eSTR *str=NULL;
long len=-1;
if(fh) {
if(feof(fh))
return NULL;
if(str=newSTR(NULL)) {
if(buffer=malloc(eSTR_BLOCK_SIZE)) {
buffer[eSTR_BLOCK_SIZE-1]='\0';
for(;;) {
c=fgetc(fh);
len++;
buffer[len]=(char)c;
if(c=='\n' || c=='\r' || c=='\0' || c==EOF) {
if(c=='\r') {
if((c=fgetc(fh))!='\n')
ungetc(c, fh);
}
buffer[len]='\0';
if(catSTR(str, buffer))
break;
else {
freeSTR(str);
str=NULL;
break;
}
}
if(len==(eSTR_BLOCK_SIZE-2)) {
if(!catSTR(str, buffer)) {
freeSTR(str);
str=NULL;
break;
} else {
len=-1;
}
}
}
free(buffer);
} else {
freeSTR(str);
str=NULL;
}
}
}
return str;
}
char traverseSTR(eSTR *str, int move_to)
{
if(str) {
switch(move_to) {
case eSTR_HEAD:
str->idx=0;
break;
case eSTR_TAIL:
str->idx=str->len;
break;
case eSTR_FWD:
str->idx++;
break;
case eSTR_BWD:
str->idx--;
break;
}
}
return chrSTR(str);
}
char *adrSTR(const eSTR *str)
{
return str ? str->str ? str->str+str->idx : NULL : NULL;
}
long idxSTR(const eSTR *str)
{
return str ? str->idx : 0;
}
char chrSTR(eSTR *str)
{
char c='\0';
if(str) {
if(str->str) {
if(str->idx<0) {
c='\0';
str->idx=0;
} else if(str->idx>str->len) {
c='\0';
str->idx=str->len;
} else {
c=str->str[str->idx];
}
}
}
return c;
}
eSTR *upperSTR(eSTR *str)
{
char *t;
if(str && (t=str->str)) {
while(*t) {
if(islower((int)*t))
*t=toupper(*t);
t++;
}
}
return str;
}
eSTR *lowerSTR(eSTR *str)
{
char *t;
if(str && (t=str->str)) {
while(*t) {
if(isupper((int)*t))
*t=tolower(*t);
t++;
}
}
return str;
}
eSTR *reverseSTR(eSTR *str)
{
long n, m;
char c;
if(str && str->str) {
for(n=0, m=str->len-1; n<(str->len)/2; n++, m--) {
c=str->str[n];
str->str[n]=str->str[m];
str->str[m]=c;
}
}
return str;
}
eSTR *stripSTR(eSTR *str, int where, const char *s)
{
long m, n, i;
if(str && str->str && s) {
if(BTST(where, eSTR_LEAD) && str->len) {
for(i=0; strchr(s, str->str[i]); i++);
str->len-=i;
if(str->len<0)
str->len=0;
else
memmove(str->str, str->str+i, (unsigned int)str->len);
}
if(BTST(where, eSTR_TRAIL) && str->len) {
i=str->len-1;
if(i>=0) {
while(strchr(s, str->str[i]))
i--;
str->str[++i]='\0';
str->len=i;
}
}
if(BTST(where, eSTR_BODY) && str->len) {
if(str->len>0) {
for(i=0; strchr(s, str->str[i]); i++);
for(n=str->len-1; strchr(s, str->str[n]); n--);
for(m=i; str->str[i]; i++)
if((strchr(s, str->str[i])==NULL) || (i>n)) {
str->str[m]=str->str[i];
m++;
}
str->str[m]='\0';
str->len=m;
}
}
}
return str;
}
eSTR *catSTR(eSTR *dest_str, const char *s)
{
long len;
char *t;
if(dest_str) {
if(s) {
if(t=malloc(dest_str->len+strlen(s)+1)) {
if(dest_str->str)
strcpy(t, dest_str->str);
else
*t='\0';
strcat(t, s);
len=dest_str->len+strlen(s);
destroy(dest_str);
dest_str->str=t;
dest_str->len=len;
return dest_str;
}
} else
return dest_str;
}
return NULL;
}
eSTR *va_catSTR(eSTR *dest_str, ...)
{
va_list strs;
const char *s;
char *t;
size_t len=0;
if(!dest_str)
return NULL;
va_start(strs, dest_str);
while(s=va_arg(strs, const char *)) {
len+=strlen(s);
}
va_end(strs);
va_start(strs, dest_str);
if(t=malloc(dest_str->len+len+1)) {
if(dest_str->str)
strcpy(t, dest_str->str);
else
*t='\0';
while(s=va_arg(strs, const char *))
strcat(t, s);
len=dest_str->len+len;
destroy(dest_str);
dest_str->str=t;
dest_str->len=len;
return dest_str;
}
va_end(strs);
return NULL;
}
char *tokSTR(eSTR *str, const char *s)
{
if(str)
return strtok(str->str, s);
else
return strtok(NULL, s);
}
eSTR *catSTRs(eSTR *dest_str, const eSTR *src_str)
{
if(dest_str && src_str && catSTR(dest_str, src_str->str))
return dest_str;
else
return NULL;
}
eSTR *leftSTR(const eSTR *str, long idx)
{
eSTR *left=NULL;
if(str) {
if(idx>=str->len)
left=dupSTR(str);
else if(idx<=0)
left=newSTR(NULL);
else {
if(left=spcSTR((unsigned long)idx))
memcpy(left->str, str->str, (size_t) idx);
}
}
return left;
}
eSTR *rightSTR(const eSTR *str, long idx)
{
eSTR *right=NULL;
if(str) {
if(idx>=str->len)
right=newSTR(NULL);
else if(idx<0)
right=dupSTR(str);
else {
if(right=spcSTR((unsigned long)str->len-idx-1))
memcpy(right->str, str->str+idx+1, (size_t) str->len-idx-1);
}
}
return right;
}
eSTR *midSTR(const eSTR *str, long idx, long len)
{
eSTR *mid=NULL;
long start, end;
if(str) {
if(len<0)
mid=rightSTR(str, idx);
else {
end=idx+len+1;
if(end>str->len)
end=str->len;
start=idx;
if(start<0)
start=-1;
if(idx>=str->len)
mid=newSTR(NULL);
else if(mid=spcSTR((unsigned long)end-start-1)) {
memcpy(mid->str, str->str+start+1, (size_t) end-start-1);
}
}
}
return mid;
}
long subsSTR(const eSTR *haystack, const char *needle)
{
char *s;
long idx=-1;
if(haystack && needle && haystack->str) {
if(s=strstr(haystack->str, needle)) {
idx=s-haystack->str;
}
}
return idx;
}
long subcSTR(const eSTR *haystack, char needle)
{
char *s;
long idx=-1;
if(haystack && needle && haystack->str) {
if(s=strchr(haystack->str, needle)) {
idx=s-haystack->str;
}
}
return idx;
}
int cmpSTR(const eSTR *str, const char *s)
{
if(str && str->str) {
if(s)
return strcmp(str->str, s);
else
return 1;
} else if(s)
return -1;
else
return 0;
}
int cmpSTRs(const eSTR *s1, const eSTR *s2)
{
if(s1 && s1->str) {
if(s2 && s2->str)
return strcmp(s1->str, s2->str);
else
return 1;
} else if(s2 && s2->str)
return -1;
else
return 0;
}
BOOL verifySTR(const eSTR *str, const char *s)
{
BOOL rc=FALSE;
char *t;
if(str && str->str && s) {
t=str->str;
rc=TRUE;
while(*t && rc) {
if(strchr(s, *t)==NULL)
rc=FALSE;
t++;
}
}
return rc;
}
eSTR *infileSTR(const char *file) {
eSTR *str=NULL;
long size;
FILE *fh;
if(fh=fopen(file, "r")) {
if(str=newSTR(NULL)) {
fseek(fh, 0, SEEK_END);
size=ftell(fh);
rewind(fh);
if(str->str=malloc((unsigned long)size+1)) {
fread(str->str, (size_t) size, 1, fh);
str->str[size]='\0';
str->len=size;
} else {
freeSTR(str);
str=NULL;
}
}
fclose(fh);
}
return str;
}
int outfileSTR(const eSTR *str, const char *file) {
int rc=0;
FILE *fh;
if(str && file) {
if(fh=fopen(file, "w")) {
rc=fwrite(str->str, (size_t)str->len, 1, fh);
fclose(fh);
}
}
return rc;
}
int tounixSTR(eSTR *str) {
char *s;
int i=0;
if(str) {
char *ss;
for(i=0, s=str->str; *s; ss=++s, *(ss-i)=*s) {
if(*s=='\r') i++;
}
str->len=str->len-i;
*(str->str+str->len)='\0';
}
return i;
}
/* --- Private Functions -------------------------------------------------- */
static int copy(eSTR *dest_str, const eSTR *src_str)
{
int rc=FALSE;
if(dest_str->str=malloc((unsigned long) src_str->len+1)) {
memcpy(dest_str->str, src_str->str, (size_t) src_str->len+1);
dest_str->len=src_str->len;
dest_str->idx=src_str->idx;
rc=TRUE;
}
return rc;
}
static void destroy(eSTR *str)
{
if(str) {
if(str->str)
free(str->str);
init(str);
}
}
static void init(eSTR *str)
{
if(str) {
str->str=NULL;
str->len=str->idx=0;
}
}
syntax highlighted by Code2HTML, v. 0.9.1