aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Riehs <tristan.riehs@inria.fr>2026-08-04 23:49:56 +0200
committerTristan Riehs <tristan.riehs@inria.fr>2026-08-04 23:49:56 +0200
commitd68c22897c57145800a7b10781d4f14f34e4b63e (patch)
tree4d423b3b2a3275c5b212a5f182d49f3ad3bd6a83
parentd10a8424cbf8e529a1b36287d41f7fe6df353e2f (diff)
Enable using development display libraries
Also add useful routines.
-rw-r--r--src/disp.c79
1 files changed, 72 insertions, 7 deletions
diff --git a/src/disp.c b/src/disp.c
index c4c1cd6..6fb25eb 100644
--- a/src/disp.c
+++ b/src/disp.c
@@ -1,12 +1,76 @@
+#include <assert.h>
#include <dlfcn.h>
#include <limits.h>
-#include <string.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-#include <assert.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
#include "disp.h"
+void
+/* Internals of strbuild. */
+__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);
+}
+
+/* Safely create a formatted string and write it to BUF. BUF shall be a buffer
+ * of size at least SIZE. BUF can be stack-allocated. If the formatting cannot
+ * be performed, exit(3) is called. This function is not meant to be called
+ * directly: the macro strbuild should be used. The code is adapted from the
+ * make_message function of the vsnprintf(3) manual page, section "examples". */
+#define strbuild(buf, fmt, ...) \
+ __strbuild(buf, sizeof(buf), __FILE__, __LINE__, fmt, __VA_ARGS__)
+
+#define strbuild_with_size(buf, size, fmt, ...) \
+ __strbuild(buf, size, __FILE__, __LINE__, fmt, __VA_ARGS__)
+
+int
+file_exists(const char *path)
+{
+ struct stat statbuf __attribute__((unused));
+ int rc = stat(path, &statbuf);
+ if (rc == 0)
+ return 1;
+ else if ((rc == -1) && (errno == ENOENT))
+ return 0;
+ fprintf(stderr, "stat: \"%s\": ", path);
+ perror("");
+ exit(EXIT_FAILURE);
+}
+
+
static void *
load_generic_symbol(struct disp *disp, char *base_name)
{
@@ -57,12 +121,13 @@ load_symbols(struct disp *disp)
struct disp *
get_disp(char *disp_name)
{
- /* displays are shared libraries */
char so_path[128];
- strcpy(so_path, CALCULER_PREFIX);
- strcat(so_path, "/lib/calculer/lib");
- strcat(so_path, disp_name);
- strcat(so_path, ".so");
+ /* local lookup, useful while developing */
+ strbuild(so_path, "./lib%s.so", disp_name);
+
+ if (!file_exists(so_path))
+ strbuild(so_path, "%s/lib/calculer/lib%s.so", CALCULER_PREFIX, disp_name);
+
struct disp *disp = malloc(sizeof(*disp));
disp->so_path = strdup(so_path);
disp->name = disp_name;