lr/str.c

264 lines
4.3 KiB
C

#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<stdbool.h>
#include<ctype.h>
#include"str.h"
Str str_new(void)
{
Str s={
.buffer=NULL,
.capacity=0,
.size=0,
};
return s;
}
void str_free(Str*s)
{
if(!s){if(STRVERBOSE)fprintf(stderr,"str_free: NULL Str*\n");return;}
if(s->capacity)
free(s->buffer);
s->capacity=0;
s->size=0;
s->buffer=NULL;
}
void str_grow(Str*s,size_t n)
{
if(!s){if(STRVERBOSE)fprintf(stderr,"str_grow: NULL Str*\n");return;}
if(!s->buffer)
{
s->buffer=malloc(n);
if(s->buffer)
s->buffer[0]=0;
}
else
s->buffer=realloc(s->buffer,s->capacity+n);
if(!s->buffer){if(STRVERBOSE)fprintf(stderr,"str_grow: buffer is NULL after allocation\n");return;}
s->capacity=n;
}
void str_assign(Str*s,char*c)
{
size_t n;
if(!s){if(STRVERBOSE)fprintf(stderr,"str:str_assign: NULL Str*\n");return;}
n=strlen(c)+1;
if(s->capacity<n)
str_grow(s,n+STRDEFSIZE);
strcpy(s->buffer,c);
s->size=n-1;
}
void str_print(Str*s)
{
printf("%p: (%lu/%lu) '%s'\n",s,s->size,s->capacity,s->buffer);
}
void str_append(Str*s,char*c)
{
size_t n;
if(!s){if(STRVERBOSE)fprintf(stderr,"str_append: NULL Str*\n");return;}
if(!c){if(STRVERBOSE)fprintf(stderr,"str_append: NULL char*\n");return;}
n=strlen(c)+1;
if(s->capacity<s->size+n)
str_grow(s,s->size+n+STRDEFSIZE);
if(!s->buffer){if(STRVERBOSE)fprintf(stderr,"str_append: buffer is NULL after str_grow\n");return;}
strcat(s->buffer,c);
s->size+=n-1;
}
void str_append_n(Str*s,char*c,size_t n)
{
if(!s){if(STRVERBOSE)fprintf(stderr,"str_append: NULL Str*\n");return;}
if(!c){if(STRVERBOSE)fprintf(stderr,"str_append: NULL char*\n");return;}
if(s->capacity<s->size+n)
str_grow(s,s->size+n+STRDEFSIZE);
if(!s->buffer){if(STRVERBOSE)fprintf(stderr,"str_append: buffer is NULL after str_grow\n");return;}
strncat(s->buffer,c,n);
s->size+=n-1;
s->buffer[s->size]=0;
}
void str_tr(Str*s,char a,char b)
{
if(!s){if(STRVERBOSE)fprintf(stderr,"str_tr: NULL Str*\n");return;}
for(size_t i=0;i<s->size;++i)
if(s->buffer[i]==a)
s->buffer[i]=b;
}
void str_clear(Str*s)
{
if(!s){if(STRVERBOSE)fprintf(stderr,"str_clear: NULL Str*\n");return;}
s->size=0;
if(s->buffer)
s->buffer[0]='\0';
}
Str str_newa(char*c)
{
Str n=str_new();
if(c)
str_assign(&n,c);
return n;
}
void str_randomize(Str*s)
{
size_t length=rand()%8+1;
bool vowell=false;
char*v="aeiou";
char*c="bcdfghjklmnpqrstvwxyz";
size_t i=0;
str_assign(s,"........\0");
for(;i<length;++i)
{
s->buffer[i]=(vowell)?(v[rand()%5]):(c[rand()%21]);
vowell=!vowell;
}
s->buffer[i]='\0';
}
int search(int*a,int n,int v)
{
int b=0,e=n-1,m=(e-b)/2;
do
{
if(a[m]==v)
return m;
if(a[m]<v)
{
if(e==b){m=-1;break;}
else b=m+1,m=(e-b)/2+b;
}
else if(a[m]>v)
{
if(e==b){m=-1;break;}
else e=m-1,m=(e-b)/2+b;
}
}while(true);
return m;
}
// Binary search of array of char pointers
int cstr_search(char**a,int n,char*v)
{
int b=0,e=n-1,m=(e-b)/2;
do
{
if(strcmp(a[m],v)==0)
return m;
if(strcmp(a[m],v)<0)
{
if(e<=b){m=-1;break;}
else b=m+1,m=(e-b)/2+b;
}
else if(strcmp(a[m],v)>0)
{
if(e<=b){m=-1;break;}
else e=m-1,m=(e-b)/2+b;
}
}while(true);
return -1;
}
// Sort array of char pointers
void cstr_sort(char**a,size_t n)
{
char*t;
for(size_t i=0;i<n-1;++i)
for(size_t j=i+1;j<n;++j)
if(strcmp(a[i],a[j])>0)
t=a[i],
a[i]=a[j],
a[j]=t;
}
Str str_basename(char*c)
{
Str s=str_new();
char*p=NULL,*t=NULL;
if(!c){if(STRVERBOSE)fprintf(stderr,"str_basename: NULL char*\n");return s;};
str_assign(&s,c);
if(!s.buffer){if(STRVERBOSE)fprintf(stderr,"str_basename: buffer NULL after str_assign\n");return s;}
p=s.buffer;
t=p;
do
{
p=t;
t=strchr(p+1,'.');
}
while(t);
if(p)
*p='\0';
return s;
}
bool str_isnum(Str*s)
{
if(!s)return false;
for(size_t i=0;i<s->size;++i)
if(!isdigit(s->buffer[i]))
return false;
return true;
}
bool str_isint(char*s)
{
if(!s)return false;
if(!s[0])return false;
for(size_t i=0;s[i];++i)
if(!isdigit(s[i]))
return false;
return true;
}
bool str_isfloat(char*s)
{
uint32_t dotcount=0;
if(!s)return false;
if(!isdigit(s[0]))
return false;
for(size_t i=0;s[i];++i)
{
if(s[i]=='.')
{
if(dotcount++>0)
return false;
}
else if(!isdigit(s[i]))
return false;
}
return true;
}