tlang-c/libtlang/src/string.c

380 lines
8.2 KiB
C

#include "tlang.h"
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <errno.h>
void string_free(string_t* s)
{
free(s->text);
free(s);
}
string_t* string_create()
{
string_t* s2 = (string_t*)malloc(sizeof(string_t));
s2->capacity = 128;
s2->length = 0;
s2->text = (char*)malloc(sizeof(char)* s2->capacity);
return s2;
}
bool string_islong(string_t* s,int64_t* number)
{
//https://wiki.sei.cmu.edu/confluence/display/c/ERR34-C.+Detect+errors+when+converting+a+string+to+a+number
char* _s = string_dupp(s);
char *end;
int si;
bool res=false;
errno = 0;
*number = strtoll(_s, &end,0);
if (end == _s) {
res = false;
} else if ('\0' != *end) {
res=false;
} else if ( ERANGE == errno) {
res=false;
} else {
res = true;
/* Process si */
}
free(_s);
return res;
}
bool string_isnumber(string_t* s,double* number)
{
//https://wiki.sei.cmu.edu/confluence/display/c/ERR34-C.+Detect+errors+when+converting+a+string+to+a+number
char* _s = string_dupp(s);
char *end;
int si;
bool res=false;
errno = 0;
*number = strtod(_s, &end);
if (end == _s) {
res = false;
} else if ('\0' != *end) {
res=false;
} else if ( ERANGE == errno) {
res=false;
} else {
res = true;
/* Process si */
}
free(_s);
return res;
}
void string_ensure(string_t* a)
{
if(a->length + 1 > a->capacity)
{
a->capacity = a->length + 128;
a->text=(char*)realloc(a->text,a->capacity);
}
}
void string_appendp(string_t* a,const char* str)
{
size_t len = strlen(str);
int _len = a->length;
a->length = _len+ (int)len;
string_ensure(a);
memcpy(a->text+_len,str,len);
}
void string_appendc(string_t* a,char c)
{
char str[2];
str[0] = c;
str[1] = 0;
string_appendp(a,str);
}
void string_appendn(string_t* s,double val)
{
char txt[1000];
//snprintf(txt,len,"%f",val);
int64_t bigNo = (int64_t)val;
val -= bigNo;
uint64_t littleNo = (uint64_t)(val * 100000000000.0);
while(littleNo % 10 == 0 && littleNo != 0)
{
littleNo /= 10;
}
snprintf(txt,1000,"%" PRId64 "", bigNo);
string_appendp(s,txt);
if(littleNo > 0)
{
snprintf(txt,1000,".%" PRIu64 "", littleNo);
string_appendp(s,txt);
}
}
void string_clear(string_t* s)
{
s->length=0;
}
char* string_dupp(string_t* s)
{
char* text = (char*)malloc(sizeof(char) * (s->length + 1));
memcpy(text,s->text,s->length);
text[s->length] = 0;
return text;
}
string_t* string_dups(string_t* s)
{
string_t* s2 = (string_t*)malloc(sizeof(string_t));
s2->capacity = s->length + 128;
s2->length = s->length;
s2->text = (char*)malloc(sizeof(char)* s2->capacity);
memcpy(s2->text,s->text,s->length);
return s2;
}
void string_appends(string_t* a,string_t* b)
{
int _len = a->length;
a->length = _len+ b->length;
string_ensure(a);
memcpy(a->text+_len,b->text,b->length);
}
const char* string_trimstart(const char* ptr,char c)
{
while(*ptr != '\0')
{
if(*ptr != c) break;
ptr++;
}
return ptr;
}
string_t* string_substring(string_t* s,int start,int length)
{
if(s->length - start < length)
{
length = s->length - start;
}
if(length < 0) length = 0;
string_t* dest = string_create();
if(length == 0) return dest;
dest->length = length;
string_ensure(dest);
memcpy(dest->text,s->text + start,length);
return dest;
}
string_t* string_remove(string_t* s,int start,int length)
{
string_t* dest = string_create();
int after = start + length;
if(start > 0)
{
string_t* dest1=string_substring(s,0,start);
string_appends(dest,dest1);
string_free(dest1);
}
if(after < s->length - 1)
{
string_t* dest1=string_substring(s,after,s->length-after);
string_appends(dest,dest1);
string_free(dest1);
}
return dest;
}
string_t* string_trimstarts(string_t* s,char c)
{
int i = 0;
while(i<s->length)
{
if(s->text[i] != c) break;
i++;
}
string_t* s2=string_create();
int _len = s->length-i;
s2->length = _len;
string_ensure(s2);
memcpy(s2->text,s->text+i,_len);
return s2;
}
int string_lastindexof(string_t* s,char c)
{
int i;
for(i=s->length-1;i>=0;i--)
{
if(s->text[i] == c) return i;
}
return i;
}
int string_indexof(string_t* s,char c)
{
int i=0;
for(i=0;i<s->length;i++)
{
if(s->text[i] == c) return i;
}
return -1;
}
string_t* string_trimends(string_t* s,char c)
{
int i = s->length-1;
while(i>=0)
{
if(s->text[i] != c) break;
i--;
}
i++;
if(i < 0) i=0;
string_t* s2=string_create();
s2->length =i;
string_ensure(s2);
memcpy(s2->text,s->text,s2->length);
return s2;
}
void string_read(string_t* str,void* ptr,size_t(*_cb)(void*,size_t,size_t,void*))
{
char buffer[1024];
size_t read=0;
do{
read = _cb(buffer,1,1024,ptr);
if(read > 0){
int _len = str->length;
str->length = _len+ (int)read;
string_ensure(str);
memcpy(str->text+_len,buffer,read);
}
}while(read > 0);
}
bool string_samep(string_t* s,const char* text)
{
size_t len = strlen(text);
if(s->length != len)
{
return false;
}
return memcmp(s->text,text,len) == 0;
}
bool string_sames(string_t* s,string_t* b)
{
int len = b->length;
if(s->length != b->length)
{
return false;
}
return memcmp(s->text,b->text,(size_t)len) == 0;
}
bool string_is_del(string_t* text,int i,string_t* del)
{
if(text->length - i < del->length) return false;
int j;
for(j = 0;j<del->length;j++)
{
if(text->text[j+i] != del->text[j]) return false;
}
return true;
}
tobject_t* string_split(runtime_t* rt,string_t* text,string_t* del,int max,bool empty)
{
if(max == 0)
{
max = 2147483647;
}
int j = 0;
int i;
tobject_t* o = tobject_create_array(rt,0);
string_t* b=string_create();
for(i=0;i<text->length;i++)
{
if(string_is_del(text,i,del) && j < max - 1)
{
i += del->length;
j++;
if(b->length > 0 || empty)
list_add(&o->data.list,tobject_string(rt,string_dups(b)));
string_clear(b);
}
if(i<text->length)
string_appendc(b,text->text[i]);
}
if(b->length > 0 || empty)
list_add(&o->data.list,tobject_string(rt,string_dups(b)));
string_free(b);
return o;
/* List<string> p = new List<string>();
StringBuilder b= new StringBuilder();
for(int i = 0;i<text.Length;i++)
{
if(IsDelimiter(text,i,delimiter) && j < c - 1)
{
i += delimiter.Length;
j++;
if(b.Length > 0 || empty)
p.Add(b.ToString());
b.Clear();
}
b.Append(text[i]);
}
if(b.Length > 0 || empty)
p.Add(b.ToString());
return p.ToArray();
*/
}
bool string_startswith(string_t* haystack,string_t* needle)
{
int len = needle->length;
if(haystack->length < len) return false;
int i;
for(i = 0;i < len;i++)
{
if(needle->text[i] != haystack->text[i]) return false;
}
return true;
}
bool string_endswith(string_t* haystack,string_t* needle)
{
int len = needle->length;
if(haystack->length < len) return false;
int i;
for(i = 0;i < needle->length;i++)
{
if(needle->text[i] != haystack->text[haystack->length-needle->length+i]) return false;
}
return true;
}
string_t* string_replace(string_t* text,string_t* old,string_t* new)
{
int j = 0;
int i;
string_t* b=string_create();
for(i=0;i<text->length;i++)
{
if(string_is_del(text,i,old))
{
i += old->length;
j++;
string_appends(b,new);
}
if(i<text->length)
string_appendc(b,text->text[i]);
}
return b;
}