aboutsummaryrefslogtreecommitdiff
path: root/src/utils.c
diff options
context:
space:
mode:
authorTristan Riehs <tristan.riehs@inria.fr>2026-04-26 12:07:39 +0200
committerTristan Riehs <tristan.riehs@inria.fr>2026-04-26 12:07:39 +0200
commit2991c0b3560781344488680625954aa3ef0893c6 (patch)
treeb5bc2048e83453e8c7b5a2d2677161c4cc4847f2 /src/utils.c
parentd2fb6a8aac6abe5bfe4b4ea7f2528d119afbc8c6 (diff)
Create a "utils" module
Also put configuration macros in a dedicated header. In the future the configuration will be read at execution time.
Diffstat (limited to 'src/utils.c')
-rw-r--r--src/utils.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/utils.c b/src/utils.c
new file mode 100644
index 0000000..a1fc5b9
--- /dev/null
+++ b/src/utils.c
@@ -0,0 +1,107 @@
+#include <assert.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "system.h"
+#include "utils.h"
+
+void __strbuild(char *buf, int size,
+ const char *file, int line,
+ const char *fmt, ...)
+{
+ va_list ap;
+ int len;
+
+ va_start(ap, fmt);
+ len = vsnprintf(NULL, 0, fmt, ap);
+ va_end(ap);
+
+ if (len < 0) {
+ fprintf(stderr, "%s:%d: ", file, line);
+ perror("");
+ exit(EXIT_FAILURE);
+ }
+ if (len >= size) {
+ fprintf(stderr, "%s:%d: error: not enough space, "
+ "have %d, need at least %d\n",
+ file, line,
+ size, len + 1);
+ exit(EXIT_FAILURE);
+ }
+
+ va_start(ap, fmt);
+ len = vsnprintf(buf, size, fmt, ap);
+ va_end(ap);
+
+ assert(len >= 0);
+}
+
+int str_has_suffix(const char *str, const char *suffix)
+{
+ int str_len = strlen(str);
+ int suffix_len = strlen(suffix);
+ return ((str_len > suffix_len)
+ && (strcmp(str + str_len - suffix_len, suffix) == 0));
+}
+
+void assert_db_exists(void)
+{
+ if (file_exists(DATABASE_PATH))
+ return;
+
+ if (errno == ENOENT) {
+ fprintf(stderr,
+ "ftag: database not found at \"%s\", "
+ "have you run \"ftag init\"?\n",
+ DATABASE_PATH);
+ }
+ else {
+ perror(DATABASE_PATH);
+ }
+ exit(EXIT_FAILURE);
+}
+
+uint32_t sum(const char *file)
+{
+ FILE *stream = fopen(file, "r");
+ uint8_t buf[4096];
+ size_t buf_len;
+ uint32_t sum = 5381;
+ if (!file) {
+ fprintf(stderr, "fopen: \"%s\": ", file);
+ perror("");
+ exit(EXIT_FAILURE);
+ }
+ while ((buf_len = fread(&buf, 1, sizeof(buf), stream)) != 0) {
+ for (int i = 0; i < buf_len; i++) {
+ uint8_t next = buf[i];
+ sum = sum*33 + next;
+ }
+ }
+ if (ferror(stream)) {
+ fprintf(stderr, "fread: \"%s\": ", file);
+ perror("");
+ exit(EXIT_FAILURE);
+ }
+ fclose(stream);
+ return sum;
+}
+
+time_t time_from_str(const char *str)
+{
+ int rc;
+ struct tm tm;
+ memset(&tm, 0, sizeof(tm));
+ rc = sscanf(str, "%d-%d-%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday);
+ if (rc <= 0) {
+ perror("sscanf");
+ exit(EXIT_FAILURE);
+ }
+ tm.tm_year -= 1900;
+ tm.tm_mon -= 1;
+ return mktime(&tm);
+}