diff options
author | EuAndreh <eu@euandre.org> | 2025-01-12 00:14:03 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2025-01-12 14:27:57 -0300 |
commit | 44d56f5311f98a8955c67638e7520963dbd4d845 (patch) | |
tree | fbb2c58c79f1730ff62c83cef116fb5c0e035dfe /src | |
parent | Replace src/config.h with <s.h>; incorporate changes from other projects (diff) | |
download | pindaiba-44d56f5311f98a8955c67638e7520963dbd4d845.tar.gz pindaiba-44d56f5311f98a8955c67638e7520963dbd4d845.tar.xz |
Revamp lib, simplify it a bit and address some FIXMEs
Diffstat (limited to 'src')
-rw-r--r-- | src/catalog.h | 22 | ||||
-rw-r--r-- | src/cmp.c | 2 | ||||
-rw-r--r-- | src/hash.c | 83 | ||||
-rw-r--r-- | src/hash.h | 6 | ||||
-rw-r--r-- | src/i18n.c | 18 | ||||
-rw-r--r-- | src/lib.c | 4 | ||||
-rw-r--r-- | src/lib.h | 3 | ||||
-rw-r--r-- | src/logerr.c | 52 | ||||
-rw-r--r-- | src/logerr.h | 25 | ||||
-rw-r--r-- | src/main.c | 6 | ||||
-rw-r--r-- | src/math.c | 9 | ||||
-rw-r--r-- | src/math.h | 6 | ||||
-rw-r--r-- | src/meta.h.in | 2 | ||||
-rw-r--r-- | src/msgs.c (renamed from src/catalog.c) | 35 | ||||
-rw-r--r-- | src/msgs.h | 26 | ||||
-rw-r--r-- | src/pindaiba.en.msg | 22 | ||||
-rw-r--r-- | src/random.c | 109 | ||||
-rw-r--r-- | src/random.h | 16 | ||||
-rw-r--r-- | src/set.c | 14 | ||||
-rw-r--r-- | src/string.c | 58 | ||||
-rw-r--r-- | src/string.h | 2 | ||||
-rw-r--r-- | src/testing.c | 31 | ||||
-rw-r--r-- | src/testing.h | 3 | ||||
-rw-r--r-- | src/trace.c | 94 | ||||
-rw-r--r-- | src/trace.h | 49 | ||||
-rw-r--r-- | src/tree.c | 47 | ||||
-rw-r--r-- | src/tree.h | 10 | ||||
-rw-r--r-- | src/util.c | 26 | ||||
-rw-r--r-- | src/util.h | 13 | ||||
-rw-r--r-- | src/vector.c | 39 |
30 files changed, 439 insertions, 393 deletions
diff --git a/src/catalog.h b/src/catalog.h deleted file mode 100644 index 3acb24d..0000000 --- a/src/catalog.h +++ /dev/null @@ -1,22 +0,0 @@ -int -i18n_init_msgs(const char *const MSGS[]); - -int -i18n_destroy(void); - -const char * -s(const char *const MSGS[], const int msg_id); - -int -s_print_msgs( - const char *const MSGS[], - FILE *restrict stream, - const int msg_begin, - const int msg_end -); - -int -s_print_msg(const char *const MSGS[], FILE *restrict stream, const int msg_id); - -int -dump_translatable_strings(const char *const MSGS[]); @@ -1,4 +1,4 @@ -#include "config.h" +#include <s.h> #include <stddef.h> @@ -1,104 +1,47 @@ -#include "config.h" +#include <s.h> #include <assert.h> -#include <pthread.h> #include <stdbool.h> -#include <stddef.h> -#include <stdint.h> #include <stdio.h> -#include <string.h> #include <siphash.h> -#include "hash.h" #include "logerr.h" #include "random.h" +#include "hash.h" -static volatile bool -INITIALIZED = false; -static uint8_t -HASH_KEY[SIPHASHBS_KEY_LENGTH]; +static bool +SEED_INITIALIZED = false; -static pthread_mutex_t -SEED_MUTEX = PTHREAD_MUTEX_INITIALIZER; +static u8 +HASH_KEY[SIPHASH_KEY_LENGTH]; -static int -unsafe_init(void) { +int +hash_setup(void) { int rc = -1; - if (urandom_bytes(SIPHASHBS_KEY_LENGTH, &HASH_KEY)) { + if (random_bytes(SIPHASH_KEY_LENGTH, &HASH_KEY)) { logerr("urandom_bytes()"); goto out; } + SEED_INITIALIZED = true; rc = 0; out: return rc; } -static int -safe_init(void) { - int rc = -1; - - bool lock_acquired = false; - - if (INITIALIZED == true) { - rc = 0; - goto out; - } - - const int ret1 = pthread_mutex_lock(&SEED_MUTEX); - if (ret1) { - logerr("pthread_mutex_lock(): %s", strerror(ret1)); - goto out; - } - lock_acquired = true; - - if (INITIALIZED == true) { - rc = 0; - goto out; - } - - if (unsafe_init()) { - logerr("unsafe_init()"); - goto out; - } - - INITIALIZED = true; - - rc = 0; -out: - if (lock_acquired) { - const int ret2 = pthread_mutex_unlock(&SEED_MUTEX); - if (ret2) { - logerr("pthread_mutex_unlock(): %s", strerror(ret2)); - rc = -1; - } - } - return rc; -} - -static void -ensure_initialized(void) { - assert((safe_init() == 0) && "Failed to initialized the hash seed"); -} - -int -hash_init(void) { - return safe_init(); -} - void hash( const size_t inlen, const void *const restrict in, - uint8_t out[HASH_OUTPUT_LENGTH] + u8 out[HASH_OUTPUT_LENGTH] ) { - ensure_initialized(); - siphashbs(HASH_KEY, inlen, in, out); + assert(SEED_INITIALIZED == true); + siphash(HASH_KEY, inlen, in, out); } @@ -1,8 +1,10 @@ -#define HASH_OUTPUT_LENGTH 16U +enum { + HASH_OUTPUT_LENGTH = 16U, +}; void hash( const size_t inlen, const void *const restrict in, - uint8_t out[HASH_OUTPUT_LENGTH] + u8 out[HASH_OUTPUT_LENGTH] ); @@ -1,12 +1,14 @@ -#include "config.h" +#include <s.h> #include <stdio.h> -#include "catalog.h" +#include "meta.h" +#include "msgs.h" #include "i18n.h" + const char *const MSGS[] = { [MSG_USAGE_FIRST]="Usage:\n", @@ -26,11 +28,11 @@ MSGS[] = { [MSG_HELP_10]="\n", [MSG_HELP_11]="Run the " NAME "(1) parser program.\n", [MSG_HELP_12]="\n", - [MSG_HELP_13]="Here is the explanation for what it does, and the synopsis\n", - [MSG_HELP_14]="of its usage.\n", + [MSG_HELP_13]="Here is the explanation for what it does, and the\n", + [MSG_HELP_14]="synopsis of its usage.\n", [MSG_HELP_15]="\n", [MSG_HELP_16]="See \"man " NAME "\" for usage information and\n", - [MSG_HELP_17]="\"man " NAME ".tutorial\" for a beginner introduction.\n", + [MSG_HELP_17]="\"man " NAME ".tutorial\" for a beginner intro.\n", [MSG_HELP_18]="\n", [MSG_HELP_19]="\n", [MSG_HELP_20]="Examples:\n", @@ -50,12 +52,14 @@ MSGS[] = { NULL }; + + const char * _(const int msg_id) { - return s(MSGS, msg_id); + return msgs_string(MSGS, msg_id); } int i18n_init(void) { - return i18n_init_msgs(MSGS); + return msgs_init(MSGS); } @@ -1,4 +1,4 @@ -#include "config.h" +#include <s.h> #include <errno.h> #include <stdio.h> @@ -6,10 +6,12 @@ #include <string.h> #include "logerr.h" +#include "meta.h" #include "lib.h" + int pindaiba_main(int argc, char *argv[]) { int rc = EXIT_FAILURE; @@ -1,5 +1,2 @@ -extern const size_t -NULL_TERMINATOR; - int pindaiba_main(int argc, char *argv[]); diff --git a/src/logerr.c b/src/logerr.c index fac87f0..2d5c340 100644 --- a/src/logerr.c +++ b/src/logerr.c @@ -1,34 +1,72 @@ -#include "config.h" +#include <s.h> #include <stdarg.h> #include <stdio.h> -#include <stdlib.h> #include "logerr.h" +static FILE * +STREAM = NULL; + + + void -vlogerr( +vflogerrf( const char *const file, const char *const function, const int lineno, FILE *restrict stream, const char *restrict format, - ... + va_list args ) { if (fprintf(stream, "%s:%s:%d: ", file, function, lineno) < 0) { perror(__FILE__ ":vlogerr(): fprintf() < 0"); } - va_list args; - va_start(args, format); if (vfprintf(stream, format, args) < 0) { perror(__FILE__ ":vlogerr(): vfprintf() < 0"); } - va_end(args); if (fprintf(stream, "\n") < 0) { perror(__FILE__ ":vlogerr(): fprintf() < 0"); } } + +void +flogerrf( + const char *const file, + const char *const function, + const int lineno, + FILE *restrict stream, + const char *restrict format, + ... +) { + va_list args; + va_start(args, format); + vflogerrf(file, function, lineno, stream, format, args); + va_end(args); +} + +void +logerrf( + const char *const file, + const char *const function, + const int lineno, + const char *restrict format, + ... +) { + if (STREAM == NULL) { + STREAM = stderr; + } + va_list args; + va_start(args, format); + vflogerrf(file, function, lineno, STREAM, format, args); + va_end(args); +} + +void +logerr_set_stream(FILE *stream) { + STREAM = stream; +} diff --git a/src/logerr.h b/src/logerr.h index 736da7a..346989d 100644 --- a/src/logerr.h +++ b/src/logerr.h @@ -1,10 +1,19 @@ -#define logerr(...) vlogerr(__FILE__, __func__, __LINE__, stderr, __VA_ARGS__) +#define logerr(...) logerrf(__FILE__, __func__, __LINE__, __VA_ARGS__) void -vlogerr( +vflogerrf( + const char *const file, + const char *const function, + const int lineno, + FILE *restrict stream, + const char *restrict format, + va_list args +); +void +flogerrf( const char *const file, const char *const function, const int lineno, @@ -12,3 +21,15 @@ vlogerr( const char *restrict format, ... ); + +void +logerrf( + const char *const file, + const char *const function, + const int lineno, + const char *restrict format, + ... +); + +void +logerr_set_stream(FILE *stream); @@ -1,8 +1,8 @@ -#include "config.h" +#include <s.h> + +#include "pindaiba.h" -#include <stddef.h> -#include "pindaibabs.h" int main(int argc, char *argv[]) { @@ -1,4 +1,4 @@ -#include "config.h" +#include <s.h> #include <assert.h> #include <errno.h> @@ -9,6 +9,7 @@ #include "math.h" + int add_size(const size_t x, const size_t y, size_t *const out) { int rc = EOVERFLOW; @@ -42,5 +43,7 @@ out: return rc; } -extern inline size_t -max_size(const size_t x, const size_t y); +size_t +max_size(const size_t x, const size_t y) { + return x > y ? x : y; +} @@ -4,7 +4,5 @@ add_size(const size_t x, const size_t y, size_t *const out); int mul_size(const size_t x, const size_t y, size_t *const out); -inline size_t -max_size(size_t x, size_t y) { - return x > y ? x : y; -} +size_t +max_size(size_t x, size_t y); diff --git a/src/meta.h.in b/src/meta.h.in index 9bd8c08..52f3437 100644 --- a/src/meta.h.in +++ b/src/meta.h.in @@ -1,3 +1,5 @@ #define VERSION "@VERSION@" #define DATE "@DATE@" #define NAME "@NAME@" + +#define LOCALEDIR "@LOCALEDIR@" diff --git a/src/catalog.c b/src/msgs.c index 9550631..eaa6276 100644 --- a/src/catalog.c +++ b/src/msgs.c @@ -1,4 +1,4 @@ -#include "config.h" +#include <s.h> #include <assert.h> #include <errno.h> @@ -8,12 +8,14 @@ #include <string.h> #include "logerr.h" +#include "meta.h" -#include "catalog.h" +#include "msgs.h" -static const char *const -CATALOG_NAME = NAME; + +static const char +CATALOG_NAME[] = NAME; static nl_catd catalog_descriptor = NULL; @@ -21,16 +23,17 @@ catalog_descriptor = NULL; static size_t msgs_length = 0U; -static const char *const -NLSPATH = LOCALEDIR "/%l_%t/LC_MESSAGES/%N.cat" ":" +static const char +NLSPATH[] = LOCALEDIR "/%l_%t/LC_MESSAGES/%N.cat" ":" LOCALEDIR "/%l/LC_MESSAGES/%N.cat"; -static const char *const -NLSPATH_KEY = "NLSPATH"; +static const char +NLSPATH_KEY[] = "NLSPATH"; + int -i18n_init_msgs(const char *const MSGS[]) { +msgs_init(const char *const MSGS[]) { int rc = -1; static const int should_overwrite = 0; @@ -57,7 +60,7 @@ out: } int -i18n_destroy(void) { +msgs_end(void) { int rc = -1; if (catalog_descriptor != NULL) { @@ -76,7 +79,7 @@ out: } const char * -s(const char* const MSGS[], const int msg_id) { +msgs_string(const char* const MSGS[], const int msg_id) { assert(msg_id >= 0); if (msgs_length != 0U) { assert((size_t)msg_id < msgs_length); @@ -96,7 +99,7 @@ s(const char* const MSGS[], const int msg_id) { } int -s_print_msgs( +msgs_print_ids( const char *const MSGS[], FILE *restrict stream, const int msg_begin, @@ -105,7 +108,7 @@ s_print_msgs( int rc = -1; for (int i = msg_begin; i <= msg_end; i++) { - if (fprintf(stream, "%s", s(MSGS, i)) < 0) { + if (fprintf(stream, "%s", msgs_string(MSGS, i)) < 0) { logerr("fprintf(): %s", strerror(errno)); goto out; } @@ -117,12 +120,12 @@ out: } int -s_print_msg(const char *const MSGS[], FILE *const fd, const int msg_id) { - return s_print_msgs(MSGS, fd, msg_id, msg_id); +msgs_print_id(const char *const MSGS[], FILE *const stream, const int msg_id) { + return msgs_print_ids(MSGS, stream, msg_id, msg_id); } int -dump_translatable_strings(const char *const MSGS[]) { +msgs_dump_translatable_strings(const char *const MSGS[]) { int rc = -1; for (size_t i = 0U; MSGS[i] != NULL; i++) { diff --git a/src/msgs.h b/src/msgs.h new file mode 100644 index 0000000..27a7f26 --- /dev/null +++ b/src/msgs.h @@ -0,0 +1,26 @@ +int +msgs_init(const char *const MSGS[]); + +int +msgs_end(void); + +const char * +msgs_string(const char *const MSGS[], const int msg_id); + +int +msgs_print_ids( + const char *const MSGS[], + FILE *restrict stream, + const int msg_begin, + const int msg_end +); + +int +msgs_print_id( + const char *const MSGS[], + FILE *restrict stream, + const int msg_id +); + +int +msgs_dump_translatable_strings(const char *const MSGS[]); diff --git a/src/pindaiba.en.msg b/src/pindaiba.en.msg index 72c5daa..8fc9fa9 100644 --- a/src/pindaiba.en.msg +++ b/src/pindaiba.en.msg @@ -1,10 +1,10 @@ 0 Usage:\n -1 pindaibabs -p FILE [-o DIRECTORY]\n +1 pindaiba -p FILE [-o DIRECTORY]\n -2 pindaibabs -l FILE [-o DIRECTORY]\n +2 pindaiba -l FILE [-o DIRECTORY]\n -3 pindaibabs [-hV]\n +3 pindaiba [-hV]\n 4 \n @@ -28,19 +28,19 @@ 14 \n -15 Run the pindaibabs(1) parser program.\n +15 Run the pindaiba(1) parser program.\n 16 \n -17 Here is the explanation for what it does, and the synopsis\n +17 Here is the explanation for what it does, and the\n -18 of its usage.\n +18 synopsis of its usage.\n 19 \n -20 See "man pindaibabs" for usage information and\n +20 See "man pindaiba" for usage information and\n -21 "man pindaibabs.tutorial" for a beginner introduction.\n +21 "man pindaiba.tutorial" for a beginner intro.\n 22 \n @@ -54,7 +54,7 @@ 27 \n -28 $ pindaibabs run md.grammar < README.md\n +28 $ pindaiba run md.grammar < README.md\n 29 \n @@ -64,9 +64,9 @@ 32 \n -33 $ pindaibabs build csv.grammar > dunno.alsodunno\n +33 $ pindaiba build csv.grammar > dunno.alsodunno\n -34 pindaibabs 0.1.0 1970-01-01\n +34 pindaiba 0.1.0 1970-01-01\n 35 Already at max capacity (%ld): %s\n diff --git a/src/random.c b/src/random.c index b409e6a..0382b3e 100644 --- a/src/random.c +++ b/src/random.c @@ -1,141 +1,64 @@ -#include "config.h" +#include <s.h> #include <assert.h> #include <errno.h> -#include <stdint.h> #include <stdio.h> -#include <stdlib.h> #include <string.h> #include "logerr.h" -#include "util.h" #include "random.h" -struct Random { - FILE *const file_handle; -}; +static FILE * +FRANDOM = NULL; int -urandom_bytes(const size_t n, uint8_t (*const addr)[]) { +random_init(void) { int rc = -1; - uint8_t *ret = NULL; - FILE *f = NULL; - - ret = malloc(n); - if (ret == NULL) { - logerr("malloc(): %s", strerror(errno)); - goto out; - } - - f = fopen("/dev/urandom", "r"); - if (f == NULL) { + FRANDOM = fopen("/dev/urandom", "r"); + if (FRANDOM == NULL) { logerr("fopen(): %s", strerror(errno)); goto out; } - const size_t read_count = fread(ret, 1U, n, f); - if (ferror(f)) { - logerr("fread(): %s", strerror(errno)); - goto out; - } - assert(read_count == n); - - if (fclose(f)) { - logerr("fclose(): %s", strerror(errno)); - goto out; - } - f = NULL; - - memcpy(addr, ret, n); rc = 0; out: - if (f != NULL) { - if (fclose(f)) { - logerr("fclose(): %s", strerror(errno)); - rc = -1; - } - } - if (ret != NULL) { - freeit((void *)&ret); - } return rc; } int -random_generate( - const struct Random *const r, - const size_t length, - uint8_t (*const out)[] -) { +random_end(void) { int rc = -1; - const size_t read_count = fread(out, 1U, length, r->file_handle); - if (ferror(r->file_handle)) { - logerr("fread(): %s", strerror(errno)); + if (fclose(FRANDOM)) { + logerr("fclose(): %s", strerror(errno)); goto out; } - assert(read_count == length); rc = 0; out: + FRANDOM = NULL; return rc; } int -random_new(const struct Random **const out) { +random_bytes(const size_t length, u8 (*const out)[]) { int rc = -1; - const struct Random *ret = NULL; - FILE *f = NULL; - - ret = malloc(sizeof(*ret)); - if (ret == NULL) { - logerr("malloc(): %s", strerror(errno)); - goto out; - } - - f = fopen("/dev/urandom", "r"); - if (f == NULL) { - logerr("fopen(): %s", strerror(errno)); - goto out; - } - - memcpy((void *)ret, &(struct Random) { - .file_handle = f, - }, sizeof(*ret)); - *out = ret; - rc = 0; -out: - if (rc) { - random_free(&ret); - } - return rc; -} - -int -random_free(const struct Random **const r) { - if (r == NULL) { - return 0; - } - - if (*r == NULL) { - return 0; - } - - int rc = -1; - if (fclose((*r)->file_handle)) { - logerr("fclose(): %s", strerror(errno)); + assert(FRANDOM != NULL); + const size_t read_count = fread(out, 1U, length, FRANDOM); + if (ferror(FRANDOM)) { + logerr("fread(): %s", strerror(errno)); goto out; } + assert(read_count == length); rc = 0; out: - freeit((void *)r); return rc; } diff --git a/src/random.h b/src/random.h index 4b31abb..ef876fe 100644 --- a/src/random.h +++ b/src/random.h @@ -1,18 +1,8 @@ -struct Random; - - -int -urandom_bytes(const size_t n, uint8_t (*const addr)[]); - int -random_new(const struct Random **out); +random_init(void); int -random_free(const struct Random **r); +random_end(void); int -random_generate( - const struct Random *r, - const size_t length, - uint8_t (*const out)[] -); +random_bytes(const size_t length, u8 (*const out)[]); @@ -1,4 +1,4 @@ -#include "config.h" +#include <s.h> #include <assert.h> #include <errno.h> @@ -8,13 +8,11 @@ #include <stdint.h> #include <string.h> -#include <endiannessbs.h> -#include <siphashbs.h> +#include <endianness.h> #include "hash.h" #include "logerr.h" #include "tree.h" -#include "util.h" #include "vector.h" #include "set.h" @@ -73,7 +71,8 @@ out: vector_free(&table); } if (ret != NULL) { - freeit((void *)&ret); + free((struct Set *)ret); + ret = NULL; } } return rc; @@ -84,7 +83,8 @@ set_free(const struct Set **const s) { assert((*s) != NULL); const struct Vector *table = (*s)->table; vector_free(&table); - freeit((void *)s); + free((struct Set *)*s); + *s = NULL; } int @@ -94,7 +94,7 @@ set_add(const struct Set *const s, const void *const value) { uint8_t hash_bytes[HASH_OUTPUT_LENGTH]; hash(s->value_size, value, hash_bytes); - const uint64_t hash_value = endiannessbs_from_le64(hash_bytes); + const uint64_t hash_value = endianness_from_le64(hash_bytes); const size_t idx = hash_value % vector_capacity(s->table); const struct Tree *slot; diff --git a/src/string.c b/src/string.c index 74fe2bd..e8c7dbc 100644 --- a/src/string.c +++ b/src/string.c @@ -1,17 +1,14 @@ -#include "config.h" +#include <s.h> #include <assert.h> #include <errno.h> #include <stdbool.h> -#include <stddef.h> -#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "logerr.h" #include "math.h" -#include "util.h" #include "string.h" @@ -19,7 +16,7 @@ struct String { const size_t length; - const uint8_t *const bytes; + const u8 *const bytes; }; @@ -33,7 +30,7 @@ string_new_with( int rc = -1; const struct String *ret = NULL; - const uint8_t *bytes = NULL; + const u8 *bytes = NULL; ret = malloc(sizeof(*ret)); if (ret == NULL) { @@ -47,9 +44,9 @@ string_new_with( goto out; } - memcpy((void *)bytes, string, length); - memcpy((void *)(bytes + length), "", NULL_TERMINATOR); - memcpy((void *)ret, &(struct String) { + memcpy((u8 *)bytes, string, length); + memcpy((u8 *)(bytes + length), "", NULL_TERMINATOR); + memcpy((u8 *)ret, &(struct String) { .length = length, .bytes = bytes, }, sizeof(*ret)); @@ -58,10 +55,12 @@ string_new_with( out: if (rc) { if (bytes != NULL) { - freeit((void *)&bytes); + free((u8 *)bytes); + bytes = NULL; } if (ret != NULL) { - freeit((void *)&ret); + free((struct String *)ret); + ret = NULL; } } return rc; @@ -72,11 +71,21 @@ string_new(const char *const string, const struct String **const out) { return string_new_with(string, strlen(string), out); } +struct String +S(const char *const string) { + return (struct String) { + .length = strlen(string) + NULL_TERMINATOR, + .bytes = (const u8 *)string, + }; +} + void string_free(const struct String **const s) { - const uint8_t *bytes = (*s)->bytes; - freeit((void *)&bytes); - freeit((void *)s); + const u8 *bytes = (*s)->bytes; + free((u8 *)bytes); + bytes = NULL; + free((struct String *)*s); + *s = NULL; } const char * @@ -91,7 +100,10 @@ string_compare(const struct String *const s1, const struct String *const s2) { } else if (s1->length > s2->length) { return Comparison_GT; } else { - const int ret = strcmp((const char *)s1->bytes, (const char *)s2->bytes); + const int ret = strcmp( + (const char *)s1->bytes, + (const char *)s2->bytes + ); if (ret < 0) { return Comparison_LT; } else if (ret > 0) { @@ -116,7 +128,7 @@ string_append( int rc = -1; const struct String *ret = NULL; - const uint8_t *bytes = NULL; + const u8 *bytes = NULL; size_t length; if (add_size(s1->length, s2->length, &length)) { @@ -136,10 +148,10 @@ string_append( goto out; } - memcpy((void *)bytes, s1->bytes, s1->length); - memcpy((void *)(bytes + s1->length), s2->bytes, s2->length); - memcpy((void *)(bytes + length), "", NULL_TERMINATOR); - memcpy((void *)ret, &(struct String) { + memcpy((u8 *)bytes, s1->bytes, s1->length); + memcpy((u8 *)(bytes + s1->length), s2->bytes, s2->length); + memcpy((u8 *)(bytes + length), "", NULL_TERMINATOR); + memcpy((u8 *)ret, &(struct String) { .length = length, .bytes = bytes, }, sizeof(*ret)); @@ -148,10 +160,12 @@ string_append( out: if (rc) { if (bytes != NULL) { - freeit((void *)&bytes); + free((u8 *)bytes); + bytes = NULL; } if (ret != NULL) { - freeit((void *)&ret); + free((struct String *)ret); + ret = NULL; } } return rc; diff --git a/src/string.h b/src/string.h index 2ae5a98..7b1e27b 100644 --- a/src/string.h +++ b/src/string.h @@ -6,6 +6,8 @@ enum Comparison { Comparison_GT, }; + + int string_new(const char *const string, const struct String **out); diff --git a/src/testing.c b/src/testing.c index f3239e0..d0b65db 100644 --- a/src/testing.c +++ b/src/testing.c @@ -1,4 +1,4 @@ -#include "config.h" +#include <s.h> #include <stdbool.h> #include <stdio.h> @@ -7,6 +7,7 @@ #include "testing.h" + #define COLOUR_RESET "\033[0m" #define COLOUR_GREEN "\033[0;32m" #define COLOUR_YELLOW "\033[0;33m" @@ -14,6 +15,10 @@ static const char ENVVAR_NAME[] = "NO_COLOUR"; +static FILE * +STREAM = NULL; + + static bool show_colour(void) { @@ -23,20 +28,26 @@ show_colour(void) { void test_start(const char *const name) { - (void)fprintf(stderr, "%s:\n", name); + if (STREAM == NULL) { + STREAM = stderr; + } + (void)fprintf(STREAM, "%s:\n", name); } void testing(const char *const message) { + if (STREAM == NULL) { + STREAM = stderr; + } if (show_colour()) { (void)fprintf( - stderr, + STREAM, COLOUR_YELLOW "testing" COLOUR_RESET ": %s... ", message ); } else { (void)fprintf( - stderr, + STREAM, "testing: %s...", message ); @@ -45,9 +56,17 @@ testing(const char *const message) { void test_ok(void) { + if (STREAM == NULL) { + STREAM = stderr; + } if (show_colour()) { - (void)fprintf(stderr, COLOUR_GREEN "OK" COLOUR_RESET ".\n"); + (void)fprintf(STREAM, COLOUR_GREEN "OK" COLOUR_RESET ".\n"); } else { - (void)fprintf(stderr, " OK.\n"); + (void)fprintf(STREAM, " OK.\n"); } } + +void +test_set_stream(FILE *stream) { + STREAM = stream; +} diff --git a/src/testing.h b/src/testing.h index 9a1bb2e..0bf6b4d 100644 --- a/src/testing.h +++ b/src/testing.h @@ -6,3 +6,6 @@ testing(const char *const message); void test_ok(void); + +void +test_set_stream(FILE *new_stream); diff --git a/src/trace.c b/src/trace.c index b37da2f..335ee43 100644 --- a/src/trace.c +++ b/src/trace.c @@ -1,73 +1,95 @@ -#include "config.h" +#include <s.h> #include <assert.h> +#include <errno.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <threads.h> +#include "logerr.h" #include "trace.h" -thread_local enum TraceLevel -TRACE_LEVEL = TraceLevel_INFO; +static thread_local enum TraceLevel +LEVEL = TraceLevel_INFO; -thread_local FILE * -TRACE_OUTPUT = NULL; +static thread_local FILE * +STREAM = NULL; void -set_level(const enum TraceLevel level) { - assert(level >= TraceLevel_NONE); - assert(level <= TraceLevel_ERROR); - TRACE_LEVEL = level; -} - -void -set_output(FILE *stream) { - TRACE_OUTPUT = stream; -} - -int -vtrace( +vftracef( const char *const file, const char *const function, const int lineno, + FILE *restrict stream, const enum TraceLevel level, const char *restrict format, - ... + va_list args ) { - int rc = 0; + if (level > LEVEL) { + return; + } - // FIXME: test - if (level < TRACE_LEVEL) { - return rc; + if (fprintf(stream, "%s:%s:%d: ", file, function, lineno) < 0) { + logerr("fprintf() < 0: %s", strerror(errno)); } - if (TRACE_OUTPUT == NULL) { - TRACE_OUTPUT = stderr; + if (vfprintf(stream, format, args) < 0) { + perror(__FILE__ ":vtrace(): vfprintf() < 0"); } - // FIXME: weavify! - if (fprintf(TRACE_OUTPUT, "%s:%s:%d: ", file, function, lineno) < 0) { + if (fprintf(stream, "\n") < 0) { perror(__FILE__ ":vtrace(): fprintf() < 0"); - rc = -1; } +} +void +ftracef( + const char *const file, + const char *const function, + const int lineno, + FILE *restrict stream, + const enum TraceLevel level, + const char *restrict format, + ... +) { va_list args; va_start(args, format); - if (vfprintf(TRACE_OUTPUT, format, args) < 0) { - perror(__FILE__ ":vtrace(): vfprintf() < 0"); - rc = -1; - } + vftracef(file, function, lineno, stream, level, format, args); va_end(args); +} - if (fprintf(TRACE_OUTPUT, "\n") < 0) { - perror(__FILE__ ":vtrace(): fprintf() < 0"); - rc = -1; +void +tracef( + const char *const file, + const char *const function, + const int lineno, + const enum TraceLevel level, + const char *restrict format, + ... +) { + if (STREAM == NULL) { + STREAM = stderr; } + va_list args; + va_start(args, format); + vftracef(file, function, lineno, STREAM, level, format, args); + va_end(args); +} - return rc; +void +trace_set_stream(FILE *stream) { + STREAM = stream; +} + +void +trace_set_level(const enum TraceLevel level) { + assert(level >= TraceLevel_NONE); + assert(level <= TraceLevel_DEBUG); + LEVEL = level; } diff --git a/src/trace.h b/src/trace.h index 220e820..b81e616 100644 --- a/src/trace.h +++ b/src/trace.h @@ -1,26 +1,45 @@ -#define trace(level, ...) vtrace(__FILE__, __func__, __LINE__, level, __VA_ARGS__) -#define debug(...) vtrace(__FILE__, __func__, __LINE__, TraceLevel_DEBUG, __VA_ARGS__) -#define info(...) vtrace(__FILE__, __func__, __LINE__, TraceLevel_INFO, __VA_ARGS__) -#define warning(...) vtrace(__FILE__, __func__, __LINE__, TraceLevel_WARNING, __VA_ARGS__) -#define error(...) vtrace(__FILE__, __func__, __LINE__, TraceLevel_ERROR, __VA_ARGS__) +#define trace(level, ...) tracef(__FILE__, __func__, __LINE__, level, __VA_ARGS__) +#define debug(...) tracef(__FILE__, __func__, __LINE__, TraceLevel_DEBUG, __VA_ARGS__) +#define info(...) tracef(__FILE__, __func__, __LINE__, TraceLevel_INFO, __VA_ARGS__) +#define warning(...) tracef(__FILE__, __func__, __LINE__, TraceLevel_WARNING, __VA_ARGS__) +#define error(...) tracef(__FILE__, __func__, __LINE__, TraceLevel_ERROR, __VA_ARGS__) enum TraceLevel { - TraceLevel_DEBUG = 1, - TraceLevel_INFO = 2, + TraceLevel_NONE = 1, + TraceLevel_ERROR = 2, TraceLevel_WARNING = 3, - TraceLevel_ERROR = 4, - TraceLevel_NONE = 5, + TraceLevel_INFO = 4, + TraceLevel_DEBUG = 5, }; void -set_level(const enum TraceLevel level); +vftracef( + const char *const file, + const char *const function, + const int lineno, + FILE *restrict stream, + const enum TraceLevel level, + const char *restrict format, + va_list args +); + +void +ftracef( + const char *const file, + const char *const function, + const int lineno, + FILE *restrict stream, + const enum TraceLevel level, + const char *restrict format, + ... +); -int -vtrace( +void +tracef( const char *const file, const char *const function, const int lineno, @@ -28,3 +47,9 @@ vtrace( const char *restrict format, ... ); + +void +trace_set_stream(FILE *stream); + +void +trace_set_level(const enum TraceLevel level); @@ -1,4 +1,4 @@ -#include "config.h" +#include <s.h> #include <assert.h> #include <errno.h> @@ -14,7 +14,22 @@ +// https://www.sanfoundry.com/c-program-implement-avl-tree/ + +/* + Implement: + + - AVL tree + - B-tree + - Red-black tree + - Hash array-mapped trie + + Also, persistent variations of all of them. +*/ + + struct Tree { + // struct Data data; const void *const value; const size_t value_size; const struct Tree *left; @@ -24,6 +39,30 @@ struct Tree { +/* +static enum Comparison +cmp(struct Data lhs, struct Data rhs) { + if (lhs.length < rhs.length) { + return Comparison_LESSER; + } + + if (lhs.length > rhs.length) { + return Comparison_GREATER; + } + + const int c = memcmp(lhs.data, rhs.data, lhs.length); + if (c < 0) { + return Comparison_LESSER; + } + + if (c > 0) { + return Comparison_GREATER; + } + + return Comparison_EQUAL; +} +*/ + int tree_new(const size_t value_size, const struct Tree **const out) { int rc = -1; @@ -48,7 +87,8 @@ tree_new(const size_t value_size, const struct Tree **const out) { out: if (rc) { if (ret != NULL) { - freeit((void *)&ret); + free((struct Tree *)ret); + ret = NULL; } } return rc; @@ -70,7 +110,8 @@ tree_free(const struct Tree **const t) { tree_free(&right); } - freeit((void *)t); + free((struct Tree *)(*t)); + *t = NULL; } static void @@ -1,5 +1,12 @@ struct Tree; +/* +struct Data { + size_t length; + void *data; +}; +*/ + int @@ -16,3 +23,6 @@ tree_remove(const struct Tree *const t, const void *const value); bool tree_contains(const struct Tree *const, const void *const value); + +// void * +// tree_search(); @@ -1,4 +1,4 @@ -#include "config.h" +#include <s.h> #include <errno.h> #include <stdio.h> @@ -11,26 +11,8 @@ -const size_t -NULL_TERMINATOR = sizeof((char)'\0'); - -const int -EXIT_USAGE = 2; - - - -void -freeit(const void **const ptr) { - if (ptr == NULL) { - return; - } - - free((void *)*ptr); - *ptr = NULL; -} - int -slurp(const char *const filename, char **out) { +slurp(const char *const filename, size_t *const outlen, char **out) { int rc = -1; FILE *file = NULL; @@ -73,6 +55,7 @@ slurp(const char *const filename, char **out) { } str[size] = '\0'; *out = str; + *outlen = size; rc = 0; out: @@ -84,7 +67,8 @@ out: } if (rc) { if (str != NULL) { - freeit((void *)&str); + free(str); + str = NULL; } } return rc; @@ -1,13 +1,2 @@ -extern const size_t -NULL_TERMINATOR; - -extern const int -EXIT_USAGE; - - - -void -freeit(const void **const ptr); - int -slurp(const char *const filename, char **out); +slurp(const char *const filename, size_t *const outlen, char **out); diff --git a/src/vector.c b/src/vector.c index 385e600..2736820 100644 --- a/src/vector.c +++ b/src/vector.c @@ -1,19 +1,16 @@ -#include "config.h" +#include <s.h> #include <assert.h> #include <errno.h> -#include <locale.h> #include <stdbool.h> #include <stdint.h> #include <stdlib.h> #include <stdio.h> #include <string.h> -#include "catalog.h" #include "i18n.h" #include "logerr.h" #include "math.h" -#include "util.h" #include "vector.h" @@ -55,11 +52,8 @@ vector_new_with( assert(capacity > 0); if (capacity > max_capacity) { - logerr( - _(MSG_ERR_VECTOR_MAX_CAPACITY), - max_capacity, - strerror(EOVERFLOW) - ); + const char *const s = _(MSG_ERR_VECTOR_MAX_CAPACITY); + logerr(s, max_capacity, strerror(EOVERFLOW)); rc = EOVERFLOW; goto out; } @@ -90,10 +84,12 @@ vector_new_with( out: if (rc) { if (ret != NULL) { - freeit((void *)&ret); + free((struct Vector *)ret); + ret = NULL; } if (values != NULL) { - freeit((void *)&values); + free((struct Vector *)values); + values = NULL; } } return rc; @@ -121,8 +117,10 @@ vector_free(const struct Vector **const v) { } const void **values = (*v)->values; - freeit((void *)&values); - freeit((void *)v); + free(values); + values = NULL; + free((struct Vector *)(*v)); + *v = NULL; } size_t @@ -146,12 +144,20 @@ next_capacity(const struct Vector *const v) { } static int -next_size(const struct Vector *const v, const size_t capacity, size_t *const out) { +next_size( + const struct Vector *const v, + const size_t capacity, + size_t *const out +) { return mul_size(v->value_size, capacity, out); } int -vector_nth(const struct Vector *const v, const size_t idx, const void **const out) { +vector_nth( + const struct Vector *const v, + const size_t idx, + const void **const out +) { int rc = -1; const size_t count = vector_count(v); @@ -232,7 +238,8 @@ vector_push_back(const struct Vector *const v, const void *const value) { out: if (rc) { if (new_values != NULL) { - freeit((void *)&new_values); + free(new_values); + new_values = NULL; } } return rc; |