commit 38ff1f2b6218ac5190427e15da92ed1bf5f24e51
parent 61bc2e57f2ea34e377d18719e7bce170fe8a91e2
Author: finwo <finwo@pm.me>
Date: Wed, 7 Oct 2026 01:49:00 +0200
multi-call binary setup
Diffstat:
4 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/src/cli/help.c b/src/cli/help.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+#include "registry.h"
+
+int main_help(int argc, char *argv[]) {
+ (void)argc;
+ (void)argv;
+ fprintf(stdout, "hi there\n");
+ return 0;
+}
+
+__attribute__((constructor))
+static void register_help(void) {
+ cli_register("help", main_help);
+}
diff --git a/src/cli/registry.c b/src/cli/registry.c
@@ -0,0 +1,38 @@
+#include <stdlib.h>
+#include <string.h>
+#include "registry.h"
+
+#define CLI_MAX 32
+
+static const char *cli_names[CLI_MAX];
+static cli_main_fn cli_fns[CLI_MAX];
+static int cli_count = 0;
+
+void cli_register(const char *name, cli_main_fn fn) {
+ if (cli_count >= CLI_MAX) return;
+ cli_names[cli_count] = name;
+ cli_fns[cli_count] = fn;
+ cli_count++;
+}
+
+cli_main_fn cli_find(const char *name) {
+ for (int i = 0; i < cli_count; i++) {
+ if (!strcmp(cli_names[i], name)) return cli_fns[i];
+ }
+ return NULL;
+}
+
+char * cli_registered() {
+ char *out;
+ int len=1;
+ for(int i=0; i<cli_count; i++) {
+ if (i) len+=2;
+ len+=strlen(cli_names[i]);
+ }
+ out = calloc(1, len);
+ for(int i=0; i<cli_count; i++) {
+ if (i) strcat(out, ", ");
+ strcat(out, cli_names[i]);
+ }
+ return out;
+}
diff --git a/src/cli/registry.h b/src/cli/registry.h
@@ -0,0 +1,10 @@
+#ifndef __SFINX_CLI_REGISTRY_H__
+#define __SFINX_CLI_REGISTRY_H__
+
+typedef int (*cli_main_fn)(int argc, char **argv);
+
+void cli_register(const char *name, cli_main_fn fn);
+cli_main_fn cli_find(const char *name);
+char * cli_registered();
+
+#endif // __SFINX_CLI_REGISTRY_H__
diff --git a/src/main.c b/src/main.c
@@ -1,3 +1,30 @@
-int main() {
- return 42;
+#include <libgen.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cli/registry.h"
+
+int main(int argc, char *argv[]) {
+ const char *prog = basename(argv[0]);
+
+ cli_main_fn fn = cli_find(prog);
+ if (fn) return fn(argc, argv);
+
+ // Not argv[0], see if it's given as subcommand
+ if (argc > 1 && (fn = cli_find(argv[1]))) {
+ char **shifted = malloc(sizeof(char *) * (size_t)argc);
+ if (!shifted) {
+ fprintf(stderr, "out of memory\n");
+ return 1;
+ }
+ shifted[0] = argv[1];
+ for (int i = 2; i < argc; i++) shifted[i - 1] = argv[i];
+ int rc = fn(argc - 1, shifted);
+ free(shifted);
+ return rc;
+ }
+
+ fprintf(stderr, "%s: unknown command: %s\n", argv[0], prog);
+ fprintf(stderr, "available commands: %s\n", cli_registered());
+ return 1;
}