276 lines
5.5 KiB
C
276 lines
5.5 KiB
C
|
/* This software is licensed by the MIT License, see LICENSE file */
|
||
|
/* Copyright © 2022 Gregory Lirent */
|
||
|
|
||
|
#include "include.h"
|
||
|
|
||
|
static void string_trim_spaces(str_t* x, int direction) {
|
||
|
static size_t m[32/(sizeof(size_t))] = {0};
|
||
|
|
||
|
u8_t* l;
|
||
|
u8_t* r;
|
||
|
|
||
|
if (sizeof(size_t) == 8) {
|
||
|
m[0] = 0x0000000100002e00UL;
|
||
|
} else {
|
||
|
m[0] = 0x00002e00UL;
|
||
|
m[1] = 0x00000001UL;
|
||
|
}
|
||
|
|
||
|
if (is_null(x->buffer))
|
||
|
return;
|
||
|
|
||
|
l = (void*)x->buffer;
|
||
|
r = (void*)x->buffer + strlen(x->buffer);
|
||
|
|
||
|
if (direction <= 0) {
|
||
|
while (m[*l/(8*sizeof(size_t))]&((size_t)1<<(*l%(8*sizeof(size_t))))) {
|
||
|
++l;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (direction >= 0) {
|
||
|
do {
|
||
|
--r;
|
||
|
} while (m[*r/(8*sizeof(size_t))]&((size_t)1<<(*r%(8*sizeof(size_t)))));
|
||
|
++r;
|
||
|
}
|
||
|
|
||
|
if (x->buffer != (char*)l) {
|
||
|
memmove(x->buffer, l, r-l);
|
||
|
r -= (char*)l - x->buffer;
|
||
|
}
|
||
|
|
||
|
*r = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
static char* string_info(const str_t* s, size_t* size, size_t* nmemb) {
|
||
|
|
||
|
char* p;
|
||
|
char* v;
|
||
|
|
||
|
if (is_null(s->buffer) || !*s->buffer) {
|
||
|
*size = *nmemb = 0;
|
||
|
return s->buffer;
|
||
|
}
|
||
|
|
||
|
*size = *nmemb = strasciilen(s->buffer);
|
||
|
p = s->buffer + *nmemb;
|
||
|
|
||
|
if (!*p) return p;
|
||
|
|
||
|
while (*(v = next_char(p))) {
|
||
|
++*size;
|
||
|
*nmemb += v - p;
|
||
|
p = v;
|
||
|
}
|
||
|
++*size;
|
||
|
*nmemb += v - p;
|
||
|
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
|
||
|
static int fetch_pad(char buffer[4], int chr) {
|
||
|
|
||
|
char* p;
|
||
|
|
||
|
if (chr) {
|
||
|
p = tochar_unicode(buffer, chr);
|
||
|
chr = !is_null(p) ? p - buffer : 0;
|
||
|
}
|
||
|
|
||
|
if (!chr) {
|
||
|
*buffer = ' ';
|
||
|
chr = 1;
|
||
|
}
|
||
|
|
||
|
return chr;
|
||
|
}
|
||
|
|
||
|
/*#####################################################################################################################*/
|
||
|
|
||
|
bool libcdsb_string_concat(str_t* x, const char* s, size_t n) {
|
||
|
size_t xn;
|
||
|
|
||
|
if (n || (n = !is_null(s) ? strlen(s) : 0)) {
|
||
|
xn = (!is_null(x->buffer)) ? strlen(x->buffer) : 0;
|
||
|
|
||
|
x->buffer = realloc(x->buffer, xn + ++n);
|
||
|
memcpy(x->buffer + xn, s, n);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
void libcdsb_string_trim(str_t* x, const char* s, int direction) {
|
||
|
|
||
|
u8_t* l;
|
||
|
u8_t* r;
|
||
|
size_t n;
|
||
|
bool f;
|
||
|
|
||
|
struct {
|
||
|
const char* p;
|
||
|
size_t n;
|
||
|
}* m;
|
||
|
|
||
|
if (is_null(s)) {
|
||
|
string_trim_spaces(x, direction);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (is_null(x->buffer) || !*s)
|
||
|
return;
|
||
|
|
||
|
if (x->buffer == s) {
|
||
|
*x->buffer = 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
n = 0;
|
||
|
m = 0;
|
||
|
|
||
|
while (*(l = (void*)next_char((void*)s))) {
|
||
|
m = realloc(m, ++n*sizeof(*m));
|
||
|
m[n-1].n = (char*)l - s;
|
||
|
m[n-1].p = s;
|
||
|
s = (void*)l;
|
||
|
}
|
||
|
|
||
|
m = realloc(m, ++n*sizeof(*m));
|
||
|
m[n-1].n = (char*)l - s;
|
||
|
m[n-1].p = s;
|
||
|
|
||
|
l = (void*)x->buffer;
|
||
|
r = (void*)x->buffer + strlen(x->buffer);
|
||
|
|
||
|
if (direction <= 0) {
|
||
|
f = false;
|
||
|
do for (size_t i = 0; i < n; ++i) {
|
||
|
if (memcmp(l, m[i].p, m[i].n) == 0) {
|
||
|
f = true;
|
||
|
l += m[i].n;
|
||
|
break;
|
||
|
}
|
||
|
} while(f && !(f = false));
|
||
|
}
|
||
|
|
||
|
if (direction >= 0) {
|
||
|
f = false;
|
||
|
do for (size_t i = 0; i < n; ++i) {
|
||
|
if (memcmp(r - m[i].n, m[i].p, m[i].n) == 0) {
|
||
|
f = true;
|
||
|
r -= m[i].n;
|
||
|
break;
|
||
|
}
|
||
|
} while(f && !(f = false));
|
||
|
}
|
||
|
|
||
|
if (x->buffer != (char*)l) {
|
||
|
memmove(x->buffer, l, r-l);
|
||
|
r -= (char*)l - x->buffer;
|
||
|
}
|
||
|
|
||
|
*r = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
size_t libcdsb_string_align(str_t* x, size_t n, int pc, int direction) {
|
||
|
char *p, s[4];
|
||
|
size_t l, ls, rs;
|
||
|
|
||
|
string_info(x, &ls, &l);
|
||
|
|
||
|
if (ls < n) {
|
||
|
pc = fetch_pad(s, pc);
|
||
|
|
||
|
if (direction == 0) {
|
||
|
ls = n - ls;
|
||
|
rs = ls / 2;
|
||
|
ls -= rs;
|
||
|
} else if (direction < 0) {
|
||
|
rs = n - ls;
|
||
|
ls = 0;
|
||
|
} else {
|
||
|
ls = n - ls;
|
||
|
rs = 0;
|
||
|
}
|
||
|
} else return ls;
|
||
|
|
||
|
x->buffer = p = realloc(x->buffer, l + ((ls + rs) * pc) + 1);
|
||
|
|
||
|
if (ls) {
|
||
|
memmove(x->buffer + ls * pc, x->buffer, l);
|
||
|
|
||
|
do {
|
||
|
p = memcpy(p, s, pc) + pc;
|
||
|
} while (--ls);
|
||
|
|
||
|
p += l;
|
||
|
} else p = x->buffer + l;
|
||
|
|
||
|
while (rs--) p = memcpy(p, s, pc) + pc;
|
||
|
*p = 0;
|
||
|
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
|
||
|
size_t libcdsb_string_replace(str_t* x, const char* s, size_t sn, const char* d, size_t dn, size_t m) {
|
||
|
|
||
|
char *sc, *dc;
|
||
|
char *p;
|
||
|
size_t c, n, o;
|
||
|
|
||
|
if (is_null(x->buffer) || is_null(s) || !*x->buffer || !*(char*)s)
|
||
|
return 0;
|
||
|
|
||
|
if (s == d) return string_count(x, s);
|
||
|
|
||
|
if (!sn) sn = strlen(s);
|
||
|
if (!dn) dn = !is_null(d) ? strlen(d) : dn;
|
||
|
|
||
|
n = strlen(x->buffer);
|
||
|
p = x->buffer;
|
||
|
sc = dc = (void*)(c = 0);
|
||
|
|
||
|
if (x->buffer == s) {
|
||
|
x->buffer = realloc(x->buffer, dn + 1);
|
||
|
memcpy(x->buffer, d, dn);
|
||
|
x->buffer[dn] = 0;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if (x->buffer < (char*)s && (char*)s < x->buffer + n) s = sc = memndup(s, sn);
|
||
|
if (x->buffer <= (char*)d && (char*)d < x->buffer + n) d = dc = memndup(d, dn);
|
||
|
|
||
|
while (m-- && !is_null(p = strstr(p, s))) {
|
||
|
|
||
|
if (sn != dn) {
|
||
|
size_t l = n;
|
||
|
|
||
|
if (sn < dn) {
|
||
|
n += dn - sn;
|
||
|
o = p - x->buffer;
|
||
|
x->buffer = realloc(x->buffer, n + 1);
|
||
|
p = x->buffer + o;
|
||
|
} else n -= sn - dn;
|
||
|
|
||
|
memmove(p + dn, p + sn, l - (p + n - x->buffer) + 1);
|
||
|
}
|
||
|
|
||
|
p += sn;
|
||
|
++c;
|
||
|
}
|
||
|
|
||
|
free(sc);
|
||
|
free(dc);
|
||
|
|
||
|
return c;
|
||
|
}
|