Refactor string

This commit is contained in:
Gregory Lirent 2022-08-22 12:13:20 +03:00
parent 205c8337c2
commit ca8251973e
19 changed files with 627 additions and 1111 deletions

View File

@ -2,8 +2,8 @@
/* Copyright © 2022 Gregory Lirent */
#include <stdio.h>
#include "../include/extra/string.h"
#include "../include/extra/array.h"
#include "../include/array.h"
#include "../include/string.h"
typedef vtype_string str_t;
typedef vtype_array arr_t;
@ -25,14 +25,14 @@ int main(int argc, char** argv) {
printf("%s\n", str.buffer);
arr_t parts = string_split(&str, ',', -1);
arr_t parts = string_split(&str, ',');
printf("%lu\n", array_size(&parts));
for (size_t i = 0; i < array_size(&parts); ++i) {
str_t* value = array_at(&parts, i);
str_t* value = at_array(&parts, i);
string_trim_spaces(value);
string_trim(value, 0);
printf("%s (%lu)\n", value->buffer, string_nmemb(value));
}

View File

@ -1,88 +1,48 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "__generics.h"
#include "bits/__generics.h"
#include "vtype.h"
#include <uchar.h>
#ifndef LIBCDSB_STRING_H
#define LIBCDSB_STRING_H
/*#####################################################################################################################*/
extern void string_init(vtype_string* x, const char* value) Nonnull__(1);
extern char* string_at(const vtype_string* s, ssize_t index) Nonnull__(1);
extern size_t string_slice (vtype_string* x, vtype_string* s, ssize_t index, size_t nchars, bool cut) Nonnull__(1,2);
extern size_t string_reverse (vtype_string* x) Nonnull__(1);
extern size_t string_to_lower (vtype_string* x) Nonnull__(1);
extern size_t string_to_upper (vtype_string* x) Nonnull__(1);
extern size_t string_capitalize(vtype_string* x) Nonnull__(1);
#define string_indexof(s, arg) _LIBCDSB_GenericS(libcdsb_string, indexof, arg)(s, arg)
#define string_count(s, arg) _LIBCDSB_GenericS(libcdsb_string, count, arg)(s, arg)
#define string_concat(x, value) _LIBCDSB_GenericS(libcdsb_string, concat, value)(x, value)
#define string_trim_spaces(x) libcdsb_string_trim_spaces(x, 0)
#define string_ltrim_spaces(x) libcdsb_string_trim_spaces(x, -1)
#define string_rtrim_spaces(x) libcdsb_string_trim_spaces(x, 1)
#define string_replace(x, src, dest, maxn) _LIBCDSB_GenericS2(libcdsb_string, replace, src, dest)(x, src, dest, maxn)
extern char* at_string (const vtype_string* s, ssize_t index) Nonnull__(1);
/*#####################################################################################################################*/
inline ssize_t libcdsb_string_indexof_string (const vtype_string* s, const vtype_string* arg) Pure__ Warn_unused_result__ Nonnull__(1) Always_inline__;
extern ssize_t libcdsb_string_indexof_cstring(const vtype_string* s, const char* arg) Pure__ Warn_unused_result__ Nonnull__(1);
extern ssize_t libcdsb_string_indexof_char (const vtype_string* s, int arg) Pure__ Warn_unused_result__ Nonnull__(1);
inline size_t libcdsb_string_count_string (const vtype_string* s, const vtype_string* arg) Pure__ Warn_unused_result__ Nonnull__(1) Always_inline__;
extern size_t libcdsb_string_count_cstring(const vtype_string* s, const char* arg) Pure__ Warn_unused_result__ Nonnull__(1);
extern size_t libcdsb_string_count_char (const vtype_string* s, int arg) Pure__ Warn_unused_result__ Nonnull__(1);
inline bool libcdsb_string_concat_string (vtype_string* x, const vtype_string* value) Nonnull__(1) Always_inline__;
extern bool libcdsb_string_concat_cstring(vtype_string* x, const char* value) Nonnull__(1);
extern bool libcdsb_string_concat_char (vtype_string* x, int value) Nonnull__(1);
extern void libcdsb_string_trim_spaces(vtype_string* x, int direction) Nonnull__(1);
inline size_t libcdsb_string_replace_string_string (vtype_string* x, const vtype_string* src, const vtype_string* dest, size_t maxn) Nonnull__(1) Always_inline__;
inline size_t libcdsb_string_replace_string_cstring (vtype_string* x, const vtype_string* src, const char* dest, size_t maxn) Nonnull__(1) Always_inline__;
inline size_t libcdsb_string_replace_string_char (vtype_string* x, const vtype_string* src, int dest, size_t maxn) Nonnull__(1) Always_inline__;
inline size_t libcdsb_string_replace_cstring_string (vtype_string* x, const char* src, const vtype_string* dest, size_t maxn) Nonnull__(1) Always_inline__;
extern size_t libcdsb_string_replace_cstring_cstring(vtype_string* x, const char* src, const char* dest, size_t maxn) Nonnull__(1);
extern size_t libcdsb_string_replace_cstring_char (vtype_string* x, const char* src, int dest, size_t maxn) Nonnull__(1);
inline size_t libcdsb_string_replace_char_string (vtype_string* x, int src, const vtype_string* dest, size_t maxn) Nonnull__(1) Always_inline__;
extern size_t libcdsb_string_replace_char_cstring (vtype_string* x, int src, const char* dest, size_t maxn) Nonnull__(1);
extern size_t libcdsb_string_replace_char_char (vtype_string* x, int src, int dest, size_t maxn) Nonnull__(1);
#define string_init(x, s) libcdsb_string_init (x, _LIBCDSB_to_cstring(s), 0)
#define string_indexof(x, s) libcdsb_string_indexof(x, _LIBCDSB_to_cstring(s))
#define string_count(x, s) libcdsb_string_count (x, _LIBCDSB_to_cstring(s), 0)
#define string_concat(x, s) libcdsb_string_concat (x, _LIBCDSB_to_cstring(s), 0)
#define string_align(x, n, c) libcdsb_string_align (x, n, c, 0)
#define string_lalign(x, n, c) libcdsb_string_align (x, n, c, -1)
#define string_ralign(x, n, c) libcdsb_string_align (x, n, c, 1)
#define string_split(x, s) libcdsb_string_split (x, _LIBCDSB_to_cstring(s), 0, -1)
#define string_trim(x, s) libcdsb_string_trim (x, _LIBCDSB_to_cstring(s), 0)
#define string_ltrim(x, s) libcdsb_string_trim (x, _LIBCDSB_to_cstring(s), -1)
#define string_rtrim(x, s) libcdsb_string_trim (x, _LIBCDSB_to_cstring(s), 1)
#define string_replace(x, s, d) libcdsb_string_replace(x, _LIBCDSB_to_cstring(s), 0, _LIBCDSB_to_cstring(d), 0, -1)
/*#####################################################################################################################*/
inline ssize_t libcdsb_string_indexof_string(const vtype_string* s, const vtype_string* arg) {
return string_indexof(s, arg->buffer);
}
inline void libcdsb_string_init (vtype_string* x, const char* s, size_t nmemb) Always_inline__ Nonnull__(1);
extern bool libcdsb_string_concat (vtype_string* x, const char* s, size_t nmemb) Nonnull__(1);
extern void libcdsb_string_trim (vtype_string* x, const char* s, int direction) Nonnull__(1);
extern size_t libcdsb_string_align (vtype_string* x, size_t padsize, int padchr, int direction) Nonnull__(1);
extern ssize_t libcdsb_string_indexof(const vtype_string* x, const char* s) Pure__ Warn_unused_result__ Nonnull__(1);
extern size_t libcdsb_string_count (const vtype_string* x, const char* s, size_t nmemb) Pure__ Warn_unused_result__ Nonnull__(1);
extern vtype_array libcdsb_string_split (const vtype_string* x, const char* s, size_t nmemb, size_t maxn) Nonnull__(1);
extern size_t libcdsb_string_replace(vtype_string* x, const char* s, size_t snmemb, const char* d, size_t dnmemb, size_t maxn) Nonnull__(1,2);
inline size_t libcdsb_string_count_string(const vtype_string* s, const vtype_string* arg) {
return string_count(s, arg->buffer);
}
inline void libcdsb_string_init (vtype_string* x, const char* s, size_t nmemb) { x->buffer = ((nmemb) ? libcdsb_strndup(s, nmemb) : libcdsb_strdup(s)); }
inline bool libcdsb_string_concat_string(vtype_string* x, const vtype_string* s) {
return string_concat(x, s->buffer);
}
inline size_t libcdsb_string_replace_string_string (vtype_string* x, const vtype_string* src, const vtype_string* dest, size_t maxn) {
return string_replace(x, src->buffer, dest->buffer, maxn);
}
inline size_t libcdsb_string_replace_string_cstring(vtype_string* x, const vtype_string* src, const char* dest, size_t maxn) {
return string_replace(x, src->buffer, dest, maxn);
}
inline size_t libcdsb_string_replace_cstring_string(vtype_string* x, const char* src, const vtype_string* dest, size_t maxn) {
return string_replace(x, src, dest->buffer, maxn);
}
inline size_t libcdsb_string_replace_string_char (vtype_string* x, const vtype_string* src, int dest, size_t maxn) {
return string_replace(x, src->buffer, dest, maxn);
}
inline size_t libcdsb_string_replace_char_string (vtype_string* x, int src, const vtype_string* dest, size_t maxn) {
return string_replace(x, src, dest->buffer, maxn);
}
#endif /* LIBCDSB_BASE_STRING_H */
#endif /* LIBCDSB_STRING_H */

61
src/string/access.c Normal file
View File

@ -0,0 +1,61 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
char* at_string(const str_t* s, ssize_t i) {
char *e, *p;
size_t n, l;
if (is_null(s->buffer) || !*s->buffer)
return nullptr;
n = strasciilen(s->buffer);
e = s->buffer + n;
if (i > n) {
p = s->buffer + n;
e = p + strlen(p);
do { p = next_char(p); } while (--i && p < e);
return (!i) ? p : nullptr;
} else if (i < 0 && n < (l = strlen(s->buffer))) {
p = s->buffer + l;
do { p = prev_char(p); } while (++i && p >= s->buffer);
return (!i) ? p : nullptr;
} else if (i < 0 && (i += l) < 0) i = 0;
return s->buffer + i;
}
ssize_t libcdsb_string_indexof(const str_t* x, const char* s) {
char *e, *p;
size_t n;
if (is_null(x->buffer) || is_null(s) || !*x->buffer || !*s) {
return 0;
}
if (!is_null(p = strstr(x->buffer, s))) {
n = strasciilen(x->buffer);
e = x->buffer + n;
if (e >= p) return p - x->buffer;
do {
e = next_char(e);
++n;
} while (e < p);
if (e != p) {
/* Trying to find index of inconsistent string part
* It is not make a sense on that abstract level */
} else return n;
}
return -1;
}

View File

@ -1,142 +0,0 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
hash_t string_hash(const str_t* s) {
hash_t hash = 0;
size_t nmemb = string_nmemb(s);
if (nmemb > 0)
hash = s->buffer[0];
if (nmemb > 1)
hash += s->buffer[nmemb-1];
hash ^= nmemb;
return hash + VTYPE_STRING;
}
size_t string_nmemb(const str_t* s) {
return (!is_null(s->buffer)) ? strlen(s->buffer) : 0;
}
size_t string_size(const str_t* s) {
size_t n;
char* p;
if (is_null(s->buffer) || !*s->buffer)
return 0;
n = strasciilen(s->buffer);
p = s->buffer + n;
while (*p) {
p = next_char(p);
++n;
}
return n;
}
void string_init(str_t* x, const char* s) {
size_t n = (!is_null(s)) ? strlen(s) : 0;
if (n) x->buffer = strndup(s, n);
else memset(x, 0, sizeof(*x));
}
void string_free(str_t* x) {
free(x->buffer);
memset(x, 0, sizeof(*x));
}
int string_compare(const str_t* s0, const str_t* s1) {
ssize_t n0, n1;
if (s0 == s1) return 0;
n0 = (!is_null(s0->buffer)) ? strlen(s0->buffer) : 0;
n1 = (!is_null(s1->buffer)) ? strlen(s1->buffer) : 0;
n0 -= n1;
if (n0 || !n1) return n0;
return memcmp(s0->buffer, s1->buffer, n1);
}
/*#####################################################################################################################*/
bool libcdsb_string_concat_cstring(str_t* x, const char* s) {
size_t n;
size_t xn;
if ((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;
}
bool libcdsb_string_concat_char(str_t* x, int chr) {
size_t xn;
size_t n;
char *e;
char s[5] = {0};
if (!is_null(e = tochar_unicode(s, chr))) {
xn = (!is_null(x->buffer)) ? strlen(x->buffer) : 0;
n = e - s;
x->buffer = realloc(x->buffer, xn + ++n);
memcpy(x->buffer + xn, s, n);
return true;
}
return false;
}
/*#####################################################################################################################*/
str_t string_copy(const str_t* s) {
str_t x = { .buffer = 0 };
size_t n = (!is_null(s->buffer)) ? strlen(s->buffer) : 0;
if (n) x.buffer = strndup(s->buffer, n);
return x;
}
str_t* string_duplicate(const str_t* s) {
str_t* x = calloc(sizeof(*x), 1);
size_t n = (!is_null(s->buffer)) ? strlen(s->buffer) : 0;
if (n) x->buffer = strndup(s->buffer, n);
return x;
}
void string_copy_init(str_t* x, const str_t* s) {
size_t n = (!is_null(s->buffer)) ? strlen(s->buffer) : 0;
if (n) x->buffer = strndup(s->buffer, n);
else memset(x, 0, sizeof(*x));
}

66
src/string/comparison.c Normal file
View File

@ -0,0 +1,66 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include <ctype.h>
#include "include.h"
int string_compare(const str_t* s0, const str_t* s1) {
ssize_t n0, n1;
if (s0 == s1) return 0;
n0 = (!is_null(s0->buffer)) ? strlen(s0->buffer) : 0;
n1 = (!is_null(s1->buffer)) ? strlen(s1->buffer) : 0;
n0 -= n1;
if (n0 || !n1) return n0;
return memcmp(s0->buffer, s1->buffer, n1);
}
int string_case_compare(const str_t* s0, const str_t* s1) {
const char *p0, *p1, *t0, *t1;
ssize_t n0, n1;
u32_t uc0, uc1;
if (s0 == s1) return 0;
p0 = s0->buffer;
p1 = s1->buffer;
n0 = (!is_null(p0)) ? strasciilen(p0) : 0;
n1 = (!is_null(p1)) ? strasciilen(p1) : 0;
n0 -= n1;
if (!n0 && n1) {
do {
n0 = toupper(*(p0++));
n0 -= toupper(*(p1++));
if (n0) return n0;
} while(--n1);
} else return memcmp(s0->buffer, s1->buffer, n1);
while (*p0 && *p1) {
t0 = fromchar_unicode(&uc0, p0);
t1 = fromchar_unicode(&uc1, p1);
if (is_null(t0) || is_null(t1)) {
n0 = (ssize_t)*(unsigned char*)(p0++) - *(unsigned char*)(p1++);
if (n0) return n0;
} else {
n0 = toupper_unicode(uc0);
if ((n0 -= toupper_unicode(uc1)))
return n0;
p0 = t0;
p1 = t1;
}
}
n0 = *(unsigned char*)p0 - *(unsigned char*)p1;
return n0;
}

60
src/string/compute.c Normal file
View File

@ -0,0 +1,60 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
size_t string_size(const str_t* s) {
size_t n;
char* p;
if (is_null(s->buffer) || !*s->buffer)
return 0;
n = strasciilen(s->buffer);
p = s->buffer + n;
while (*p) {
p = next_char(p);
++n;
}
return n;
}
hash_t string_hash(const str_t* s) {
hash_t hash = 0;
size_t nmemb = string_nmemb(s);
if (nmemb > 0)
hash = s->buffer[0];
if (nmemb > 1)
hash += s->buffer[nmemb-1];
hash ^= nmemb;
return hash + VTYPE_STRING;
}
size_t libcdsb_string_count(const str_t* x, const char* s, size_t sn) {
char* p;
size_t c;
if (is_null(x->buffer) || is_null(s) || !*x->buffer || !*s) {
return 0;
}
if (!sn) sn = strlen(s);
p = x->buffer;
c = 0;
while (!is_null(p = strstr(p, s))) {
p += sn;
++c;
}
return c;
}

78
src/string/copy.c Normal file
View File

@ -0,0 +1,78 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
size_t string_slice(str_t* x, str_t* s, ssize_t i, size_t c, bool cut) {
char *e, *p, *v;
size_t n = 0;
memset(x, 0, sizeof(*x));
if (!c) return n;
p = at_string(s, i);
if (is_null(p))
return n;
e = p + strlen(p);
v = p;
while (c-- && v < e) {
v = next_char(v);
++n;
}
x->buffer = strndup(p, v - p);
if (cut) {
memmove(p, v, strlen(v) + 1);
}
return n;
}
arr_t libcdsb_string_split(const str_t* x, const char* s, size_t sn, size_t maxn) {
arr_t ret;
char *p, *e;
str_t* v;
ret.mem = 0;
ret.size = 0;
ret.type = VTYPE_STRING;
if (is_null(x->buffer))
return ret;
if (is_null(s) || !*s) {
v = ret.mem = malloc(sizeof(str_t));
v->buffer = strdup(x->buffer);
return ret;
}
if (!sn) sn = strlen(s);
p = x->buffer;
e = p;
while (maxn-- && !is_null(p = strstr(p, s))) {
p += sn;
v = ret.mem = realloc(ret.mem, ++ret.size * sizeof(str_t));
v[ret.size-1].buffer = strndup(e, p - e);
p += sn;
e = p;
}
if (*e) {
sn = strlen(e);
v = ret.mem = realloc(ret.mem, ++ret.size*sizeof(str_t));
v[ret.size-1].buffer = strndup(e, sn);
}
return ret;
}

View File

@ -1,142 +0,0 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
/*#####################################################################################################################*/
static char* string_info(const vtype_string* 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;
}
/*#####################################################################################################################*/
size_t string_align_center(vtype_string* x, size_t n, int pc) {
char s[4];
size_t l;
size_t ls;
size_t rs;
char* p;
string_info(x, &ls, &l);
if (ls < n) {
pc = fetch_pad(s, pc);
ls = n - ls;
rs = ls / 2;
} else return ls;
x->buffer = p = realloc(x->buffer, l + ls*pc + 1);
memmove(x->buffer + (ls -= rs)*pc, x->buffer, l);
for (size_t i = 0; i < ls; ++i) {
p = memcpy(p, s, pc) + pc;
}
p += l;
for (size_t i = 0; i < rs; ++i) {
p = memcpy(p, s, pc) + pc;
}
*p = 0;
return n;
}
size_t string_align_right(vtype_string* x, size_t n, int pc) {
char s[4];
size_t l;
size_t ls;
char* p;
string_info(x, &ls, &l);
if (ls < n) {
pc = fetch_pad(s, pc);
ls = n - ls;
} else return ls;
x->buffer = p = realloc(x->buffer, ++l + ls*pc);
memmove(x->buffer + ls*pc, x->buffer, l);
for (size_t i = 0; i < ls; ++i) {
p = memcpy(p, s, pc) + pc;
}
return n;
}
size_t string_align_left(vtype_string* x, size_t n, int pc) {
char s[4];
size_t l;
size_t rs;
char* p;
string_info(x, &rs, &l);
if (rs < n) {
pc = fetch_pad(s, pc);
rs = n - rs;
} else return rs;
x->buffer = realloc(x->buffer, l + rs*pc + 1);
p = x->buffer + l;
for (size_t i = 0; i < rs; ++i) {
p = memcpy(p, s, pc) + pc;
}
*p = 0;
return n;
}

View File

@ -1,89 +0,0 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
arr_t libcdsb_string_split_cstring(const str_t* s, const char* a, size_t maxn) {
arr_t x = { .mem = 0, .size = 0, .type = VTYPE_STRING };
size_t n;
char* p;
char* e;
str_t* v;
if (is_null(s->buffer)) {
return x;
}
if (is_null(a) || !*a) {
v = x.mem = malloc(sizeof(str_t));
v->buffer = strdup(s->buffer);
return x;
}
n = strlen(a);
p = s->buffer;
e = p;
while (maxn-- && !is_null(p = strstr(p, a))) {
p += n;
v = x.mem = realloc(x.mem, ++x.size*sizeof(str_t));
v[x.size-1].buffer = strndup(e, p - e);
p += n;
e = p;
}
if (*e) {
n = strlen(e);
v = x.mem = realloc(x.mem, ++x.size*sizeof(str_t));
v[x.size-1].buffer = strndup(e, n);
}
return x;
}
arr_t libcdsb_string_split_char(const str_t* s, int ac, size_t maxn) {
arr_t x = { .mem = 0, .size = 0, .type = VTYPE_STRING };
char a[5] = { 0 };
size_t n;
char* p;
char* e;
str_t* v;
if (is_null(s->buffer)) {
return x;
}
if (is_null(p = tochar_unicode(a, ac)) || !(n = p - a)) {
v = x.mem = malloc(sizeof(str_t));
v->buffer = strdup(s->buffer);
return x;
}
p = s->buffer;
e = p;
while (maxn-- && !is_null(p = strstr(p, a))) {
p += n;
v = x.mem = realloc(x.mem, ++x.size*sizeof(str_t));
v[x.size-1].buffer = strndup(e, p - e);
p += n;
e = p;
}
if (*e) {
n = strlen(e);
v = x.mem = realloc(x.mem, ++x.size*sizeof(str_t));
v[x.size-1].buffer = strndup(e, n);
}
return x;
}

View File

@ -1,174 +0,0 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
char* string_at(const str_t* s, ssize_t i) {
char *e, *p;
size_t n, l;
if (is_null(s->buffer) || !*s->buffer)
return nullptr;
n = strasciilen(s->buffer);
e = s->buffer + n;
if (i > n) {
p = s->buffer + n;
e = p + strlen(p);
do { p = next_char(p); } while (--i && p < e);
return (!i) ? p : nullptr;
} else if (i < 0 && n < (l = strlen(s->buffer))) {
p = s->buffer + l;
do { p = prev_char(p); } while (++i && p >= s->buffer);
return (!i) ? p : nullptr;
} else if (i < 0 && (i += l) < 0) i = 0;
return s->buffer + i;
}
size_t string_slice(str_t* x, str_t* s, ssize_t i, size_t c, bool cut) {
char *e, *p, *v;
size_t n = 0;
memset(x, 0, sizeof(*x));
if (!c) return n;
p = string_at(s, i);
if (is_null(p))
return n;
e = p + strlen(p);
v = p;
while (c-- && v < e) {
v = next_char(v);
++n;
}
x->buffer = strndup(p, v - p);
if (cut) {
memmove(p, v, strlen(v) + 1);
}
return n;
}
/*#####################################################################################################################*/
ssize_t libcdsb_string_indexof_cstring(const str_t* s, const char* a) {
char *e, *p;
size_t n;
if (is_null(s->buffer) || is_null(a) || !*s->buffer || !*a) {
return 0;
}
if (!is_null(p = strstr(s->buffer, a))) {
n = strasciilen(s->buffer);
e = s->buffer + n;
if (e >= p) return p - s->buffer;
do {
e = next_char(e);
++n;
} while (e < p);
if (e != p) {
/* Trying to find index of inconsistent string part
* It is not make a sense on that abstract level */
} else return n;
}
return -1;
}
ssize_t libcdsb_string_indexof_char(const str_t* s, int ac) {
size_t n;
char* e;
char a[5] = { 0 };
char* p = tochar_unicode(a, ac);
if (is_null(s->buffer) || !*s->buffer || is_null(p)) {
return 0;
}
if (!is_null(p = strstr(s->buffer, a))) {
n = strasciilen(s->buffer);
e = s->buffer + n;
if (e >= p) return p - s->buffer;
do {
e = next_char(e);
++n;
} while (e < p);
if (e != p) {
/* Trying to find index of inconsistent string part
* It is not make a sense on that abstract level */
} else return n;
}
return -1;
}
/*#####################################################################################################################*/
size_t libcdsb_string_count_cstring(const str_t* s, const char* a) {
char* p;
size_t n, c;
if (is_null(s->buffer) || is_null(a) || !*s->buffer || !*a) {
return 0;
}
n = strlen(a);
p = s->buffer;
c = 0;
while (!is_null(p = strstr(p, a))) {
p += n;
++c;
}
return c;
}
size_t libcdsb_string_count_char(const str_t* s, int ac) {
size_t n, c;
char a[5] = {0};
char* p = tochar_unicode(a, ac);
if (is_null(s->buffer) || !*s->buffer || is_null(p)) {
return 0;
}
n = p - a;
p = s->buffer;
c = 0;
while (!is_null(p = strstr(p, a))) {
p += n;
++c;
}
return c;
}

View File

@ -2,7 +2,7 @@
/* Copyright © 2022 Gregory Lirent */
#include "../../modules/libunic/include.h"
#include "../../include/extra/string.h"
#include "../../include/string.h"
#include "../__internal/include.h"
#ifndef LIBCDSB_SRC_STRING_INCLUDE_H

275
src/string/modify.c Normal file
View File

@ -0,0 +1,275 @@
/* 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;
}

View File

@ -1,223 +0,0 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
size_t libcdsb_string_replace_cstring_cstring(str_t* x, const char* a, const char* d, size_t maxn) {
char *p, *t, *r;
size_t c, n, an, dn;
if (a == d) return string_count(x, a);
if (is_null(x->buffer) || is_null(a) || !*x->buffer || !*a) {
return 0;
}
an = strlen(a);
dn = (!is_null(d)) ? strlen(d) : 0;
n = strlen(x->buffer);
p = x->buffer;
c = 0;
t = 0;
r = 0;
if (x->buffer == a) {
x->buffer = realloc(x->buffer, dn + 1);
memcpy(x->buffer, d, dn);
x->buffer[dn] = 0;
return 1;
}
if (x->buffer < a && a < x->buffer + n) {
a = r = memndup(a, an);
}
if (x->buffer <= d && d < x->buffer + n) {
d = t = memndup(d, dn);
}
while (maxn-- && !is_null(p = strstr(p, a))) {
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}
free(r);
free(t);
return c;
}
size_t libcdsb_string_replace_cstring_char(str_t* x, const char* a, int dc, size_t maxn) {
char *p, *t;
char d[4];
size_t c, n, an, dn;
if (is_null(x->buffer) || is_null(a) || !*x->buffer || !*a) {
return 0;
}
an = strlen(a);
p = tochar_unicode(d, dc);
dn = (!is_null(p)) ? p - d : 0;
n = strlen(x->buffer);
p = x->buffer;
c = 0;
t = 0;
if (x->buffer == a) {
x->buffer = realloc(x->buffer, dn + 1);
memcpy(x->buffer, d, dn);
x->buffer[dn] = 0;
return 1;
} else if (x->buffer < a && a < x->buffer + n) {
a = t = memndup(a, an);
}
while (maxn-- && !is_null(p = strstr(p, a))) {
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}
free(t);
return c;
}
size_t libcdsb_string_replace_char_cstring(str_t* x, int ac, const char* d, size_t maxn) {
char *p, *t;
char a[4];
size_t c, n, an, dn;
p = tochar_unicode(a, ac);
if (is_null(x->buffer) || is_null(p) || !*x->buffer || !*p) {
return 0;
}
an = p - a;
dn = (!is_null(d)) ? strlen(d) : 0;
n = strlen(x->buffer);
p = x->buffer;
c = 0;
t = 0;
if (x->buffer <= d && d < x->buffer + n) {
d = t = memndup(d, dn);
}
while (maxn-- && !is_null(p = strstr(p, a))) {
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}
free(t);
return c;
}
size_t libcdsb_string_replace_char_char(str_t* x, int ac, int dc, size_t maxn) {
char* p;
char a[4];
char d[4];
size_t c, an, dn;
p = tochar_unicode(a, ac);
if (is_null(x->buffer) || is_null(p) || !*x->buffer || !*p) {
return 0;
}
an = p - a;
p = tochar_unicode(d, dc);
dn = (!is_null(p)) ? p - d : 0;
p = x->buffer;
c = 0;
while (maxn-- && !is_null(p = strstr(p, a))) {
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}
return c;
}
size_t libcdsb_string_replace_r_cstring_cstring(str_t* x, const char*restrict a, const char*restrict d, size_t maxn) {
char *restrict p;
size_t c, an, dn;
if (is_null(x->buffer) || is_null(a) || !*x->buffer || !*a) {
return 0;
}
an = strlen(a);
dn = (!is_null(d)) ? strlen(d) : 0;
p = x->buffer;
c = 0;
while (maxn-- && !is_null(p = strstr(p, a))) {
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}
return c;
}
size_t libcdsb_string_replace_r_cstring_char(str_t* x, const char*restrict a, int dc, size_t maxn) {
char *restrict p;
char d[4];
size_t c, an, dn;
if (is_null(x->buffer) || is_null(a) || !*x->buffer || !*a) {
return 0;
}
an = strlen(a);
p = tochar_unicode(d, dc);
dn = (!is_null(p)) ? p - d : 0;
p = x->buffer;
c = 0;
while (maxn-- && !is_null(p = strstr(p, a))) {
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}
return c;
}
size_t libcdsb_string_replace_r_char_cstring(str_t* x, int ac, const char*restrict d, size_t maxn) {
char *restrict p;
char a[4];
size_t c, an, dn;
p = tochar_unicode(a, ac);
if (is_null(x->buffer) || is_null(p) || !*x->buffer || !*p) {
return 0;
}
an = p - a;
dn = (!is_null(d)) ? strlen(d) : 0;
p = x->buffer;
c = 0;
while (maxn-- && !is_null(p = strstr(p, a))) {
libcdsb_string_replace(x, p, an, d, dn);
p += an;
++c;
}
return c;
}

View File

@ -1,60 +1,59 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include <ctype.h>
#include "include.h"
int string_compare_case_insensitive(const str_t* s0, const str_t* s1) {
const char *p0, *p1, *t0, *t1;
ssize_t n0, n1;
u32_t uc0, uc1;
static void string_replace_builtin(str_t* x, char* p, size_t n, const char* v, size_t vn) {
if (n != vn) {
size_t l = strlen(x->buffer);
if (s0 == s1) return 0;
if (n < vn) {
char* t = x->buffer;
p0 = s0->buffer;
p1 = s1->buffer;
n0 = (!is_null(p0)) ? strasciilen(p0) : 0;
n1 = (!is_null(p1)) ? strasciilen(p1) : 0;
n0 -= n1;
if (!n0 && n1) {
do {
n0 = toupper(*(p0++));
n0 -= toupper(*(p1++));
if (n0) return n0;
} while(--n1);
} else return memcmp(s0->buffer, s1->buffer, n1);
while (*p0 && *p1) {
t0 = fromchar_unicode(&uc0, p0);
t1 = fromchar_unicode(&uc1, p1);
if (is_null(t0) || is_null(t1)) {
n0 = (ssize_t)*(unsigned char*)(p0++) - *(unsigned char*)(p1++);
if (n0) return n0;
} else {
n0 = toupper_unicode(uc0);
if ((n0 -= toupper_unicode(uc1)))
return n0;
p0 = t0;
p1 = t1;
}
x->buffer = realloc(x->buffer, l + (vn - n) + 1);
p = x->buffer + (p - t);
}
n0 = *(unsigned char*)p0 - *(unsigned char*)p1;
return n0;
memmove(p+vn, p+n, l - (p+n - x->buffer) + 1);
}
memcpy(p, v, vn);
}
/*#####################################################################################################################*/
size_t string_reverse(str_t* x) {
char *t, *p, *v;
size_t n;
if (is_null(x->buffer) || !*x->buffer)
return 0;
n = strlen(x->buffer);
t = malloc(n + 1);
p = t + n;
v = x->buffer;
n = 0;
while (p > t) {
int cs = charsize(v);
if (cs > 1) {
p = memcpy(p - cs, v, cs);
v += cs;
} else *(--p) = *(v++);
++n;
}
free(x->buffer);
x->buffer = t;
return n;
}
size_t string_to_lower(str_t* x) {
char ps[4];
char *es, *p, *e;
u32_t uc0, uc1;
@ -76,7 +75,7 @@ size_t string_to_lower(str_t* x) {
es = tochar_unicode(ps, uc1);
if (!is_null(es)) {
libcdsb_string_replace(x, p, e-p, ps, es-ps);
string_replace_builtin(x, p, e-p, ps, es-ps);
++n;
}
}
@ -112,7 +111,7 @@ size_t string_to_upper(str_t* x) {
es = tochar_unicode(ps, uc1);
if (!is_null(es)) {
libcdsb_string_replace(x, p, e-p, ps, es-ps);
string_replace_builtin(x, p, e-p, ps, es-ps);
++n;
}
}
@ -146,7 +145,7 @@ size_t string_capitalize(str_t* x) {
es = tochar_unicode(ps, uc1);
if (!is_null(es)) {
libcdsb_string_replace(x, p, e-p, ps, es-ps);
string_replace_builtin(x, p, e-p, ps, es-ps);
++n;
}
}
@ -164,7 +163,7 @@ size_t string_capitalize(str_t* x) {
es = tochar_unicode(ps, uc1);
if (!is_null(es)) {
libcdsb_string_replace(x, p, e-p, ps, es-ps);
string_replace_builtin(x, p, e-p, ps, es-ps);
++n;
}
}
@ -175,56 +174,3 @@ size_t string_capitalize(str_t* x) {
return n;
}
/*#####################################################################################################################*/
size_t string_reverse(str_t* x) {
char *t, *p, *v;
size_t n;
if (is_null(x->buffer) || !*x->buffer)
return 0;
n = strlen(x->buffer);
t = malloc(n + 1);
p = t + n;
v = x->buffer;
n = 0;
while (p > t) {
int cs = charsize(v);
if (cs > 1) {
p = memcpy(p - cs, v, cs);
v += cs;
} else *(--p) = *(v++);
++n;
}
free(x->buffer);
x->buffer = t;
return n;
}
/*#####################################################################################################################*/
void libcdsb_string_replace(str_t* x, char* p, size_t n, const char* v, size_t vn) {
if (n != vn) {
size_t l = strlen(x->buffer);
if (n < vn) {
char* t = x->buffer;
x->buffer = realloc(x->buffer, l + (vn - n) + 1);
p = x->buffer + (p - t);
}
memmove(p+vn, p+n, l - (p+n - x->buffer) + 1);
}
memcpy(p, v, vn);
}

View File

@ -1,160 +0,0 @@
/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
/*#####################################################################################################################*/
void libcdsb_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;
}
/*#####################################################################################################################*/
void libcdsb_string_trim_cstring(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))
return libcdsb_string_trim_spaces(x, direction);
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;
}
void libcdsb_string_trim_char(str_t* x, int sc, int direction) {
u8_t* l;
u8_t* r;
char p[4];
size_t n;
if (!sc)
return libcdsb_string_trim_spaces(x, direction);
if (is_null(x->buffer) || is_null(l = (void*)tochar_unicode(p, sc)))
return;
n = (char*)l - p;
l = (void*)x->buffer;
r = (void*)x->buffer + strlen(x->buffer);
if (direction <= 0) {
while (memcmp(l, p, n) == 0) {
l += n;
}
}
if (direction >= 0) {
while (memcmp(r-n, p, n) == 0) {
r -= n;
}
}
if (x->buffer != (char*)l) {
memmove(x->buffer, l, r-l);
r -= (char*)l - x->buffer;
}
*r = 0;
}

View File

@ -2,7 +2,7 @@
/* Copyright © 2022 Gregory Lirent */
#include <stdio.h>
#include "../../include/extra/vtype.h"
#include "../../include/vtype.h"
#ifndef LIBCDSB_TESTS_TEST_H
#define LIBCDSB_TESTS_TEST_H

View File

@ -18,10 +18,10 @@ int main(int argc, char** argv) {
{
char* repl = random_utf8_cstring(30);
void* hack = string_at(&x, 31);
void* hack = at_string(&x, 31);
string_print((void*)&hack, "(part 2)");
string_print((void*)&repl, "(part 2 replaced)");
string_replace(&x, hack, repl, -1);
string_replace(&x, hack, repl);
free(repl);
}
@ -54,16 +54,16 @@ int main(int argc, char** argv) {
x = string_random(12);
string_align_center(&x, 30, 0);
string_align(&x, 30, 0);
string_info(&x);
string_print(&x, 0);
string_trim_spaces(&x);
string_trim(&x, 0);
string_info(&x);
string_print(&x, "trimmed");
put_separator(0);
string_align_center(&x, 30, c);
string_align(&x, 30, c);
string_info(&x);
string_print(&x, 0);

View File

@ -3,7 +3,7 @@
#include <stdlib.h>
#include "../../../modules/libunic/include.h"
#include "../../../include/extra/string.h"
#include "../../../include/string.h"
#include "../../include/random.h"
#include "../../include/test.h"

View File

@ -45,7 +45,7 @@ void string_replace_random(str_t* x, unsigned int n) {
v = random_utf8_cstring(n);
} else v = random_ascii_cstring(n);
string_replace(x, x, v, -1);
string_replace(x, x, v);
free(v);
}