summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2025-01-12 00:14:03 -0300
committerEuAndreh <eu@euandre.org>2025-01-12 14:27:57 -0300
commit44d56f5311f98a8955c67638e7520963dbd4d845 (patch)
treefbb2c58c79f1730ff62c83cef116fb5c0e035dfe /src
parentReplace src/config.h with <s.h>; incorporate changes from other projects (diff)
downloadpindaiba-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.h22
-rw-r--r--src/cmp.c2
-rw-r--r--src/hash.c83
-rw-r--r--src/hash.h6
-rw-r--r--src/i18n.c18
-rw-r--r--src/lib.c4
-rw-r--r--src/lib.h3
-rw-r--r--src/logerr.c52
-rw-r--r--src/logerr.h25
-rw-r--r--src/main.c6
-rw-r--r--src/math.c9
-rw-r--r--src/math.h6
-rw-r--r--src/meta.h.in2
-rw-r--r--src/msgs.c (renamed from src/catalog.c)35
-rw-r--r--src/msgs.h26
-rw-r--r--src/pindaiba.en.msg22
-rw-r--r--src/random.c109
-rw-r--r--src/random.h16
-rw-r--r--src/set.c14
-rw-r--r--src/string.c58
-rw-r--r--src/string.h2
-rw-r--r--src/testing.c31
-rw-r--r--src/testing.h3
-rw-r--r--src/trace.c94
-rw-r--r--src/trace.h49
-rw-r--r--src/tree.c47
-rw-r--r--src/tree.h10
-rw-r--r--src/util.c26
-rw-r--r--src/util.h13
-rw-r--r--src/vector.c39
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[]);
diff --git a/src/cmp.c b/src/cmp.c
index 9784aae..a23de15 100644
--- a/src/cmp.c
+++ b/src/cmp.c
@@ -1,4 +1,4 @@
-#include "config.h"
+#include <s.h>
#include <stddef.h>
diff --git a/src/hash.c b/src/hash.c
index 03fc8df..367376f 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -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);
}
diff --git a/src/hash.h b/src/hash.h
index 4831c4b..874669a 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -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]
);
diff --git a/src/i18n.c b/src/i18n.c
index 5ecc47f..06b828f 100644
--- a/src/i18n.c
+++ b/src/i18n.c
@@ -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);
}
diff --git a/src/lib.c b/src/lib.c
index 6c9503f..daa1eff 100644
--- a/src/lib.c
+++ b/src/lib.c
@@ -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;
diff --git a/src/lib.h b/src/lib.h
index 9ace170..29645a7 100644
--- a/src/lib.h
+++ b/src/lib.h
@@ -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);
diff --git a/src/main.c b/src/main.c
index 3a0b47d..0551400 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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[]) {
diff --git a/src/math.c b/src/math.c
index 143a48d..90cea26 100644
--- a/src/math.c
+++ b/src/math.c
@@ -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;
+}
diff --git a/src/math.h b/src/math.h
index 79b52f0..0cb915f 100644
--- a/src/math.h
+++ b/src/math.h
@@ -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)[]);
diff --git a/src/set.c b/src/set.c
index e2baaed..2d748cd 100644
--- a/src/set.c
+++ b/src/set.c
@@ -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);
diff --git a/src/tree.c b/src/tree.c
index 57b2cd1..41f4601 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -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
diff --git a/src/tree.h b/src/tree.h
index 34e52f4..021b773 100644
--- a/src/tree.h
+++ b/src/tree.h
@@ -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();
diff --git a/src/util.c b/src/util.c
index 7e62755..c88eb7b 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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;
diff --git a/src/util.h b/src/util.h
index 7e7db1f..741f970 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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;