aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-08-30 00:59:52 +0200
committerhachem <im@hachem.wtf>2026-08-30 00:59:52 +0200
commit11d3e0294d6c4d657c45c6f8de23dd628b61680d (patch)
treef58b7b57efe3447dbbe0f07fd47c30a8fc5d44e7 /src
parentcd04e59647a9440e6b362b3a46b36f46bf2b2576 (diff)
add: command-line argument parser
Diffstat (limited to 'src')
-rw-r--r--src/cli/args.c119
-rw-r--r--src/cli/args.h26
-rw-r--r--src/main.c20
3 files changed, 163 insertions, 2 deletions
diff --git a/src/cli/args.c b/src/cli/args.c
new file mode 100644
index 0000000..501406f
--- /dev/null
+++ b/src/cli/args.c
@@ -0,0 +1,119 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "cli/args.h"
+
+#define HDASS_VERSION "0.1.0"
+
+static bool match_assembler(const char* name, enum Assembler* out)
+{
+ if (strcmp(name, "nasm") == 0)
+ {
+ *out = ASSEMBLER_NASM;
+ return true;
+ }
+ if (strcmp(name, "fasm") == 0)
+ {
+ *out = ASSEMBLER_FASM;
+ return true;
+ }
+ if (strcmp(name, "masm") == 0)
+ {
+ *out = ASSEMBLER_MASM;
+ return true;
+ }
+ return false;
+}
+
+void print_version(void)
+{
+ printf("hdass %s\n", HDASS_VERSION);
+}
+
+void print_usage(const char* program)
+{
+ printf("hachem's dumb assembly super set\n\n");
+ printf("usage: %s <input.hdass> [options]\n\n", program);
+ printf("options:\n");
+ printf(" -o, --output <file> write output to <file> (default: stdout)\n");
+ printf(" -t, --target <name> target assembler: nasm, fasm, masm (default: nasm)\n");
+ printf(" -h, --help print this help and exit\n");
+ printf(" -v, --version print version and exit\n");
+}
+
+enum ParseResult parse_args(int argc, char** argv, struct Args* args)
+{
+ const char* program = argv[0];
+
+ args->input_path = NULL;
+ args->output_path = NULL;
+ args->target = ASSEMBLER_NASM;
+
+ for (int i = 1; i < argc; i += 1)
+ {
+ const char* arg = argv[i];
+
+ if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0)
+ {
+ print_usage(program);
+ return PARSE_EXIT;
+ }
+
+ if (strcmp(arg, "-v") == 0 || strcmp(arg, "--version") == 0)
+ {
+ print_version();
+ return PARSE_EXIT;
+ }
+
+ if (strcmp(arg, "-o") == 0 || strcmp(arg, "--output") == 0)
+ {
+ i += 1;
+ if (i >= argc)
+ {
+ fprintf(stderr, "error: '%s' requires an argument\n", arg);
+ return PARSE_ERROR;
+ }
+ args->output_path = argv[i];
+ continue;
+ }
+
+ if (strcmp(arg, "-t") == 0 || strcmp(arg, "--target") == 0)
+ {
+ i += 1;
+ if (i >= argc)
+ {
+ fprintf(stderr, "error: '%s' requires an argument\n", arg);
+ return PARSE_ERROR;
+ }
+ if (!match_assembler(argv[i], &args->target))
+ {
+ fprintf(stderr, "error: unknown target '%s'\n", argv[i]);
+ return PARSE_ERROR;
+ }
+ continue;
+ }
+
+ if (arg[0] == '-')
+ {
+ fprintf(stderr, "error: unknown option '%s'\n", arg);
+ return PARSE_ERROR;
+ }
+
+ if (args->input_path != NULL)
+ {
+ fprintf(stderr, "error: multiple input files given ('%s' and '%s')\n", args->input_path, arg);
+ return PARSE_ERROR;
+ }
+
+ args->input_path = arg;
+ }
+
+ if (args->input_path == NULL)
+ {
+ fprintf(stderr, "error: no input file given\n");
+ return PARSE_ERROR;
+ }
+
+ return PARSE_OK;
+}
diff --git a/src/cli/args.h b/src/cli/args.h
new file mode 100644
index 0000000..f80b736
--- /dev/null
+++ b/src/cli/args.h
@@ -0,0 +1,26 @@
+#pragma once
+
+enum Assembler
+{
+ ASSEMBLER_NASM,
+ ASSEMBLER_FASM,
+ ASSEMBLER_MASM,
+};
+
+enum ParseResult
+{
+ PARSE_OK,
+ PARSE_EXIT,
+ PARSE_ERROR,
+};
+
+struct Args
+{
+ const char* input_path;
+ const char* output_path;
+ enum Assembler target;
+};
+
+enum ParseResult parse_args(int argc, char** argv, struct Args* args);
+void print_usage(const char* program);
+void print_version(void);
diff --git a/src/main.c b/src/main.c
index 902e18a..a14d2ba 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,6 +1,22 @@
#include <stdio.h>
-int main(void)
+#include "cli/args.h"
+
+int main(int argc, char** argv)
{
- puts("type shi");
+ struct Args args;
+
+ enum ParseResult result = parse_args(argc, argv, &args);
+ if (result == PARSE_EXIT)
+ return 0;
+ if (result == PARSE_ERROR)
+ return 1;
+
+ static const char* target_names[] = { "nasm", "fasm", "masm" };
+
+ printf("input: %s\n", args.input_path);
+ printf("output: %s\n", args.output_path != NULL ? args.output_path : "<stdout>");
+ printf("target: %s\n", target_names[args.target]);
+
+ return 0;
}