.
This commit is contained in:
parent
01f4ad7f62
commit
6d36aa4442
100 changed files with 5138 additions and 13015 deletions
303
str.h
303
str.h
|
|
@ -1,36 +1,50 @@
|
|||
#pragma once
|
||||
#ifndef COLLA_STR_H
|
||||
#define COLLA_STR_H
|
||||
|
||||
#include <stdarg.h> // va_list
|
||||
#include <string.h> // strlen
|
||||
|
||||
#include "collatypes.h"
|
||||
|
||||
typedef struct arena_t arena_t;
|
||||
#include "core.h"
|
||||
#include "darr.h"
|
||||
|
||||
#define STR_NONE SIZE_MAX
|
||||
|
||||
typedef struct {
|
||||
typedef struct str_t str_t;
|
||||
struct str_t {
|
||||
char *buf;
|
||||
usize len;
|
||||
} str_t;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
typedef struct str16_t str16_t;
|
||||
struct str16_t {
|
||||
u16 *buf;
|
||||
usize len;
|
||||
};
|
||||
|
||||
#if COLLA_UNICODE
|
||||
typedef str16_t tstr_t;
|
||||
#else
|
||||
typedef str_t tstr_t;
|
||||
#endif
|
||||
|
||||
typedef struct strview_t strview_t;
|
||||
struct strview_t {
|
||||
const char *buf;
|
||||
usize len;
|
||||
} strview_t;
|
||||
};
|
||||
|
||||
darr_define(str_list_t, str_t);
|
||||
darr_define(strv_list_t, strview_t);
|
||||
|
||||
// == STR_T ========================================================
|
||||
|
||||
#define str__1(arena, x) \
|
||||
_Generic((x), \
|
||||
const char *: strInit, \
|
||||
char *: strInit, \
|
||||
const wchar_t *: strFromWChar, \
|
||||
wchar_t *: strFromWChar, \
|
||||
strview_t: strInitView \
|
||||
#define str__1(arena, x) \
|
||||
_Generic((x), \
|
||||
const char *: str_init, \
|
||||
char *: str_init, \
|
||||
strview_t: str_init_view \
|
||||
)(arena, x)
|
||||
|
||||
#define str__2(arena, cstr, clen) strInitLen(arena, cstr, clen)
|
||||
#define str__2(arena, cstr, clen) str_init_len(arena, cstr, clen)
|
||||
#define str__impl(_1, _2, n, ...) str__##n
|
||||
|
||||
// either:
|
||||
|
|
@ -40,80 +54,223 @@ typedef struct {
|
|||
|
||||
#define STR_EMPTY (str_t){0}
|
||||
|
||||
str_t strInit(arena_t *arena, const char *buf);
|
||||
str_t strInitLen(arena_t *arena, const char *buf, usize len);
|
||||
str_t strInitView(arena_t *arena, strview_t view);
|
||||
str_t strFmt(arena_t *arena, const char *fmt, ...);
|
||||
str_t strFmtv(arena_t *arena, const char *fmt, va_list args);
|
||||
str_t str_init(arena_t *arena, const char *buf);
|
||||
str_t str_init_len(arena_t *arena, const char *buf, usize len);
|
||||
str_t str_init_view(arena_t *arena, strview_t view);
|
||||
str_t str_fmt(arena_t *arena, const char *fmt, ...);
|
||||
str_t str_fmtv(arena_t *arena, const char *fmt, va_list args);
|
||||
|
||||
str_t strFromWChar(arena_t *arena, const wchar_t *src);
|
||||
str_t strFromWCharLen(arena_t *arena, const wchar_t *src, usize srclen);
|
||||
tstr_t tstr_init(TCHAR *str, usize optional_len);
|
||||
str16_t str16_init(u16 *str, usize optional_len);
|
||||
|
||||
bool strEquals(str_t a, str_t b);
|
||||
int strCompare(str_t a, str_t b);
|
||||
str_t str_from_str16(arena_t *arena, str16_t src);
|
||||
str_t str_from_tstr(arena_t *arena, tstr_t src);
|
||||
str16_t str16_from_str(arena_t *arena, str_t src);
|
||||
|
||||
str_t strDup(arena_t *arena, str_t src);
|
||||
bool strIsEmpty(str_t ctx);
|
||||
bool str_equals(str_t a, str_t b);
|
||||
int str_compare(str_t a, str_t b);
|
||||
|
||||
void strReplace(str_t *ctx, char from, char to);
|
||||
str_t str_dup(arena_t *arena, str_t src);
|
||||
str_t str_cat(arena_t *arena, str_t a, str_t b);
|
||||
bool str_is_empty(str_t ctx);
|
||||
|
||||
void str_lower(str_t *src);
|
||||
void str_upper(str_t *src);
|
||||
|
||||
void str_replace(str_t *ctx, char from, char to);
|
||||
// if len == SIZE_MAX, copies until end
|
||||
strview_t strSub(str_t ctx, usize from, usize to);
|
||||
|
||||
void strLower(str_t *ctx);
|
||||
void strUpper(str_t *ctx);
|
||||
|
||||
str_t strToLower(arena_t *arena, str_t ctx);
|
||||
str_t strToUpper(arena_t *arena, str_t ctx);
|
||||
strview_t str_sub(str_t ctx, usize from, usize to);
|
||||
|
||||
// == STRVIEW_T ====================================================
|
||||
|
||||
#define strv__1(x) \
|
||||
_Generic((x), \
|
||||
char *: strvInit, \
|
||||
const char *: strvInit, \
|
||||
str_t: strvInitStr \
|
||||
)(x)
|
||||
|
||||
#define strv__2(cstr, clen) strvInitLen(cstr, clen)
|
||||
#define strv__impl(_1, _2, n, ...) strv__##n
|
||||
|
||||
#define strv(...) strv__impl(__VA_ARGS__, 2, 1, 0)(__VA_ARGS__)
|
||||
// these macros might be THE worst code ever written, but they work ig
|
||||
// detects if you're trying to create a string view from either:
|
||||
// - a str_t -> calls strv_init_str
|
||||
// - a string literal -> calls strv_init_len with comptime size
|
||||
// - a c string -> calls strv_init with runtime size
|
||||
|
||||
#define STRV_EMPTY (strview_t){0}
|
||||
|
||||
strview_t strvInit(const char *cstr);
|
||||
strview_t strvInitLen(const char *buf, usize size);
|
||||
strview_t strvInitStr(str_t str);
|
||||
// needed for strv__init_literal _Generic implementation, it's never actually called
|
||||
inline strview_t strv__ignore(str_t s, size_t l) {
|
||||
COLLA_UNUSED(s); COLLA_UNUSED(l);
|
||||
return STRV_EMPTY;
|
||||
}
|
||||
|
||||
bool strvIsEmpty(strview_t ctx);
|
||||
bool strvEquals(strview_t a, strview_t b);
|
||||
int strvCompare(strview_t a, strview_t b);
|
||||
#define strv__check(x, ...) ((#x)[0] == '"')
|
||||
#define strv__init_literal(x, ...) \
|
||||
_Generic((x), \
|
||||
char *: strv_init_len, \
|
||||
const char *: strv_init_len, \
|
||||
str_t: strv__ignore \
|
||||
)(x, sizeof(x) - 1)
|
||||
|
||||
char strvFront(strview_t ctx);
|
||||
char strvBack(strview_t ctx);
|
||||
#define strv__1(x) \
|
||||
_Generic((x), \
|
||||
char *: strv_init, \
|
||||
const char *: strv_init, \
|
||||
str_t: strv_init_str \
|
||||
)(x)
|
||||
|
||||
wchar_t *strvToWChar(arena_t *arena, strview_t ctx, usize *outlen);
|
||||
TCHAR *strvToTChar(arena_t *arena, strview_t str);
|
||||
#define strv__2(cstr, clen) strv_init_len(cstr, clen)
|
||||
|
||||
strview_t strvRemovePrefix(strview_t ctx, usize n);
|
||||
strview_t strvRemoveSuffix(strview_t ctx, usize n);
|
||||
strview_t strvTrim(strview_t ctx);
|
||||
strview_t strvTrimLeft(strview_t ctx);
|
||||
strview_t strvTrimRight(strview_t ctx);
|
||||
#define strv__impl(_1, _2, n, ...) strv__##n
|
||||
|
||||
strview_t strvSub(strview_t ctx, usize from, usize to);
|
||||
#define strv(...) strv__check(__VA_ARGS__) ? strv__init_literal(__VA_ARGS__) : strv__impl(__VA_ARGS__, 2, 1, 0)(__VA_ARGS__)
|
||||
|
||||
bool strvStartsWith(strview_t ctx, char c);
|
||||
bool strvStartsWithView(strview_t ctx, strview_t view);
|
||||
strview_t strv_init(const char *cstr);
|
||||
strview_t strv_init_len(const char *buf, usize size);
|
||||
strview_t strv_init_str(str_t str);
|
||||
|
||||
bool strvEndsWith(strview_t ctx, char c);
|
||||
bool strvEndsWithView(strview_t ctx, strview_t view);
|
||||
bool strv_is_empty(strview_t ctx);
|
||||
bool strv_equals(strview_t a, strview_t b);
|
||||
int strv_compare(strview_t a, strview_t b);
|
||||
|
||||
bool strvContains(strview_t ctx, char c);
|
||||
bool strvContainsView(strview_t ctx, strview_t view);
|
||||
char strv_front(strview_t ctx);
|
||||
char strv_back(strview_t ctx);
|
||||
|
||||
usize strvFind(strview_t ctx, char c, usize from);
|
||||
usize strvFindView(strview_t ctx, strview_t view, usize from);
|
||||
str16_t strv_to_str16(arena_t *arena, strview_t src);
|
||||
tstr_t strv_to_tstr(arena_t *arena, strview_t src);
|
||||
|
||||
usize strvRFind(strview_t ctx, char c, usize from_right);
|
||||
usize strvRFindView(strview_t ctx, strview_t view, usize from_right);
|
||||
strview_t strv_remove_prefix(strview_t ctx, usize n);
|
||||
strview_t strv_remove_suffix(strview_t ctx, usize n);
|
||||
strview_t strv_trim(strview_t ctx);
|
||||
strview_t strv_trim_left(strview_t ctx);
|
||||
strview_t strv_trim_right(strview_t ctx);
|
||||
|
||||
strview_t strv_sub(strview_t ctx, usize from, usize to);
|
||||
|
||||
bool strv_starts_with(strview_t ctx, char c);
|
||||
bool strv_starts_with_view(strview_t ctx, strview_t view);
|
||||
|
||||
bool strv_ends_with(strview_t ctx, char c);
|
||||
bool strv_ends_with_view(strview_t ctx, strview_t view);
|
||||
|
||||
bool strv_contains(strview_t ctx, char c);
|
||||
bool strv_contains_view(strview_t ctx, strview_t view);
|
||||
bool strv_contains_either(strview_t ctx, strview_t chars);
|
||||
|
||||
usize strv_find(strview_t ctx, char c, usize from);
|
||||
usize strv_find_view(strview_t ctx, strview_t view, usize from);
|
||||
usize strv_find_either(strview_t ctx, strview_t chars, usize from);
|
||||
|
||||
usize strv_rfind(strview_t ctx, char c, usize from_right);
|
||||
usize strv_rfind_view(strview_t ctx, strview_t view, usize from_right);
|
||||
|
||||
// == CTYPE ========================================================
|
||||
|
||||
bool char_is_space(char c);
|
||||
bool char_is_alpha(char c);
|
||||
bool char_is_num(char c);
|
||||
|
||||
// == INPUT STREAM =================================================
|
||||
|
||||
typedef struct instream_t instream_t;
|
||||
struct instream_t {
|
||||
const char *beg;
|
||||
const char *cur;
|
||||
usize len;
|
||||
};
|
||||
|
||||
instream_t istr_init(strview_t str);
|
||||
|
||||
// get the current character and advance
|
||||
char istr_get(instream_t *ctx);
|
||||
// get the current character but don't advance
|
||||
char istr_peek(instream_t *ctx);
|
||||
// get the next character but don't advance
|
||||
char istr_peek_next(instream_t *ctx);
|
||||
// returns the previous character
|
||||
char istr_prev(instream_t *ctx);
|
||||
// returns the character before the previous
|
||||
char istr_prev_prev(instream_t *ctx);
|
||||
// ignore characters until the delimiter
|
||||
void istr_ignore(instream_t *ctx, char delim);
|
||||
// ignore characters until the delimiter and skip it
|
||||
void istr_ignore_and_skip(instream_t *ctx, char delim);
|
||||
// skip n characters
|
||||
void istr_skip(instream_t *ctx, usize n);
|
||||
// skips whitespace (' ', '\\n', '\\t', '\\r')
|
||||
void istr_skip_whitespace(instream_t *ctx);
|
||||
// returns to the beginning of the stream
|
||||
void istr_rewind(instream_t *ctx);
|
||||
// returns back <amount> characters
|
||||
void istr_rewind_n(instream_t *ctx, usize amount);
|
||||
// returns the number of bytes read from beginning of stream
|
||||
usize istr_tell(instream_t *ctx);
|
||||
// returns the number of bytes left to read in the stream
|
||||
usize istr_remaining(instream_t *ctx);
|
||||
// return true if the stream doesn't have any new bytes to read
|
||||
bool istr_is_finished(instream_t *ctx);
|
||||
|
||||
bool istr_get_bool(instream_t *ctx, bool *val);
|
||||
bool istr_get_u8(instream_t *ctx, u8 *val);
|
||||
bool istr_get_u16(instream_t *ctx, u16 *val);
|
||||
bool istr_get_u32(instream_t *ctx, u32 *val);
|
||||
bool istr_get_u64(instream_t *ctx, u64 *val);
|
||||
bool istr_get_i8(instream_t *ctx, i8 *val);
|
||||
bool istr_get_i16(instream_t *ctx, i16 *val);
|
||||
bool istr_get_i32(instream_t *ctx, i32 *val);
|
||||
bool istr_get_i64(instream_t *ctx, i64 *val);
|
||||
bool istr_get_num(instream_t *ctx, double *val);
|
||||
strview_t istr_get_view(instream_t *ctx, char delim);
|
||||
strview_t istr_get_view_either(instream_t *ctx, strview_t chars);
|
||||
strview_t istr_get_view_len(instream_t *ctx, usize len);
|
||||
strview_t istr_get_line(instream_t *ctx);
|
||||
|
||||
// == OUTPUT STREAM ================================================
|
||||
|
||||
typedef struct outstream_t outstream_t;
|
||||
struct outstream_t {
|
||||
char *beg;
|
||||
arena_t *arena;
|
||||
};
|
||||
|
||||
outstream_t ostr_init(arena_t *exclusive_arena);
|
||||
void ostr_clear(outstream_t *ctx);
|
||||
|
||||
usize ostr_tell(outstream_t *ctx);
|
||||
|
||||
char ostr_back(outstream_t *ctx);
|
||||
str_t ostr_to_str(outstream_t *ctx);
|
||||
strview_t ostr_as_view(outstream_t *ctx);
|
||||
|
||||
void ostr_pop(outstream_t *ctx, usize count);
|
||||
|
||||
void ostr_print(outstream_t *ctx, const char *fmt, ...);
|
||||
void ostr_printv(outstream_t *ctx, const char *fmt, va_list args);
|
||||
void ostr_putc(outstream_t *ctx, char c);
|
||||
void ostr_puts(outstream_t *ctx, strview_t v);
|
||||
|
||||
void ostr_append_bool(outstream_t *ctx, bool val);
|
||||
void ostr_append_uint(outstream_t *ctx, u64 val);
|
||||
void ostr_append_int(outstream_t *ctx, i64 val);
|
||||
void ostr_append_num(outstream_t *ctx, double val);
|
||||
|
||||
// == INPUT BINARY STREAM ==========================================
|
||||
|
||||
typedef struct {
|
||||
const u8 *beg;
|
||||
const u8 *cur;
|
||||
usize len;
|
||||
} ibstream_t;
|
||||
|
||||
ibstream_t ibstr_init(buffer_t buffer);
|
||||
|
||||
bool ibstr_is_finished(ibstream_t *ib);
|
||||
usize ibstr_tell(ibstream_t *ib);
|
||||
usize ibstr_remaining(ibstream_t *ib);
|
||||
usize ibstr_read(ibstream_t *ib, void *buffer, usize len);
|
||||
void ibstr_skip(ibstream_t *ib, usize count);
|
||||
|
||||
bool ibstr_get_u8(ibstream_t *ib, u8 *out);
|
||||
bool ibstr_get_u16(ibstream_t *ib, u16 *out);
|
||||
bool ibstr_get_u32(ibstream_t *ib, u32 *out);
|
||||
bool ibstr_get_u64(ibstream_t *ib, u64 *out);
|
||||
|
||||
bool ibstr_get_i8(ibstream_t *ib, i8 *out);
|
||||
bool ibstr_get_i16(ibstream_t *ib, i16 *out);
|
||||
bool ibstr_get_i32(ibstream_t *ib, i32 *out);
|
||||
bool ibstr_get_i64(ibstream_t *ib, i64 *out);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue