#ifndef UCX_STRING_H
#define UCX_STRING_H
#include "common.h"
#include "allocator.h"
extern unsigned const 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
__attribute__((__warn_unused_result__, __nonnull__))
cxmutstr cx_mutstr(
char *cstring);
__attribute__((__warn_unused_result__))
cxmutstr cx_mutstrn(
char *cstring,
size_t length
);
__attribute__((__warn_unused_result__, __nonnull__))
cxstring cx_str(
const char *cstring);
__attribute__((__warn_unused_result__))
cxstring cx_strn(
const char *cstring,
size_t length
);
__attribute__((__warn_unused_result__))
cxstring cx_strcast(cxmutstr str);
__attribute__((__nonnull__))
void cx_strfree(cxmutstr *str);
__attribute__((__nonnull__))
void cx_strfree_a(
const CxAllocator *alloc,
cxmutstr *str
);
__attribute__((__warn_unused_result__))
size_t cx_strlen(
size_t count,
...
);
__attribute__((__warn_unused_result__, __nonnull__))
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__)
__attribute__((__warn_unused_result__))
cxstring cx_strsubs(
cxstring string,
size_t start
);
__attribute__((__warn_unused_result__))
cxstring cx_strsubsl(
cxstring string,
size_t start,
size_t length
);
__attribute__((__warn_unused_result__))
cxmutstr cx_strsubs_m(
cxmutstr string,
size_t start
);
__attribute__((__warn_unused_result__))
cxmutstr cx_strsubsl_m(
cxmutstr string,
size_t start,
size_t length
);
__attribute__((__warn_unused_result__))
cxstring cx_strchr(
cxstring string,
int chr
);
__attribute__((__warn_unused_result__))
cxmutstr cx_strchr_m(
cxmutstr string,
int chr
);
__attribute__((__warn_unused_result__))
cxstring cx_strrchr(
cxstring string,
int chr
);
__attribute__((__warn_unused_result__))
cxmutstr cx_strrchr_m(
cxmutstr string,
int chr
);
__attribute__((__warn_unused_result__))
cxstring cx_strstr(
cxstring haystack,
cxstring needle
);
__attribute__((__warn_unused_result__))
cxmutstr cx_strstr_m(
cxmutstr haystack,
cxstring needle
);
__attribute__((__warn_unused_result__, __nonnull__))
size_t cx_strsplit(
cxstring string,
cxstring delim,
size_t limit,
cxstring *output
);
__attribute__((__warn_unused_result__, __nonnull__))
size_t cx_strsplit_a(
const CxAllocator *allocator,
cxstring string,
cxstring delim,
size_t limit,
cxstring **output
);
__attribute__((__warn_unused_result__, __nonnull__))
size_t cx_strsplit_m(
cxmutstr string,
cxstring delim,
size_t limit,
cxmutstr *output
);
__attribute__((__warn_unused_result__, __nonnull__))
size_t cx_strsplit_ma(
const CxAllocator *allocator,
cxmutstr string,
cxstring delim,
size_t limit,
cxmutstr **output
);
__attribute__((__warn_unused_result__))
int cx_strcmp(
cxstring s1,
cxstring s2
);
__attribute__((__warn_unused_result__))
int cx_strcasecmp(
cxstring s1,
cxstring s2
);
__attribute__((__warn_unused_result__, __nonnull__))
int cx_strcmp_p(
const void *s1,
const void *s2
);
__attribute__((__warn_unused_result__, __nonnull__))
int cx_strcasecmp_p(
const void *s1,
const void *s2
);
__attribute__((__warn_unused_result__, __nonnull__))
cxmutstr cx_strdup_a(
const CxAllocator *allocator,
cxstring string
);
#define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string)
#define cx_strdup_ma(allocator, string) cx_strdup_a(allocator, cx_strcast(string))
#define cx_strdup_m(string) cx_strdup_a(cxDefaultAllocator, cx_strcast(string))
__attribute__((__warn_unused_result__))
cxstring cx_strtrim(cxstring string);
__attribute__((__warn_unused_result__))
cxmutstr cx_strtrim_m(cxmutstr string);
__attribute__((__warn_unused_result__))
bool cx_strprefix(
cxstring string,
cxstring prefix
);
__attribute__((__warn_unused_result__))
bool cx_strsuffix(
cxstring string,
cxstring suffix
);
__attribute__((__warn_unused_result__))
bool cx_strcaseprefix(
cxstring string,
cxstring prefix
);
__attribute__((__warn_unused_result__))
bool cx_strcasesuffix(
cxstring string,
cxstring suffix
);
void cx_strlower(cxmutstr string);
void cx_strupper(cxmutstr string);
__attribute__((__warn_unused_result__, __nonnull__))
cxmutstr cx_strreplacen_a(
const CxAllocator *allocator,
cxstring str,
cxstring pattern,
cxstring replacement,
size_t replmax
);
#define cx_strreplacen(str, pattern, replacement, replmax) \
cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, replmax)
#define cx_strreplace_a(allocator, str, pattern, replacement) \
cx_strreplacen_a(allocator, str, pattern, replacement,
SIZE_MAX)
#define cx_strreplace(str, pattern, replacement) \
cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement,
SIZE_MAX)
__attribute__((__warn_unused_result__))
CxStrtokCtx cx_strtok(
cxstring str,
cxstring delim,
size_t limit
);
__attribute__((__warn_unused_result__))
CxStrtokCtx cx_strtok_m(
cxmutstr str,
cxstring delim,
size_t limit
);
__attribute__((__warn_unused_result__, __nonnull__))
bool cx_strtok_next(
CxStrtokCtx *ctx,
cxstring *token
);
__attribute__((__warn_unused_result__, __nonnull__))
bool cx_strtok_next_m(
CxStrtokCtx *ctx,
cxmutstr *token
);
__attribute__((__nonnull__))
void cx_strtok_delim(
CxStrtokCtx *ctx,
const cxstring *delim,
size_t count
);
#ifdef __cplusplus
}
#endif
#endif