Add string
This commit is contained in:
parent
4c3af1db79
commit
540d71ee3c
27
include/extra/string.h
Normal file
27
include/extra/string.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* This software is licensed by the MIT License, see LICENSE file */
|
||||||
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
|
#include "../string.h"
|
||||||
|
|
||||||
|
#ifndef LIBCDSB_EXTRA_STRING_H
|
||||||
|
#define LIBCDSB_EXTRA_STRING_H
|
||||||
|
|
||||||
|
#define string_split(x, sep, maxn) _LIBCDSB_GenericS(libcdsb_string, split, sep)(x, sep, maxn)
|
||||||
|
#define string_case_compare string_compare_case_insensitive
|
||||||
|
|
||||||
|
extern size_t string_to_lower (vtype_string* x) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
extern size_t string_to_upper (vtype_string* x) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
extern size_t string_capitalize(vtype_string* x) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
|
||||||
|
|
||||||
|
extern int string_compare_case_insensitive(const vtype_string* s0, const vtype_string* s1) LIBCDSB_cmpattr__;
|
||||||
|
|
||||||
|
inline vtype_array libcdsb_string_split_string (const vtype_string* x, const vtype_string* sep, size_t maxn) __attribute__((always_inline));
|
||||||
|
extern vtype_array libcdsb_string_split_cstring(const vtype_string* string, const char* sep, size_t maxn) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
extern vtype_array libcdsb_string_split_char (const vtype_string* string, int chr, size_t maxn) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
|
||||||
|
inline vtype_array libcdsb_string_split_string(const vtype_string* x, const vtype_string* sep, size_t maxn) {
|
||||||
|
return string_split(x, sep->buffer, maxn);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* LIBCDSB_EXTRA_STRING_H */
|
114
include/string.h
Normal file
114
include/string.h
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/* This software is licensed by the MIT License, see LICENSE file */
|
||||||
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
|
#include "__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) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
|
||||||
|
extern char* string_at(const vtype_string* s, ssize_t index) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
extern _Bool string_slice(vtype_string* x, vtype_string* s, ssize_t index, size_t nchars, _Bool cut) LIBCDSB_nt__ LIBCDSB_nn12__;
|
||||||
|
|
||||||
|
|
||||||
|
#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(s, value) _LIBCDSB_GenericS(libcdsb_string, concat, value)(s, value)
|
||||||
|
|
||||||
|
|
||||||
|
#define string_trim(x, arg) _LIBCDSB_GenericS(libcdsb_string, trim, arg)(x, arg)
|
||||||
|
#define string_ltrim(x, arg) _LIBCDSB_GenericS(libcdsb_string, ltrim, arg)(x, arg)
|
||||||
|
#define string_rtrim(x, arg) _LIBCDSB_GenericS(libcdsb_string, rtrim, arg)(x, arg)
|
||||||
|
|
||||||
|
#define string_replace(x, src, dest, maxn) _LIBCDSB_GenericS2(libcdsb_string, replace, src, dest)(x, src, dest, maxn)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline ssize_t libcdsb_string_indexof_string (const vtype_string* s, const vtype_string* arg) __attribute__((always_inline));
|
||||||
|
extern ssize_t libcdsb_string_indexof_cstring(const vtype_string* s, const char* arg) LIBCDSB_pure__ LIBCDSB_nn1__;
|
||||||
|
extern ssize_t libcdsb_string_indexof_char (const vtype_string* s, int arg) LIBCDSB_pure__ LIBCDSB_nn1__;
|
||||||
|
|
||||||
|
inline size_t libcdsb_string_count_string (const vtype_string* s, const vtype_string* arg) __attribute__((always_inline));
|
||||||
|
extern size_t libcdsb_string_count_cstring(const vtype_string* s, const char* arg) LIBCDSB_pure__ LIBCDSB_nn1__;
|
||||||
|
extern size_t libcdsb_string_count_char (const vtype_string* s, int arg) LIBCDSB_pure__ LIBCDSB_nn1__;
|
||||||
|
|
||||||
|
inline _Bool libcdsb_string_concat_string (vtype_string* x, const vtype_string* value) __attribute__((always_inline));
|
||||||
|
extern _Bool libcdsb_string_concat_cstring(vtype_string* x, const char* value) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
extern _Bool libcdsb_string_concat_char (vtype_string* x, int value) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
|
||||||
|
inline void libcdsb_string_trim_string (vtype_string* x, const vtype_string* arg) __attribute__((always_inline));
|
||||||
|
extern void libcdsb_string_trim_cstring (vtype_string* x, const char* arg) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
extern void libcdsb_string_trim_char (vtype_string* x, int arg) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
|
||||||
|
inline void libcdsb_string_ltrim_string (vtype_string* x, const vtype_string* arg) __attribute__((always_inline));
|
||||||
|
extern void libcdsb_string_ltrim_cstring(vtype_string* x, const char* arg) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
extern void libcdsb_string_ltrim_char (vtype_string* x, int arg) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
|
||||||
|
inline void libcdsb_string_rtrim_string (vtype_string* x, const vtype_string* arg) __attribute__((always_inline));
|
||||||
|
extern void libcdsb_string_rtrim_cstring(vtype_string* x, const char* arg) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
extern void libcdsb_string_rtrim_char (vtype_string* x, int arg) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
|
||||||
|
|
||||||
|
inline size_t libcdsb_string_replace_string_string (vtype_string* x, const vtype_string* src, const vtype_string* dest, size_t maxn) __attribute__((always_inline));
|
||||||
|
inline size_t libcdsb_string_replace_string_cstring (vtype_string* x, const vtype_string* src, const char* dest, size_t maxn) __attribute__((always_inline));
|
||||||
|
inline size_t libcdsb_string_replace_string_char (vtype_string* x, const vtype_string* src, int dest, size_t maxn) __attribute__((always_inline));
|
||||||
|
inline size_t libcdsb_string_replace_cstring_string (vtype_string* x, const char* src, const vtype_string* dest, size_t maxn) __attribute__((always_inline));
|
||||||
|
extern size_t libcdsb_string_replace_cstring_cstring(vtype_string* string, const char* src, const char* dest, size_t maxn) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
extern size_t libcdsb_string_replace_cstring_char (vtype_string* string, const char* src, int dest, size_t maxn) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
inline size_t libcdsb_string_replace_char_string (vtype_string* x, int src, const vtype_string* dest, size_t maxn) __attribute__((always_inline));
|
||||||
|
extern size_t libcdsb_string_replace_char_cstring (vtype_string* string, int src, const char* dest, size_t maxn) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
extern size_t libcdsb_string_replace_char_char (vtype_string* string, int src, int dest, size_t maxn) LIBCDSB_nt__ LIBCDSB_nn1__;
|
||||||
|
|
||||||
|
|
||||||
|
inline ssize_t libcdsb_string_indexof_string(const vtype_string* s, const vtype_string* arg) {
|
||||||
|
return string_indexof(s, arg->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t libcdsb_string_count_string(const vtype_string* s, const vtype_string* arg) {
|
||||||
|
return string_count(s, arg->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline _Bool libcdsb_string_concat_string(vtype_string* x, const vtype_string* s) {
|
||||||
|
return string_concat(x, s->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void libcdsb_string_trim_string (vtype_string* x, const vtype_string* s) {
|
||||||
|
return string_trim (x, s->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void libcdsb_string_ltrim_string (vtype_string* x, const vtype_string* s) {
|
||||||
|
return string_ltrim(x, s->buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void libcdsb_string_rtrim_string (vtype_string* x, const vtype_string* s) {
|
||||||
|
return string_rtrim(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 */
|
126
src/string/base.c
Normal file
126
src/string/base.c
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/* This software is licensed by the MIT License, see LICENSE file */
|
||||||
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
|
#include "include.h"
|
||||||
|
|
||||||
|
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 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 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));
|
||||||
|
}
|
89
src/string/extra-split.c
Normal file
89
src/string/extra-split.c
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/* This software is licensed by the MIT License, see LICENSE file */
|
||||||
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
|
#include "include.h"
|
||||||
|
|
||||||
|
arr_t 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 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;
|
||||||
|
}
|
177
src/string/extra.c
Normal file
177
src/string/extra.c
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/* This software is licensed by the MIT License, see LICENSE file */
|
||||||
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "include.h"
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*#####################################################################################################################*/
|
||||||
|
|
||||||
|
|
||||||
|
size_t string_to_lower(str_t* x) {
|
||||||
|
|
||||||
|
char ps[4];
|
||||||
|
char *es, *p, *e;
|
||||||
|
u32_t uc0, uc1;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
if (is_null(x->buffer) || !*x->buffer)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
p = x->buffer;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
e = (char*)fromchar_unicode(&uc0, p);
|
||||||
|
|
||||||
|
if (!is_null(e)) {
|
||||||
|
if (!uc0) break;
|
||||||
|
|
||||||
|
if (uc0 != (uc1 = tolower_unicode(uc0))) {
|
||||||
|
es = tochar_unicode(ps, uc1);
|
||||||
|
|
||||||
|
if (!is_null(es)) {
|
||||||
|
string_replace(x, p, e-p, ps, es-ps);
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = e;
|
||||||
|
} else ++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t string_to_upper(str_t* x) {
|
||||||
|
|
||||||
|
char ps[4];
|
||||||
|
char *es, *p, *e;
|
||||||
|
u32_t uc0, uc1;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
if (is_null(x->buffer) || !*x->buffer)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
p = x->buffer;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
e = (char*)fromchar_unicode(&uc0, p);
|
||||||
|
|
||||||
|
if (!is_null(e)) {
|
||||||
|
if (!uc0) break;
|
||||||
|
|
||||||
|
if (uc0 != (uc1 = toupper_unicode(uc0))) {
|
||||||
|
es = tochar_unicode(ps, uc1);
|
||||||
|
|
||||||
|
if (!is_null(es)) {
|
||||||
|
string_replace(x, p, e-p, ps, es-ps);
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = e;
|
||||||
|
} else ++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t string_capitalize(str_t* x) {
|
||||||
|
|
||||||
|
char ps[4];
|
||||||
|
char *es, *p, *e;
|
||||||
|
u32_t uc0, uc1;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
if (is_null(x->buffer) || !*x->buffer)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
p = x->buffer;
|
||||||
|
e = (char*)fromchar_unicode(&uc0, p);
|
||||||
|
|
||||||
|
if (!is_null(e)) {
|
||||||
|
if (!uc0) return 0;
|
||||||
|
|
||||||
|
if (uc0 != (uc1 = toupper_unicode(uc0))) {
|
||||||
|
es = tochar_unicode(ps, uc1);
|
||||||
|
|
||||||
|
if (!is_null(es)) {
|
||||||
|
string_replace(x, p, e-p, ps, es-ps);
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = e;
|
||||||
|
} else ++p;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
e = (char*)fromchar_unicode(&uc0, p);
|
||||||
|
|
||||||
|
if (!is_null(e)) {
|
||||||
|
if (!uc0) break;
|
||||||
|
|
||||||
|
if (uc0 != (uc1 = tolower_unicode(uc0))) {
|
||||||
|
es = tochar_unicode(ps, uc1);
|
||||||
|
|
||||||
|
if (!is_null(es)) {
|
||||||
|
string_replace(x, p, e-p, ps, es-ps);
|
||||||
|
++n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p = e;
|
||||||
|
} else ++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
172
src/string/get.c
Normal file
172
src/string/get.c
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_Bool string_slice(str_t* x, str_t* s, ssize_t i, size_t c, _Bool cut) {
|
||||||
|
char *e, *p, *v;
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
memset(x, 0, sizeof(*x));
|
||||||
|
|
||||||
|
if (!c) return true;
|
||||||
|
|
||||||
|
p = string_at(s, i);
|
||||||
|
|
||||||
|
if (is_null(p) || (e = p + strlen(p)) > p + c)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
v = p;
|
||||||
|
|
||||||
|
do { v = next_char(v); } while (--c && v < e);
|
||||||
|
|
||||||
|
if (!c) {
|
||||||
|
x->buffer = strndup(p, v - p);
|
||||||
|
|
||||||
|
if (cut) {
|
||||||
|
memmove(p, v, strlen(v) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*#####################################################################################################################*/
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t 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 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 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 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;
|
||||||
|
}
|
59
src/string/include.h
Normal file
59
src/string/include.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/* This software is licensed by the MIT License, see LICENSE file */
|
||||||
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
|
#include "../../modules/libunic/include.h"
|
||||||
|
#include "../../include/extra/string.h"
|
||||||
|
#include "../__internal/include.h"
|
||||||
|
|
||||||
|
#ifndef LIBCDSB_SRC_STRING_INCLUDE_H
|
||||||
|
#define LIBCDSB_SRC_STRING_INCLUDE_H
|
||||||
|
|
||||||
|
ainline(char* next_char(char* s)) {
|
||||||
|
int cs = charsize(s);
|
||||||
|
|
||||||
|
if (cs) return s + cs;
|
||||||
|
return ++s;
|
||||||
|
}
|
||||||
|
|
||||||
|
ainline(char* prev_char(char* s)) {
|
||||||
|
|
||||||
|
if (*(--s)&0x80) {
|
||||||
|
char* p = s;
|
||||||
|
|
||||||
|
while ((*(--p)&0xc0) == 0x80) {}
|
||||||
|
|
||||||
|
if (charsize(p) == s - p)
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void libcdsb_string_replace(str_t* x, char* p, size_t n, const char* v, size_t vn);
|
||||||
|
|
||||||
|
#ifdef string_replace
|
||||||
|
#undef string_replace
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define string_replace libcdsb_string_replace
|
||||||
|
#define string_indexof_cstring libcdsb_string_indexof_cstring
|
||||||
|
#define string_indexof_char libcdsb_string_indexof_char
|
||||||
|
#define string_count_cstring libcdsb_string_count_cstring
|
||||||
|
#define string_count_char libcdsb_string_count_char
|
||||||
|
#define string_concat_cstring libcdsb_string_concat_cstring
|
||||||
|
#define string_concat_char libcdsb_string_concat_char
|
||||||
|
#define string_trim_cstring libcdsb_string_trim_cstring
|
||||||
|
#define string_trim_char libcdsb_string_trim_char
|
||||||
|
#define string_ltrim_cstring libcdsb_string_ltrim_cstring
|
||||||
|
#define string_ltrim_char libcdsb_string_ltrim_char
|
||||||
|
#define string_rtrim_cstring libcdsb_string_rtrim_cstring
|
||||||
|
#define string_rtrim_char libcdsb_string_rtrim_char
|
||||||
|
#define string_replace_cstring_cstring libcdsb_string_replace_cstring_cstring
|
||||||
|
#define string_replace_cstring_char libcdsb_string_replace_cstring_char
|
||||||
|
#define string_replace_char_cstring libcdsb_string_replace_char_cstring
|
||||||
|
#define string_replace_char_char libcdsb_string_replace_char_char
|
||||||
|
#define string_split_string libcdsb_string_split_string
|
||||||
|
#define string_split_cstring libcdsb_string_split_cstring
|
||||||
|
#define string_split_char libcdsb_string_split_char
|
||||||
|
|
||||||
|
#endif /* LIBCDSB_SRC_STRING_INCLUDE_H */
|
21
src/string/internal.c
Normal file
21
src/string/internal.c
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/* This software is licensed by the MIT License, see LICENSE file */
|
||||||
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
|
#include "include.h"
|
||||||
|
|
||||||
|
void 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);
|
||||||
|
}
|
105
src/string/replace.c
Normal file
105
src/string/replace.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/* This software is licensed by the MIT License, see LICENSE file */
|
||||||
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
|
#include "include.h"
|
||||||
|
|
||||||
|
size_t string_replace_cstring_cstring(str_t* x, const char* a, const char* d, size_t maxn) {
|
||||||
|
char* 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))) {
|
||||||
|
string_replace(x, p, an, d, dn);
|
||||||
|
p += an;
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t string_replace_cstring_char(str_t* x, const char* a, int dc, size_t maxn) {
|
||||||
|
char* 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))) {
|
||||||
|
string_replace(x, p, an, d, dn);
|
||||||
|
p += an;
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t string_replace_char_cstring(str_t* x, int ac, const char* d, size_t maxn) {
|
||||||
|
char* 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))) {
|
||||||
|
string_replace(x, p, an, d, dn);
|
||||||
|
p += an;
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t 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))) {
|
||||||
|
string_replace(x, p, an, d, dn);
|
||||||
|
p += an;
|
||||||
|
++c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
259
src/string/trim.c
Normal file
259
src/string/trim.c
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
/* This software is licensed by the MIT License, see LICENSE file */
|
||||||
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
|
#include "include.h"
|
||||||
|
|
||||||
|
/*#####################################################################################################################*/
|
||||||
|
|
||||||
|
typedef struct trim_handler {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
size_t pad;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
const char* ptr;
|
||||||
|
size_t len;
|
||||||
|
} *values;
|
||||||
|
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
#ifndef STRING_TRIM_MEMOPT
|
||||||
|
u8_t x[128];
|
||||||
|
#else
|
||||||
|
size_t x[(16/sizeof(size_t))];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
} th_t;
|
||||||
|
|
||||||
|
/*#####################################################################################################################*/
|
||||||
|
|
||||||
|
static void th_init(th_t* x, const char* s) {
|
||||||
|
size_t n = (!is_null(s)) ? strlen(s) : 0;
|
||||||
|
|
||||||
|
memset(x, 0, sizeof(*x));
|
||||||
|
|
||||||
|
if (n && n == strasciilen(s)) {
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
#ifndef STRING_TRIM_MEMOPT
|
||||||
|
x->x[s[i]] = 1;
|
||||||
|
#else
|
||||||
|
x->x[s[i]/(8*sizeof(size_t))] |= (size_t)1<<(s[i]%(8*sizeof(size_t)));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else if (n) {
|
||||||
|
x->pad = (size_t)-1;
|
||||||
|
do {
|
||||||
|
if ((n = charsize(s))) {
|
||||||
|
|
||||||
|
x->values = realloc(x->values, sizeof(*x->values)*x->size + 1);
|
||||||
|
x->values[x->size].len = n;
|
||||||
|
x->values[x->size].ptr = s;
|
||||||
|
|
||||||
|
++x->size;
|
||||||
|
s += n;
|
||||||
|
s += n;
|
||||||
|
} else ++s;
|
||||||
|
} while (*s);
|
||||||
|
} else {
|
||||||
|
#ifndef STRING_TRIM_MEMOPT
|
||||||
|
x->x[ ' '] = 1;
|
||||||
|
x->x['\r'] = 1;
|
||||||
|
x->x['\n'] = 1;
|
||||||
|
x->x['\t'] = 1;
|
||||||
|
x->x['\v'] = 1;
|
||||||
|
#else
|
||||||
|
x->x[ ' '/(8*sizeof(size_t))] |= (size_t)1<<( ' '%(8*sizeof(size_t)));
|
||||||
|
x->x['\r'/(8*sizeof(size_t))] |= (size_t)1<<('\r'%(8*sizeof(size_t)));
|
||||||
|
x->x['\n'/(8*sizeof(size_t))] |= (size_t)1<<('\n'%(8*sizeof(size_t)));
|
||||||
|
x->x['\t'/(8*sizeof(size_t))] |= (size_t)1<<('\t'%(8*sizeof(size_t)));
|
||||||
|
x->x['\v'/(8*sizeof(size_t))] |= (size_t)1<<('\v'%(8*sizeof(size_t)));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void th_free(th_t* x) {
|
||||||
|
if (x->pad == (size_t)-1) {
|
||||||
|
free(x->values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static char* th_next(const th_t* x, char* s) {
|
||||||
|
|
||||||
|
if (!(x->pad != (size_t)-1) && *(u8_t*)s <= 0x7f) {
|
||||||
|
#ifndef STRING_TRIM_MEMOPT
|
||||||
|
if (x->x[*(u8_t*)s]) {
|
||||||
|
#else
|
||||||
|
if (x->x[(*(u8_t*)s)/(8*sizeof(size_t))] & ((size_t)1<<((*(u8_t*)s)%(8*sizeof(size_t))))) {
|
||||||
|
#endif
|
||||||
|
return ++s;
|
||||||
|
}
|
||||||
|
} else for (int i = 0; i < x->size; ++i) {
|
||||||
|
if (memcmp(x->values[i].ptr, s, x->values[i].len) == 0) {
|
||||||
|
return s + x->values[i].len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static char* th_prev(const th_t* x, char* s) {
|
||||||
|
|
||||||
|
if (!(x->pad != (size_t)-1) && *(u8_t*)(--s) <= 0x7f) {
|
||||||
|
#ifndef STRING_TRIM_MEMOPT
|
||||||
|
if (x->x[*(u8_t*)s]) {
|
||||||
|
#else
|
||||||
|
if (x->x[(*(u8_t*)s)/(8*sizeof(size_t))] & ((size_t)1<<((*(u8_t*)s)%(8*sizeof(size_t))))) {
|
||||||
|
#endif
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
} else for (int i = 0; i < x->size; ++i) {
|
||||||
|
char* p = s - x->values[i].len;
|
||||||
|
if (memcmp(x->values[i].ptr, p, x->values[i].len) == 0) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*#####################################################################################################################*/
|
||||||
|
|
||||||
|
|
||||||
|
void string_trim_cstring(str_t* x, const char* s) {
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
if (!is_null(x->buffer) && (n = strlen(x->buffer))) {
|
||||||
|
th_t t;
|
||||||
|
char *p0, *p1;
|
||||||
|
|
||||||
|
th_init(&t, s);
|
||||||
|
|
||||||
|
p0 = x->buffer;
|
||||||
|
|
||||||
|
while ((p1 = th_next(&t, p0))) { p0 = p1; }
|
||||||
|
|
||||||
|
n -= p0 - x->buffer;
|
||||||
|
p0 = memmove(x->buffer, p0, n + 1) + n;
|
||||||
|
|
||||||
|
while ((p1 = th_prev(&t, p0))) { p0 = p1; }
|
||||||
|
*p0 = 0;
|
||||||
|
|
||||||
|
th_free(&t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void string_trim_char(str_t* x, int sc) {
|
||||||
|
size_t n;
|
||||||
|
char s[5] = {0};
|
||||||
|
|
||||||
|
if (!is_null(x->buffer) && tochar_unicode(s, sc) && (n = strlen(x->buffer))) {
|
||||||
|
th_t t;
|
||||||
|
char *p0, *p1;
|
||||||
|
|
||||||
|
th_init(&t, s);
|
||||||
|
|
||||||
|
p0 = x->buffer;
|
||||||
|
|
||||||
|
while ((p1 = th_next(&t, p0))) { p0 = p1; }
|
||||||
|
|
||||||
|
n -= p0 - x->buffer;
|
||||||
|
p0 = memmove(x->buffer, p0, n + 1) + n;
|
||||||
|
|
||||||
|
while ((p1 = th_prev(&t, p0))) { p0 = p1; }
|
||||||
|
*p0 = 0;
|
||||||
|
|
||||||
|
th_free(&t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void string_ltrim_cstring(str_t* x, const char* s) {
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
if (!is_null(x->buffer) && (n = strlen(x->buffer))) {
|
||||||
|
th_t t;
|
||||||
|
char *p0, *p1;
|
||||||
|
|
||||||
|
th_init(&t, s);
|
||||||
|
|
||||||
|
p0 = x->buffer;
|
||||||
|
|
||||||
|
while ((p1 = th_next(&t, p0))) { p0 = p1; }
|
||||||
|
|
||||||
|
n -= p0 - x->buffer;
|
||||||
|
|
||||||
|
memmove(x->buffer, p0, ++n);
|
||||||
|
|
||||||
|
th_free(&t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void string_ltrim_char(str_t* x, int sc) {
|
||||||
|
size_t n;
|
||||||
|
char s[5] = {0};
|
||||||
|
|
||||||
|
if (!is_null(x->buffer) && tochar_unicode(s, sc) && (n = strlen(x->buffer))) {
|
||||||
|
th_t t;
|
||||||
|
char *p0, *p1;
|
||||||
|
|
||||||
|
th_init(&t, s);
|
||||||
|
|
||||||
|
p0 = x->buffer;
|
||||||
|
|
||||||
|
while ((p1 = th_next(&t, p0))) { p0 = p1; }
|
||||||
|
|
||||||
|
n -= p0 - x->buffer;
|
||||||
|
|
||||||
|
memmove(x->buffer, p0, ++n);
|
||||||
|
|
||||||
|
th_free(&t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void string_rtrim_cstring(str_t* x, const char* s) {
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
if (!is_null(x->buffer) && (n = strlen(x->buffer))) {
|
||||||
|
th_t t;
|
||||||
|
char *p0, *p1;
|
||||||
|
|
||||||
|
th_init(&t, s);
|
||||||
|
|
||||||
|
p0 = x->buffer + n;
|
||||||
|
|
||||||
|
while ((p1 = th_prev(&t, p0))) { p0 = p1; }
|
||||||
|
*p0 = 0;
|
||||||
|
|
||||||
|
th_free(&t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void string_rtrim_char(str_t* x, int sc) {
|
||||||
|
size_t n;
|
||||||
|
char s[5] = {0};
|
||||||
|
|
||||||
|
if (!is_null(x->buffer) && tochar_unicode(s, sc) && (n = strlen(x->buffer))) {
|
||||||
|
th_t t;
|
||||||
|
char *p0, *p1;
|
||||||
|
|
||||||
|
th_init(&t, s);
|
||||||
|
|
||||||
|
p0 = x->buffer + n;
|
||||||
|
|
||||||
|
while ((p1 = th_prev(&t, p0))) { p0 = p1; }
|
||||||
|
*p0 = 0;
|
||||||
|
|
||||||
|
th_free(&t);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user