Refactor string
This commit is contained in:
parent
205c8337c2
commit
ca8251973e
@ -2,8 +2,8 @@
|
|||||||
/* Copyright © 2022 Gregory Lirent */
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "../include/extra/string.h"
|
#include "../include/array.h"
|
||||||
#include "../include/extra/array.h"
|
#include "../include/string.h"
|
||||||
|
|
||||||
typedef vtype_string str_t;
|
typedef vtype_string str_t;
|
||||||
typedef vtype_array arr_t;
|
typedef vtype_array arr_t;
|
||||||
@ -25,14 +25,14 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
printf("%s\n", str.buffer);
|
printf("%s\n", str.buffer);
|
||||||
|
|
||||||
arr_t parts = string_split(&str, ',', -1);
|
arr_t parts = string_split(&str, ',');
|
||||||
|
|
||||||
printf("%lu\n", array_size(&parts));
|
printf("%lu\n", array_size(&parts));
|
||||||
|
|
||||||
for (size_t i = 0; i < array_size(&parts); ++i) {
|
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));
|
printf("%s (%lu)\n", value->buffer, string_nmemb(value));
|
||||||
}
|
}
|
||||||
|
@ -1,88 +1,48 @@
|
|||||||
/* This software is licensed by the MIT License, see LICENSE file */
|
/* This software is licensed by the MIT License, see LICENSE file */
|
||||||
/* Copyright © 2022 Gregory Lirent */
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
#include "__generics.h"
|
#include "bits/__generics.h"
|
||||||
#include "vtype.h"
|
#include "vtype.h"
|
||||||
#include <uchar.h>
|
|
||||||
|
|
||||||
#ifndef LIBCDSB_STRING_H
|
#ifndef LIBCDSB_STRING_H
|
||||||
#define 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_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)
|
extern char* at_string (const vtype_string* s, ssize_t index) Nonnull__(1);
|
||||||
#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)
|
|
||||||
|
|
||||||
/*#####################################################################################################################*/
|
/*#####################################################################################################################*/
|
||||||
|
|
||||||
inline ssize_t libcdsb_string_indexof_string (const vtype_string* s, const vtype_string* arg) Pure__ Warn_unused_result__ Nonnull__(1) Always_inline__;
|
#define string_init(x, s) libcdsb_string_init (x, _LIBCDSB_to_cstring(s), 0)
|
||||||
extern ssize_t libcdsb_string_indexof_cstring(const vtype_string* s, const char* arg) Pure__ Warn_unused_result__ Nonnull__(1);
|
#define string_indexof(x, s) libcdsb_string_indexof(x, _LIBCDSB_to_cstring(s))
|
||||||
extern ssize_t libcdsb_string_indexof_char (const vtype_string* s, int arg) Pure__ Warn_unused_result__ Nonnull__(1);
|
#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)
|
||||||
inline size_t libcdsb_string_count_string (const vtype_string* s, const vtype_string* arg) Pure__ Warn_unused_result__ Nonnull__(1) Always_inline__;
|
#define string_align(x, n, c) libcdsb_string_align (x, n, c, 0)
|
||||||
extern size_t libcdsb_string_count_cstring(const vtype_string* s, const char* arg) Pure__ Warn_unused_result__ Nonnull__(1);
|
#define string_lalign(x, n, c) libcdsb_string_align (x, n, c, -1)
|
||||||
extern size_t libcdsb_string_count_char (const vtype_string* s, int arg) Pure__ Warn_unused_result__ Nonnull__(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)
|
||||||
inline bool libcdsb_string_concat_string (vtype_string* x, const vtype_string* value) Nonnull__(1) Always_inline__;
|
#define string_trim(x, s) libcdsb_string_trim (x, _LIBCDSB_to_cstring(s), 0)
|
||||||
extern bool libcdsb_string_concat_cstring(vtype_string* x, const char* value) Nonnull__(1);
|
#define string_ltrim(x, s) libcdsb_string_trim (x, _LIBCDSB_to_cstring(s), -1)
|
||||||
extern bool libcdsb_string_concat_char (vtype_string* x, int value) Nonnull__(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)
|
||||||
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);
|
|
||||||
|
|
||||||
/*#####################################################################################################################*/
|
/*#####################################################################################################################*/
|
||||||
|
|
||||||
inline ssize_t libcdsb_string_indexof_string(const vtype_string* s, const vtype_string* arg) {
|
inline void libcdsb_string_init (vtype_string* x, const char* s, size_t nmemb) Always_inline__ Nonnull__(1);
|
||||||
return string_indexof(s, arg->buffer);
|
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) {
|
inline void libcdsb_string_init (vtype_string* x, const char* s, size_t nmemb) { x->buffer = ((nmemb) ? libcdsb_strndup(s, nmemb) : libcdsb_strdup(s)); }
|
||||||
return string_count(s, arg->buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool libcdsb_string_concat_string(vtype_string* x, const vtype_string* s) {
|
#endif /* LIBCDSB_STRING_H */
|
||||||
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 */
|
|
||||||
|
61
src/string/access.c
Normal file
61
src/string/access.c
Normal 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;
|
||||||
|
}
|
@ -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
66
src/string/comparison.c
Normal 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
60
src/string/compute.c
Normal 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
78
src/string/copy.c
Normal 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;
|
||||||
|
}
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
174
src/string/get.c
174
src/string/get.c
@ -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;
|
|
||||||
}
|
|
@ -2,7 +2,7 @@
|
|||||||
/* Copyright © 2022 Gregory Lirent */
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
#include "../../modules/libunic/include.h"
|
#include "../../modules/libunic/include.h"
|
||||||
#include "../../include/extra/string.h"
|
#include "../../include/string.h"
|
||||||
#include "../__internal/include.h"
|
#include "../__internal/include.h"
|
||||||
|
|
||||||
#ifndef LIBCDSB_SRC_STRING_INCLUDE_H
|
#ifndef LIBCDSB_SRC_STRING_INCLUDE_H
|
||||||
|
275
src/string/modify.c
Normal file
275
src/string/modify.c
Normal 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;
|
||||||
|
}
|
@ -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;
|
|
||||||
}
|
|
@ -1,60 +1,59 @@
|
|||||||
/* This software is licensed by the MIT License, see LICENSE file */
|
/* This software is licensed by the MIT License, see LICENSE file */
|
||||||
/* Copyright © 2022 Gregory Lirent */
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include "include.h"
|
#include "include.h"
|
||||||
|
|
||||||
int string_compare_case_insensitive(const str_t* s0, const str_t* s1) {
|
static void string_replace_builtin(str_t* x, char* p, size_t n, const char* v, size_t vn) {
|
||||||
const char *p0, *p1, *t0, *t1;
|
if (n != vn) {
|
||||||
ssize_t n0, n1;
|
size_t l = strlen(x->buffer);
|
||||||
u32_t uc0, uc1;
|
|
||||||
|
|
||||||
if (s0 == s1) return 0;
|
if (n < vn) {
|
||||||
|
char* t = x->buffer;
|
||||||
|
|
||||||
p0 = s0->buffer;
|
x->buffer = realloc(x->buffer, l + (vn - n) + 1);
|
||||||
p1 = s1->buffer;
|
p = x->buffer + (p - t);
|
||||||
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;
|
memmove(p+vn, p+n, l - (p+n - x->buffer) + 1);
|
||||||
|
|
||||||
return n0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
size_t string_to_lower(str_t* x) {
|
||||||
|
|
||||||
char ps[4];
|
char ps[4];
|
||||||
char *es, *p, *e;
|
char *es, *p, *e;
|
||||||
u32_t uc0, uc1;
|
u32_t uc0, uc1;
|
||||||
@ -76,7 +75,7 @@ size_t string_to_lower(str_t* x) {
|
|||||||
es = tochar_unicode(ps, uc1);
|
es = tochar_unicode(ps, uc1);
|
||||||
|
|
||||||
if (!is_null(es)) {
|
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;
|
++n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,7 +111,7 @@ size_t string_to_upper(str_t* x) {
|
|||||||
es = tochar_unicode(ps, uc1);
|
es = tochar_unicode(ps, uc1);
|
||||||
|
|
||||||
if (!is_null(es)) {
|
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;
|
++n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,7 +145,7 @@ size_t string_capitalize(str_t* x) {
|
|||||||
es = tochar_unicode(ps, uc1);
|
es = tochar_unicode(ps, uc1);
|
||||||
|
|
||||||
if (!is_null(es)) {
|
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;
|
++n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,7 +163,7 @@ size_t string_capitalize(str_t* x) {
|
|||||||
es = tochar_unicode(ps, uc1);
|
es = tochar_unicode(ps, uc1);
|
||||||
|
|
||||||
if (!is_null(es)) {
|
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;
|
++n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,56 +174,3 @@ size_t string_capitalize(str_t* x) {
|
|||||||
|
|
||||||
return n;
|
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);
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -2,7 +2,7 @@
|
|||||||
/* Copyright © 2022 Gregory Lirent */
|
/* Copyright © 2022 Gregory Lirent */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "../../include/extra/vtype.h"
|
#include "../../include/vtype.h"
|
||||||
|
|
||||||
#ifndef LIBCDSB_TESTS_TEST_H
|
#ifndef LIBCDSB_TESTS_TEST_H
|
||||||
#define LIBCDSB_TESTS_TEST_H
|
#define LIBCDSB_TESTS_TEST_H
|
||||||
|
@ -18,10 +18,10 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
char* repl = random_utf8_cstring(30);
|
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*)&hack, "(part 2)");
|
||||||
string_print((void*)&repl, "(part 2 replaced)");
|
string_print((void*)&repl, "(part 2 replaced)");
|
||||||
string_replace(&x, hack, repl, -1);
|
string_replace(&x, hack, repl);
|
||||||
free(repl);
|
free(repl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,16 +54,16 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
x = string_random(12);
|
x = string_random(12);
|
||||||
|
|
||||||
string_align_center(&x, 30, 0);
|
string_align(&x, 30, 0);
|
||||||
string_info(&x);
|
string_info(&x);
|
||||||
string_print(&x, 0);
|
string_print(&x, 0);
|
||||||
|
|
||||||
string_trim_spaces(&x);
|
string_trim(&x, 0);
|
||||||
string_info(&x);
|
string_info(&x);
|
||||||
string_print(&x, "trimmed");
|
string_print(&x, "trimmed");
|
||||||
|
|
||||||
put_separator(0);
|
put_separator(0);
|
||||||
string_align_center(&x, 30, c);
|
string_align(&x, 30, c);
|
||||||
string_info(&x);
|
string_info(&x);
|
||||||
string_print(&x, 0);
|
string_print(&x, 0);
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "../../../modules/libunic/include.h"
|
#include "../../../modules/libunic/include.h"
|
||||||
#include "../../../include/extra/string.h"
|
#include "../../../include/string.h"
|
||||||
|
|
||||||
#include "../../include/random.h"
|
#include "../../include/random.h"
|
||||||
#include "../../include/test.h"
|
#include "../../include/test.h"
|
||||||
|
@ -45,7 +45,7 @@ void string_replace_random(str_t* x, unsigned int n) {
|
|||||||
v = random_utf8_cstring(n);
|
v = random_utf8_cstring(n);
|
||||||
} else v = random_ascii_cstring(n);
|
} else v = random_ascii_cstring(n);
|
||||||
|
|
||||||
string_replace(x, x, v, -1);
|
string_replace(x, x, v);
|
||||||
|
|
||||||
free(v);
|
free(v);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user