diff options
| -rw-r--r-- | .gitignore | 5 | ||||
| -rw-r--r-- | src/cli/args.c | 119 | ||||
| -rw-r--r-- | src/cli/args.h | 26 | ||||
| -rw-r--r-- | src/main.c | 20 |
4 files changed, 168 insertions, 2 deletions
@@ -7,3 +7,8 @@ Makefile *.sln *.vcxproj *.vcxproj.* + +compile_commands.json +compile_flags.txt +.clangd + 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); @@ -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; } |
