/* 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; }