diff options
author | Anton Kling <anton@kling.gg> | 2024-12-31 14:53:29 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-12-31 14:55:34 +0100 |
commit | 1b0c0f4b45e518bf12c58902819fbc90e4834dad (patch) | |
tree | fb8a52096d8c8aee9a6355c716cc972a57567027 | |
parent | f2e31397b0e20e962eba1c2096fba73a0b210846 (diff) |
libc: Add more sv/sb functions
-rw-r--r-- | userland/libc/include/tb/sb.h | 8 | ||||
-rw-r--r-- | userland/libc/include/tb/sv.h | 8 | ||||
-rw-r--r-- | userland/libc/tb/sb.c | 61 | ||||
-rw-r--r-- | userland/libc/tb/sv.c | 50 | ||||
-rw-r--r-- | userland/minibox/utilities/sh/sh.c | 2 |
5 files changed, 121 insertions, 8 deletions
diff --git a/userland/libc/include/tb/sb.h b/userland/libc/include/tb/sb.h index 7832015..f75fa5c 100644 --- a/userland/libc/include/tb/sb.h +++ b/userland/libc/include/tb/sb.h @@ -8,12 +8,14 @@ struct sb { char *string; size_t length; size_t capacity; + size_t to_ignore; uint8_t prebuffer; }; struct sv; void sb_init(struct sb *ctx); +void sb_set_ignore(struct sb *ctx, size_t n); int sb_init_capacity(struct sb *ctx, size_t starting_capacity); void sb_init_buffer(struct sb *ctx, char *buffer, size_t size); void sb_free(struct sb *ctx); @@ -22,8 +24,10 @@ int sb_isempty(const struct sb *ctx); int sb_append_char(struct sb *ctx, char c); int sb_delete_right(struct sb *ctx, size_t n); int sb_append(struct sb *ctx, const char *s); -int sb_append_buffer(struct sb *ctx, const char *buffer, size_t length); +int sb_append_buffer(struct sb *ctx, const void *buffer, size_t length); int sb_append_sv(struct sb *ctx, struct sv sv); int sb_prepend_sv(struct sb *ctx, struct sv sv); -int sb_prepend_buffer(struct sb *ctx, const char *buffer, size_t length); +int sb_prepend_buffer(struct sb *ctx, const void *buffer, size_t length); +int sb_modify_location(struct sb *ctx, void *buffer, size_t length, size_t offset); +int sb_reserve_buffer(struct sb *ctx, size_t *offset, size_t length); #endif diff --git a/userland/libc/include/tb/sv.h b/userland/libc/include/tb/sv.h index 7062741..8a993ec 100644 --- a/userland/libc/include/tb/sv.h +++ b/userland/libc/include/tb/sv.h @@ -2,6 +2,7 @@ #define SV_H #include "sb.h" #include <stddef.h> +#include <stdint.h> #define SB_TO_SV(_sb) \ (struct sv) { \ @@ -11,6 +12,7 @@ #define C_TO_SV(_c_string) \ ((struct sv){.length = strlen(_c_string), .s = (_c_string)}) +#define sv_buffer(a) ((a).s) #define sv_length(a) ((a).length) struct sv { @@ -18,6 +20,7 @@ struct sv { size_t length; }; +struct sv sv_init(const char *s, size_t length); char *SV_TO_C(struct sv s); size_t sv_to_cstring_buffer(struct sv s, char *buffer, size_t length); struct sv sv_split_delim(const struct sv input, struct sv *rest, char delim); @@ -27,6 +30,7 @@ struct sv sv_split_space(const struct sv input, struct sv *rest); struct sv sv_skip_chars(const struct sv input, const char *chars); struct sv sv_split_function(const struct sv input, struct sv *rest, int (*function)(int)); +int sv_try_eat(struct sv input, struct sv *rest, struct sv b); struct sv sv_take(struct sv s, struct sv *rest, size_t n); struct sv sv_take_end(struct sv s, struct sv *rest, size_t n); struct sv sv_next(struct sv s); @@ -38,5 +42,7 @@ struct sv sv_trim_left(struct sv s, size_t n); struct sv sv_clone(struct sv s); struct sv sv_clone_from_c(const char *s); char *sv_copy_to_c(struct sv s, char *out, size_t buffer_length); -uint64_t sv_parse_unsigned_number(struct sv input, struct sv *rest); +uint64_t sv_parse_unsigned_number(struct sv input, struct sv *rest, + int *got_num); +int sv_read(struct sv s, struct sv *rest, void *buf, size_t n); #endif diff --git a/userland/libc/tb/sb.c b/userland/libc/tb/sb.c index c379082..0c36750 100644 --- a/userland/libc/tb/sb.c +++ b/userland/libc/tb/sb.c @@ -10,6 +10,7 @@ void sb_init(struct sb *ctx) { } int sb_init_capacity(struct sb *ctx, size_t starting_capacity) { + ctx->to_ignore = 0; ctx->length = 0; ctx->prebuffer = 0; ctx->string = malloc(starting_capacity); @@ -26,6 +27,7 @@ void sb_init_buffer(struct sb *ctx, char *buffer, size_t size) { ctx->capacity = size; ctx->length = 0; ctx->prebuffer = 1; + ctx->to_ignore = 0; } void sb_free(struct sb *ctx) { @@ -39,8 +41,13 @@ void sb_free(struct sb *ctx) { ctx->string = NULL; } +void sb_set_ignore(struct sb *ctx, size_t n) { + ctx->to_ignore = n; +} + void sb_reset(struct sb *ctx) { ctx->length = 0; + ctx->to_ignore = 0; } int sb_isempty(const struct sb *ctx) { @@ -63,6 +70,10 @@ int sb_increase_buffer(struct sb *ctx, size_t min) { } int sb_append_char(struct sb *ctx, char c) { + if (ctx->to_ignore > 0) { + ctx->to_ignore--; + return 1; + } if (1 > ctx->capacity - ctx->length) { if (!sb_increase_buffer(ctx, 1)) { return 0; @@ -81,6 +92,13 @@ int sb_delete_right(struct sb *ctx, size_t n) { int sb_append(struct sb *ctx, const char *s) { size_t l = strlen(s); + if (ctx->to_ignore >= l) { + ctx->to_ignore -= l; + return 1; + } + l -= ctx->to_ignore; + s += ctx->to_ignore; + ctx->to_ignore = 0; if (l > ctx->capacity - ctx->length) { if (!sb_increase_buffer(ctx, l)) { return 0; @@ -95,7 +113,14 @@ int sb_prepend_sv(struct sb *ctx, struct sv sv) { return sb_prepend_buffer(ctx, sv.s, sv.length); } -int sb_prepend_buffer(struct sb *ctx, const char *buffer, size_t length) { +int sb_prepend_buffer(struct sb *ctx, const void *buffer, size_t length) { + if (ctx->to_ignore >= length) { + ctx->to_ignore -= length; + return 1; + } + length -= ctx->to_ignore; + buffer = (void *)((uintptr_t)buffer + ctx->to_ignore); + ctx->to_ignore = 0; if (length > ctx->capacity - ctx->length) { if (!sb_increase_buffer(ctx, length)) { return 0; @@ -107,7 +132,14 @@ int sb_prepend_buffer(struct sb *ctx, const char *buffer, size_t length) { return 1; } -int sb_append_buffer(struct sb *ctx, const char *buffer, size_t length) { +int sb_append_buffer(struct sb *ctx, const void *buffer, size_t length) { + if (ctx->to_ignore >= length) { + ctx->to_ignore -= length; + return 1; + } + length -= ctx->to_ignore; + buffer = (void *)((uintptr_t)buffer + ctx->to_ignore); + ctx->to_ignore = 0; if (length > ctx->capacity - ctx->length) { if (!sb_increase_buffer(ctx, length)) { return 0; @@ -118,6 +150,31 @@ int sb_append_buffer(struct sb *ctx, const char *buffer, size_t length) { return 1; } +int sb_modify_location(struct sb *ctx, void *buffer, size_t length, + size_t offset) { + if (offset + length > ctx->length) { + return 0; + } + memcpy(ctx->string + offset, buffer, length); + return 1; +} + +int sb_reserve_buffer(struct sb *ctx, size_t *offset, size_t length) { + if (ctx->to_ignore > 0) { + return 0; + } + if (length > ctx->capacity - ctx->length) { + if (!sb_increase_buffer(ctx, length)) { + return 0; + } + } + if (offset) { + *offset = ctx->length; + } + ctx->length += length; + return 1; +} + int sb_append_sv(struct sb *ctx, struct sv sv) { return sb_append_buffer(ctx, sv.s, sv.length); } diff --git a/userland/libc/tb/sv.c b/userland/libc/tb/sv.c index 0d47924..a4458d5 100644 --- a/userland/libc/tb/sv.c +++ b/userland/libc/tb/sv.c @@ -1,9 +1,14 @@ #include <ctype.h> -#include <math.h> #include <stdlib.h> #include <string.h> #include <tb/sv.h> +#define min(a, b) (((a) < (b)) ? (a) : (b)) + +struct sv sv_init(const char *s, size_t length) { + return (struct sv){.s = s, .length = length}; +} + char *SV_TO_C(struct sv s) { char *c_string = malloc(s.length + 1); memcpy(c_string, s.s, s.length); @@ -49,7 +54,11 @@ struct sv sv_skip_chars(const struct sv input, const char *chars) { return r; } -uint64_t sv_parse_unsigned_number(struct sv input, struct sv *rest) { +uint64_t sv_parse_unsigned_number(struct sv input, struct sv *rest, + int *got_num) { + if (got_num) { + *got_num = 0; + } uint64_t r = 0; size_t i = 0; for (; i < input.length; i++) { @@ -59,6 +68,11 @@ uint64_t sv_parse_unsigned_number(struct sv input, struct sv *rest) { r *= 10; r += input.s[i] - '0'; } + if (i > 0) { + if (got_num) { + *got_num = 1; + } + } input.length -= i; input.s += i; if (rest) { @@ -189,6 +203,21 @@ struct sv sv_take(struct sv s, struct sv *rest, size_t n) { return s; } +int sv_read(struct sv s, struct sv *rest, void *buf, size_t n) { + if (s.length < n) { + if (rest) { + rest->length = 0; + } + return 0; + } + memcpy(buf, s.s, n); + if (rest) { + rest->length -= n; + rest->s += n; + } + return 1; +} + struct sv sv_take_end(struct sv s, struct sv *rest, size_t n) { if (s.length < n) { if (rest) { @@ -224,6 +253,23 @@ struct sv sv_clone(struct sv s) { return new_sv; } +int sv_try_eat(struct sv input, struct sv *rest, struct sv b) { + if (input.length < b.length) { + return 0; + } + for (size_t i = 0; i < b.length; i++) { + if (input.s[i] != b.s[i]) { + return 0; + } + } + input.s += b.length; + input.length -= b.length; + if (rest) { + *rest = input; + } + return 1; +} + char *sv_copy_to_c(struct sv s, char *out, size_t buffer_length) { int copy_len = min(s.length + 1, buffer_length); if (0 == copy_len) { diff --git a/userland/minibox/utilities/sh/sh.c b/userland/minibox/utilities/sh/sh.c index e30e3f5..da7249f 100644 --- a/userland/minibox/utilities/sh/sh.c +++ b/userland/minibox/utilities/sh/sh.c @@ -113,7 +113,7 @@ int execute_command(struct AST *ast, int input_fd) { struct AST *child = ast->children; if (child) { struct sv rest; - rc = sv_parse_unsigned_number(child->val.string, &rest); + rc = sv_parse_unsigned_number(child->val.string, &rest, NULL); if (rc > 255) { rc = 2; } |