Add optional arena to a Noh_String
This commit is contained in:
75
src/noh.h
75
src/noh.h
@@ -187,6 +187,17 @@ do {
|
|||||||
(da)->elems[(da)->count++] = (elem); \
|
(da)->elems[(da)->count++] = (elem); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
// The same as noh_da_append, but uses an arena to allocate more data. No data is freed.
|
||||||
|
#define noh_da_append_arena(arena, da, elem) \
|
||||||
|
do { \
|
||||||
|
if ((da)->count >= (da)->capacity) { \
|
||||||
|
(da)->capacity = (da)->capacity == 0 ? NOH_DA_INIT_CAP : (da)->capacity * 2; \
|
||||||
|
(da)->elems = noh_arena_alloc((arena), (da)->capacity * sizeof(*(da)->elems)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
(da)->elems[(da)->count++] = (elem); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
// Appends multiple elements to a dynamic array. Allocates more memory and moves all elements to newly allocated memory
|
// Appends multiple elements to a dynamic array. Allocates more memory and moves all elements to newly allocated memory
|
||||||
// if needed.
|
// if needed.
|
||||||
#define noh_da_append_multiple(da, new_elems, new_elems_count) \
|
#define noh_da_append_multiple(da, new_elems, new_elems_count) \
|
||||||
@@ -201,6 +212,19 @@ do {
|
|||||||
(da)->count += new_elems_count; \
|
(da)->count += new_elems_count; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
// The same as noh_da_append_multiple, but uses an arena to allocate more data. No data is freed.
|
||||||
|
#define noh_da_append_multiple_arena(arena, da, new_elems, new_elems_count) \
|
||||||
|
do { \
|
||||||
|
if ((da)->count + new_elems_count > (da)->capacity) { \
|
||||||
|
if ((da)->capacity == 0) (da)->capacity = NOH_DA_INIT_CAP; \
|
||||||
|
while ((da)->count + new_elems_count > (da)->capacity) (da)->capacity *= 2; \
|
||||||
|
(da)->elems = noh_arena_alloc((arena), (da)->capacity * sizeof(*(da)->elems)); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
memcpy((da)->elems + (da)->count, new_elems, new_elems_count * sizeof(*(da)->elems)); \
|
||||||
|
(da)->count += new_elems_count; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
// Removes the element at the specified location.
|
// Removes the element at the specified location.
|
||||||
#define noh_da_remove_at(da, index) \
|
#define noh_da_remove_at(da, index) \
|
||||||
do { \
|
do { \
|
||||||
@@ -335,6 +359,9 @@ typedef struct {
|
|||||||
char *elems;
|
char *elems;
|
||||||
size_t count;
|
size_t count;
|
||||||
size_t capacity;
|
size_t capacity;
|
||||||
|
// If set, memory will be allocated in this arena when adding to the string.
|
||||||
|
// if set or unset halfway through using a string, this will cause undefined behaviour.
|
||||||
|
Noh_Arena *arena;
|
||||||
} Noh_String;
|
} Noh_String;
|
||||||
|
|
||||||
// Copies a Noh_String to the arena, and frees the Noh_String
|
// Copies a Noh_String to the arena, and frees the Noh_String
|
||||||
@@ -343,6 +370,10 @@ char *noh_arena_consume_string(Noh_Arena *arena, Noh_String *string);
|
|||||||
// Creates a Noh_String from a c-string.
|
// Creates a Noh_String from a c-string.
|
||||||
Noh_String noh_string_from_cstr(const char *cstr);
|
Noh_String noh_string_from_cstr(const char *cstr);
|
||||||
|
|
||||||
|
// Creates a Noh_String from a c-string.
|
||||||
|
// Provide a Noh_Arena to allocate the string's data in.
|
||||||
|
Noh_String noh_string_from_cstr_arena(Noh_Arena *arena, const char *cstr);
|
||||||
|
|
||||||
// Appends a null-terminated string into a Noh_String.
|
// Appends a null-terminated string into a Noh_String.
|
||||||
void noh_string_append_cstr(Noh_String *string, const char *cstr);
|
void noh_string_append_cstr(Noh_String *string, const char *cstr);
|
||||||
|
|
||||||
@@ -353,7 +384,10 @@ void noh_string_append_null(Noh_String *string);
|
|||||||
void noh_string_replace(Noh_String *string, const char from, const char to);
|
void noh_string_replace(Noh_String *string, const char from, const char to);
|
||||||
|
|
||||||
// Frees a Noh_String, freeing the memory used and settings the count and capacity to 0.
|
// Frees a Noh_String, freeing the memory used and settings the count and capacity to 0.
|
||||||
#define noh_string_free(string) noh_da_free(string)
|
#define noh_string_free(string) do { \
|
||||||
|
noh_assert(!(string)->arena && "A string with an arena cannot be freed."); \
|
||||||
|
noh_da_free(string); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
// Resets a Noh_String, setting the count to 0.
|
// Resets a Noh_String, setting the count to 0.
|
||||||
#define noh_string_reset(string) noh_da_reset(string)
|
#define noh_string_reset(string) noh_da_reset(string)
|
||||||
@@ -857,31 +891,54 @@ char *noh_arena_consume_string(Noh_Arena *arena, Noh_String *string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Noh_String noh_string_from_cstr(const char *cstr) {
|
Noh_String noh_string_from_cstr(const char *cstr) {
|
||||||
|
return noh_string_from_cstr_arena(cstr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Noh_String noh_string_from_cstr_arena(Noh_Arena *arena, const char *cstr) {
|
||||||
Noh_String str = {0};
|
Noh_String str = {0};
|
||||||
|
if (arena) str.arena = arena;
|
||||||
|
|
||||||
noh_string_append_cstr(&str, cstr);
|
noh_string_append_cstr(&str, cstr);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void noh_string_append_cstr(Noh_String *string, const char *cstr) {
|
void noh_string_append_cstr(Noh_String *string, const char *cstr) {
|
||||||
size_t len = strlen(cstr);
|
size_t len = strlen(cstr);
|
||||||
|
|
||||||
|
if (string->arena) {
|
||||||
|
noh_da_append_multiple_arena(string->arena, string, cstr, len);
|
||||||
|
} else {
|
||||||
noh_da_append_multiple(string, cstr, len);
|
noh_da_append_multiple(string, cstr, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void noh_string_append_null(Noh_String *string) {
|
void noh_string_append_null(Noh_String *string) {
|
||||||
|
if (string->arena) {
|
||||||
|
noh_da_append_arena(string->arena, string, '\0');
|
||||||
|
} else {
|
||||||
noh_da_append(string, '\0');
|
noh_da_append(string, '\0');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void noh_string_replace(Noh_String *string, const char from, const char to) {
|
void noh_string_replace(Noh_String *string, const char from, const char to) {
|
||||||
Noh_String result = {0};
|
Noh_String result = {0};
|
||||||
for (size_t i = 0; i < string->count; i++) {
|
for (size_t i = 0; i < string->count; i++) {
|
||||||
|
if (result.arena) {
|
||||||
|
if (string->elems[i] == from) {
|
||||||
|
noh_da_append_arena(result.arena, &result, to);
|
||||||
|
} else {
|
||||||
|
noh_da_append_arena(result.arena, &result, string->elems[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (string->elems[i] == from) {
|
if (string->elems[i] == from) {
|
||||||
noh_da_append(&result, to);
|
noh_da_append(&result, to);
|
||||||
} else {
|
} else {
|
||||||
noh_da_append(&result, string->elems[i]);
|
noh_da_append(&result, string->elems[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
noh_string_free(string);
|
if (!string->arena) noh_string_free(string);
|
||||||
string->elems = result.elems;
|
string->elems = result.elems;
|
||||||
string->count = result.count;
|
string->count = result.count;
|
||||||
string->capacity = result.capacity;
|
string->capacity = result.capacity;
|
||||||
@@ -906,7 +963,11 @@ bool noh_string_read_file(Noh_String *string, const char *filename) {
|
|||||||
|
|
||||||
size_t n = fread(buf, 1, buf_size, f);
|
size_t n = fread(buf, 1, buf_size, f);
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
|
if (string->arena) {
|
||||||
|
noh_da_append_multiple_arena(string->arena, string, buf, n);
|
||||||
|
} else {
|
||||||
noh_da_append_multiple(string, buf, n);
|
noh_da_append_multiple(string, buf, n);
|
||||||
|
}
|
||||||
n = fread(buf, 1, buf_size, f);
|
n = fread(buf, 1, buf_size, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -951,7 +1012,11 @@ Noh_String_View noh_sv_copy_cstr(Noh_Arena *arena, const char *cstr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void noh_string_append_sv(Noh_String *string, Noh_String_View sv) {
|
void noh_string_append_sv(Noh_String *string, Noh_String_View sv) {
|
||||||
|
if (string->arena) {
|
||||||
|
noh_da_append_multiple_arena(string->arena, string, sv.elems, sv.count);
|
||||||
|
} else {
|
||||||
noh_da_append_multiple(string, sv.elems, sv.count);
|
noh_da_append_multiple(string, sv.elems, sv.count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void noh_sv_increase_position(Noh_String_View *sv, size_t distance) {
|
void noh_sv_increase_position(Noh_String_View *sv, size_t distance) {
|
||||||
@@ -1292,11 +1357,17 @@ bool noh_procs_wait(Noh_Procs procs) {
|
|||||||
void noh_quote_if_needed(const char *value, Noh_String *string) {
|
void noh_quote_if_needed(const char *value, Noh_String *string) {
|
||||||
if (!strchr(value, ' ')) {
|
if (!strchr(value, ' ')) {
|
||||||
noh_string_append_cstr(string, value);
|
noh_string_append_cstr(string, value);
|
||||||
|
} else {
|
||||||
|
if (string->arena) {
|
||||||
|
noh_da_append_arena(string->arena, string, '\'');
|
||||||
|
noh_string_append_cstr(string, value);
|
||||||
|
noh_da_append_arena(string->arena, string, '\'');
|
||||||
} else {
|
} else {
|
||||||
noh_da_append(string, '\'');
|
noh_da_append(string, '\'');
|
||||||
noh_string_append_cstr(string, value);
|
noh_string_append_cstr(string, value);
|
||||||
noh_da_append(string, '\'');
|
noh_da_append(string, '\'');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void noh_cmd_render(Noh_Cmd cmd, Noh_String *string) {
|
void noh_cmd_render(Noh_Cmd cmd, Noh_String *string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user