aboutsummaryrefslogtreecommitdiff
path: root/src/Cli
diff options
context:
space:
mode:
Diffstat (limited to 'src/Cli')
-rw-r--r--src/Cli/Cli.c102
-rw-r--r--src/Cli/Cli.h30
2 files changed, 132 insertions, 0 deletions
diff --git a/src/Cli/Cli.c b/src/Cli/Cli.c
new file mode 100644
index 0000000..3648493
--- /dev/null
+++ b/src/Cli/Cli.c
@@ -0,0 +1,102 @@
+#include "Cli/Cli.h"
+
+#include "Logger/Logger.h"
+#include "Version/Version.h"
+
+#include <getopt.h>
+#include <stdio.h>
+
+void cli_print_usage(const char *program_name) {
+ fprintf(
+ stderr,
+ "Usage:\n"
+ " %s FILE [-o OUTPUT]\n"
+ " %s -d DIRECTORY [-o OUTPUT] [-f]\n\n"
+ "Options:\n"
+ " -d, --directory DIRECTORY Process a directory recursively\n"
+ " -o, --output OUTPUT Set the output path\n"
+ " -f, --overwrite Overwrite an existing output directory\n"
+ " -l, --log-level LEVEL error, warning, info, debug, or silent\n"
+ " -v, --version Show the program version\n"
+ " -h, --help Show this help\n",
+ program_name, program_name);
+}
+
+static void cli_print_version(void) { printf("yapssg %s\n", yapssg_version); }
+
+static const char *strip_optional_equals(const char *value) {
+ return value != NULL && value[0] == '=' ? value + 1 : value;
+}
+
+CliParseResult cli_parse(int argc, char **argv, CliOptions *options) {
+ static const struct option long_options[] = {
+ {"directory", required_argument, NULL, 'd'},
+ {"output", required_argument, NULL, 'o'},
+ {"overwrite", no_argument, NULL, 'f'},
+ {"force", no_argument, NULL, 'f'},
+ {"log-level", required_argument, NULL, 'l'},
+ {"version", no_argument, NULL, 'v'},
+ {"help", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, 0}};
+ const char *directory = NULL;
+ int option;
+
+ options->input_type = INPUT_TYPE_NONE;
+ options->input_path = NULL;
+ options->output_path = NULL;
+ options->overwrite_output = 0;
+ options->log_level = LOG_LEVEL_INFO;
+
+ while ((option = getopt_long(argc, argv, "d:o:fl:vh", long_options, NULL)) !=
+ -1) {
+ switch (option) {
+ case 'd':
+ directory = strip_optional_equals(optarg);
+ break;
+ case 'o':
+ options->output_path = strip_optional_equals(optarg);
+ break;
+ case 'f':
+ options->overwrite_output = 1;
+ break;
+ case 'l':
+ if (logger_parse_level(optarg, &options->log_level) != 0) {
+ logger_error("unknown log level '%s'", optarg);
+ return CLI_PARSE_ERROR;
+ }
+ break;
+ case 'v':
+ cli_print_version();
+ return CLI_PARSE_VERSION;
+ case 'h':
+ cli_print_usage(argv[0]);
+ return CLI_PARSE_HELP;
+ default:
+ cli_print_usage(argv[0]);
+ return CLI_PARSE_ERROR;
+ }
+ }
+
+ if (directory != NULL) {
+ if (optind != argc || directory[0] == '\0') {
+ logger_error("a directory cannot be combined with a file");
+ return CLI_PARSE_ERROR;
+ }
+ options->input_type = INPUT_TYPE_DIRECTORY;
+ options->input_path = directory;
+ } else {
+ if (optind + 1 != argc) {
+ cli_print_usage(argv[0]);
+ return CLI_PARSE_ERROR;
+ }
+ options->input_type = INPUT_TYPE_FILE;
+ options->input_path = argv[optind];
+ }
+
+ if (options->output_path != NULL && options->output_path[0] == '\0') {
+ logger_error("output path cannot be empty");
+ return CLI_PARSE_ERROR;
+ }
+
+ return CLI_PARSE_OK;
+}
diff --git a/src/Cli/Cli.h b/src/Cli/Cli.h
new file mode 100644
index 0000000..9695fd4
--- /dev/null
+++ b/src/Cli/Cli.h
@@ -0,0 +1,30 @@
+#ifndef YAPSSG_CLI_H
+#define YAPSSG_CLI_H
+
+#include "Logger/Logger.h"
+
+typedef enum {
+ INPUT_TYPE_NONE,
+ INPUT_TYPE_FILE,
+ INPUT_TYPE_DIRECTORY
+} InputType;
+
+typedef enum {
+ CLI_PARSE_ERROR = -1,
+ CLI_PARSE_OK,
+ CLI_PARSE_HELP,
+ CLI_PARSE_VERSION
+} CliParseResult;
+
+typedef struct {
+ InputType input_type;
+ const char *input_path;
+ const char *output_path;
+ int overwrite_output;
+ LogLevel log_level;
+} CliOptions;
+
+CliParseResult cli_parse(int argc, char **argv, CliOptions *options);
+void cli_print_usage(const char *program_name);
+
+#endif