diff options
Diffstat (limited to 'src/Cli')
| -rw-r--r-- | src/Cli/Cli.c | 102 | ||||
| -rw-r--r-- | src/Cli/Cli.h | 30 |
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 |
