#ifndef UCX_STRING_H
#define UCX_STRING_H
#include "common.h"
#include "allocator.h"
#define CX_SFMT(s) (
int) (s).length, (s).ptr
#define CX_PRIstr
".*s"
CX_EXPORT extern const unsigned cx_strstr_sbo_size;
struct cx_mutstr_s {
char *ptr;
size_t length;
};
typedef struct cx_mutstr_s cxmutstr;
struct cx_string_s {
const char *ptr;
size_t length;
};
typedef struct cx_string_s cxstring;
struct cx_strtok_ctx_s {
cxstring str;
cxstring delim;
const cxstring *delim_more;
size_t delim_more_count;
size_t pos;
size_t delim_pos;
size_t next_pos;
size_t found;
size_t limit;
};
typedef struct cx_strtok_ctx_s CxStrtokCtx;
#ifdef __cplusplus
extern "C" {
#define CX_STR(literal) cxstring{literal,
sizeof(literal) -
1}
#else
#define CX_STR(literal) ((cxstring){literal,
sizeof(literal) -
1})
#endif
cx_attr_nodiscard cx_attr_cstr_arg(
1)
CX_EXPORT cxmutstr cx_mutstr(
char *cstring);
cx_attr_nodiscard cx_attr_access_rw(
1,
2)
CX_EXPORT cxmutstr cx_mutstrn(
char *cstring,
size_t length);
cx_attr_nodiscard cx_attr_cstr_arg(
1)
CX_EXPORT cxstring cx_str(
const char *cstring);
cx_attr_nodiscard cx_attr_access_r(
1,
2)
CX_EXPORT cxstring cx_strn(
const char *cstring,
size_t length);
#ifdef __cplusplus
}
cx_attr_nodiscard
CX_CPPDECL cxstring cx_strcast(cxmutstr str) {
return cx_strn(str.ptr, str.length);
}
cx_attr_nodiscard
CX_CPPDECL cxstring cx_strcast(cxstring str) {
return str;
}
cx_attr_nodiscard
CX_CPPDECL cxstring cx_strcast(
const char *str) {
return cx_str(str);
}
cx_attr_nodiscard
CX_CPPDECL cxstring cx_strcast(
const unsigned char *str) {
return cx_str(reinterpret_cast<
const char*>(str));
}
extern "C" {
#else
cx_attr_nodiscard
CX_INLINE cxstring cx_strcast_m(cxmutstr str) {
return (cxstring) {str.ptr, str.length};
}
cx_attr_nodiscard
CX_INLINE cxstring cx_strcast_c(cxstring str) {
return str;
}
cx_attr_nodiscard
CX_INLINE cxstring cx_strcast_u(
const unsigned char *str) {
return cx_str((
const char*)str);
}
cx_attr_nodiscard
CX_INLINE cxstring cx_strcast_z(
const char *str) {
return cx_str(str);
}
#define cx_strcast(str) _Generic((str), \
cxmutstr: cx_strcast_m, \
cxstring: cx_strcast_c, \
const unsigned char*: cx_strcast_u, \
unsigned char *: cx_strcast_u, \
const char*: cx_strcast_z, \
char *: cx_strcast_z) (str)
#endif
CX_EXPORT void cx_strfree(cxmutstr *str);
cx_attr_nonnull_arg(
1)
CX_EXPORT void cx_strfree_a(
const CxAllocator *alloc, cxmutstr *str);
cx_attr_nonnull_arg(
1)
CX_EXPORT int cx_strcpy_a(
const CxAllocator *alloc, cxmutstr *dest, cxstring src);
#define cx_strcpy(dest, src) cx_strcpy_a(cxDefaultAllocator, dest, src)
cx_attr_nodiscard
CX_EXPORT size_t cx_strlen(
size_t count, ...);
cx_attr_nodiscard cx_attr_nonnull
CX_EXPORT cxmutstr cx_strcat_ma(
const CxAllocator *alloc,
cxmutstr str,
size_t count, ...);
#define cx_strcat_a(alloc, count, ...) \
cx_strcat_ma(alloc, cx_mutstrn(
NULL,
0), count,
__VA_ARGS__)
#define cx_strcat(count, ...) \
cx_strcat_ma(cxDefaultAllocator, cx_mutstrn(
NULL,
0), count,
__VA_ARGS__)
#define cx_strcat_m(str, count, ...) \
cx_strcat_ma(cxDefaultAllocator, str, count,
__VA_ARGS__)
cx_attr_nodiscard
CX_EXPORT cxstring cx_strsubs(cxstring string,
size_t start);
cx_attr_nodiscard
CX_EXPORT cxstring cx_strsubsl(cxstring string,
size_t start,
size_t length);
cx_attr_nodiscard
CX_EXPORT cxmutstr cx_strsubs_m(cxmutstr string,
size_t start);
cx_attr_nodiscard
CX_EXPORT cxmutstr cx_strsubsl_m(cxmutstr string,
size_t start,
size_t length);
cx_attr_nodiscard
CX_EXPORT cxstring cx_strchr(cxstring string,
int chr);
cx_attr_nodiscard
CX_EXPORT cxmutstr cx_strchr_m(cxmutstr string,
int chr);
cx_attr_nodiscard
CX_EXPORT cxstring cx_strrchr(cxstring string,
int chr);
cx_attr_nodiscard
CX_EXPORT cxmutstr cx_strrchr_m(cxmutstr string,
int chr);
cx_attr_nodiscard
CX_EXPORT cxstring cx_strstr(cxstring haystack, cxstring needle);
cx_attr_nodiscard
CX_EXPORT cxmutstr cx_strstr_m(cxmutstr haystack, cxstring needle);
cx_attr_nodiscard cx_attr_nonnull cx_attr_access_w(
4,
3)
CX_EXPORT size_t cx_strsplit(cxstring string, cxstring delim,
size_t limit, cxstring *output);
cx_attr_nodiscard cx_attr_nonnull cx_attr_access_w(
5)
CX_EXPORT size_t cx_strsplit_a(
const CxAllocator *allocator,
cxstring string, cxstring delim,
size_t limit, cxstring **output);
cx_attr_nodiscard cx_attr_nonnull cx_attr_access_w(
4,
3)
CX_EXPORT size_t cx_strsplit_m(cxmutstr string, cxstring delim,
size_t limit, cxmutstr *output);
cx_attr_nodiscard cx_attr_nonnull cx_attr_access_w(
5)
CX_EXPORT size_t cx_strsplit_ma(
const CxAllocator *allocator,
cxmutstr string, cxstring delim,
size_t limit,
cxmutstr **output);
cx_attr_nodiscard
CX_EXPORT int cx_strcmp_(cxstring s1, cxstring s2);
#define cx_strcmp(s1, s2) cx_strcmp_(cx_strcast(s1), cx_strcast(s2))
cx_attr_nodiscard
CX_EXPORT int cx_strcasecmp_(cxstring s1, cxstring s2);
#define cx_strcasecmp(s1, s2) cx_strcasecmp_(cx_strcast(s1), cx_strcast(s2))
cx_attr_nodiscard cx_attr_nonnull
CX_EXPORT int cx_strcmp_p(
const void *s1,
const void *s2);
cx_attr_nodiscard cx_attr_nonnull
CX_EXPORT int cx_strcasecmp_p(
const void *s1,
const void *s2);
cx_attr_nodiscard cx_attr_nonnull
CX_EXPORT cxmutstr cx_strdup_a_(
const CxAllocator *allocator, cxstring string);
#define cx_strdup_a(allocator, string) cx_strdup_a_((allocator), cx_strcast(string))
#define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string)
cx_attr_nodiscard
CX_EXPORT cxstring cx_strtrim(cxstring string);
cx_attr_nodiscard
CX_EXPORT cxmutstr cx_strtrim_m(cxmutstr string);
cx_attr_nodiscard
CX_EXPORT bool cx_strprefix_(cxstring string, cxstring prefix);
#define cx_strprefix(string, prefix) cx_strprefix_(cx_strcast(string), cx_strcast(prefix))
cx_attr_nodiscard
CX_EXPORT bool cx_strsuffix_(cxstring string, cxstring suffix);
#define cx_strsuffix(string, suffix) cx_strsuffix_(cx_strcast(string), cx_strcast(suffix))
cx_attr_nodiscard
CX_EXPORT bool cx_strcaseprefix_(cxstring string, cxstring prefix);
#define cx_strcaseprefix(string, prefix) cx_strcaseprefix_(cx_strcast(string), cx_strcast(prefix))
cx_attr_nodiscard
CX_EXPORT bool cx_strcasesuffix_(cxstring string, cxstring suffix);
#define cx_strcasesuffix(string, suffix) cx_strcasesuffix_(cx_strcast(string), cx_strcast(suffix))
cx_attr_nodiscard cx_attr_nonnull
CX_EXPORT cxmutstr cx_strreplacen_a(
const CxAllocator *allocator,
cxstring str, cxstring search, cxstring replacement,
size_t replmax);
#define cx_strreplacen(str, search, replacement, replmax) \
cx_strreplacen_a(cxDefaultAllocator, str, search, replacement, replmax)
#define cx_strreplace_a(allocator, str, search, replacement) \
cx_strreplacen_a(allocator, str, search, replacement,
SIZE_MAX)
#define cx_strreplace(str, search, replacement) \
cx_strreplacen_a(cxDefaultAllocator, str, search, replacement,
SIZE_MAX)
cx_attr_nodiscard
CX_EXPORT CxStrtokCtx cx_strtok_(cxstring str, cxstring delim,
size_t limit);
#define cx_strtok(str, delim, limit) \
cx_strtok_(cx_strcast(str), cx_strcast(delim), (limit))
cx_attr_nonnull cx_attr_nodiscard cx_attr_access_w(
2)
CX_EXPORT bool cx_strtok_next(CxStrtokCtx *ctx, cxstring *token);
cx_attr_nonnull cx_attr_nodiscard cx_attr_access_w(
2)
CX_EXPORT bool cx_strtok_next_m(CxStrtokCtx *ctx, cxmutstr *token);
cx_attr_nonnull cx_attr_access_r(
2,
3)
CX_EXPORT void cx_strtok_delim(CxStrtokCtx *ctx,
const cxstring *delim,
size_t count);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtos_lc_(cxstring str,
short *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtoi_lc_(cxstring str,
int *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtol_lc_(cxstring str,
long *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtoll_lc_(cxstring str,
long long *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtoi8_lc_(cxstring str,
int8_t *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtoi16_lc_(cxstring str,
int16_t *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtoi32_lc_(cxstring str,
int32_t *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtoi64_lc_(cxstring str,
int64_t *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtous_lc_(cxstring str,
unsigned short *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtou_lc_(cxstring str,
unsigned int *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtoul_lc_(cxstring str,
unsigned long *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtoull_lc_(cxstring str,
unsigned long long *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtou8_lc_(cxstring str,
uint8_t *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtou16_lc_(cxstring str,
uint16_t *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtou32_lc_(cxstring str,
uint32_t *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtou64_lc_(cxstring str,
uint64_t *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtoz_lc_(cxstring str,
size_t *output,
int base,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtof_lc_(cxstring str,
float *output,
char decsep,
const char *groupsep);
cx_attr_access_w(
2) cx_attr_nonnull_arg(
2)
CX_EXPORT int cx_strtod_lc_(cxstring str,
double *output,
char decsep,
const char *groupsep);
#define cx_strtos_lc(str, output, base, groupsep) cx_strtos_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtoi_lc(str, output, base, groupsep) cx_strtoi_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtol_lc(str, output, base, groupsep) cx_strtol_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtoll_lc(str, output, base, groupsep) cx_strtoll_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtoi8_lc(str, output, base, groupsep) cx_strtoi8_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtoi16_lc(str, output, base, groupsep) cx_strtoi16_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtoi32_lc(str, output, base, groupsep) cx_strtoi32_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtoi64_lc(str, output, base, groupsep) cx_strtoi64_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtous_lc(str, output, base, groupsep) cx_strtous_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtou_lc(str, output, base, groupsep) cx_strtou_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtoul_lc(str, output, base, groupsep) cx_strtoul_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtoull_lc(str, output, base, groupsep) cx_strtoull_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtou8_lc(str, output, base, groupsep) cx_strtou8_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtou16_lc(str, output, base, groupsep) cx_strtou16_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtou32_lc(str, output, base, groupsep) cx_strtou32_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtou64_lc(str, output, base, groupsep) cx_strtou64_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtoz_lc(str, output, base, groupsep) cx_strtoz_lc_(cx_strcast(str), output, base, groupsep)
#define cx_strtos(str, output, base) cx_strtos_lc_(cx_strcast(str), output, base,
",")
#define cx_strtoi(str, output, base) cx_strtoi_lc_(cx_strcast(str), output, base,
",")
#define cx_strtol(str, output, base) cx_strtol_lc_(cx_strcast(str), output, base,
",")
#define cx_strtoll(str, output, base) cx_strtoll_lc_(cx_strcast(str), output, base,
",")
#define cx_strtoi8(str, output, base) cx_strtoi8_lc_(cx_strcast(str), output, base,
",")
#define cx_strtoi16(str, output, base) cx_strtoi16_lc_(cx_strcast(str), output, base,
",")
#define cx_strtoi32(str, output, base) cx_strtoi32_lc_(cx_strcast(str), output, base,
",")
#define cx_strtoi64(str, output, base) cx_strtoi64_lc_(cx_strcast(str), output, base,
",")
#define cx_strtoz(str, output, base) cx_strtoz_lc_(cx_strcast(str), output, base,
",")
#define cx_strtous(str, output, base) cx_strtous_lc_(cx_strcast(str), output, base,
",")
#define cx_strtou(str, output, base) cx_strtou_lc_(cx_strcast(str), output, base,
",")
#define cx_strtoul(str, output, base) cx_strtoul_lc_(cx_strcast(str), output, base,
",")
#define cx_strtoull(str, output, base) cx_strtoull_lc_(cx_strcast(str), output, base,
",")
#define cx_strtou8(str, output, base) cx_strtou8_lc_(cx_strcast(str), output, base,
",")
#define cx_strtou16(str, output, base) cx_strtou16_lc_(cx_strcast(str), output, base,
",")
#define cx_strtou32(str, output, base) cx_strtou32_lc_(cx_strcast(str), output, base,
",")
#define cx_strtou64(str, output, base) cx_strtou64_lc_(cx_strcast(str), output, base,
",")
#define cx_strtof_lc(str, output, decsep, groupsep) cx_strtof_lc_(cx_strcast(str), output, decsep, groupsep)
#define cx_strtod_lc(str, output, decsep, groupsep) cx_strtod_lc_(cx_strcast(str), output, decsep, groupsep)
#define cx_strtof(str, output) cx_strtof_lc_(cx_strcast(str), output,
'.',
",")
#define cx_strtod(str, output) cx_strtod_lc_(cx_strcast(str), output,
'.',
",")
#ifdef __cplusplus
}
#endif
#endif