From ebce03b49c754003013f4831134895e526b88a41 Mon Sep 17 00:00:00 2001 From: klemek Date: Wed, 4 Jun 2025 00:07:05 +0200 Subject: [PATCH] full arg parse --- src/args.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++- src/args.h | 2 - src/generator.c | 3 +- src/generator.h | 4 +- src/main.c | 3 +- src/types.h | 11 ++-- 6 files changed, 154 insertions(+), 14 deletions(-) diff --git a/src/args.c b/src/args.c index b7cc298..99c846b 100644 --- a/src/args.c +++ b/src/args.c @@ -1,16 +1,155 @@ #include "args.h" +#include +#include +#include -const parameters EMPTY_PARAMS = { - 0, 0, NULL, 0, 0.0, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; +void print_help(int status_code) { + puts("usage: mg " + "[--help] " + "[-q] " + "[-w=WIDTH] " + "[-h=HEIGHT] " + "[-o=PATH] " + "[-p=PIXEL_SIZE] " + "[-s=SLOPE] " + "[-c=R,G,B] " + "[-v=R,G,B]\n\n" + "generates a marble-like pattern bitmap image.\n\n" + "options:\n" + " --help show this help message and exit\n" + " -q, --quiet do not print to console\n" + " -w, --width image width (default: 1920)\n" + " -h, --height image height (default: 1080)\n" + " -o, --output output file (default: output.bmp)\n" + " -p, --pixel pixel size (default: random)\n" + " -s, --slope slope [0-255] (default: random)\n" + " -c, --color base color [0-255,0-255,0-255] (default: random)\n" + " -v, --variation base variation [0-255,0-255,0-255] (default: " + "random)"); + exit(status_code); +} + +void invalid_arg(char *arg) { + fprintf(stderr, "invalid argument: '%s'\n\n", arg); + print_help(1); +} + +void invalid_value(char *arg, char *subarg, char *value) { + if (subarg == NULL) { + fprintf(stderr, "invalid value for argument '%s': '%s'\n\n", arg, value); + } else { + fprintf(stderr, "invalid value for argument '%s' %s: '%s'\n\n", arg, subarg, + value); + } + print_help(1); +} + +bool is_arg(char *arg, char *ref) { + return strncmp(arg, ref, strlen(ref)) == 0; +} + +char *get_arg_value(char *arg) { + strtok(arg, "="); // remove first part + return strtok(NULL, "="); +} + +bool is_digit(char c) { return c >= '0' && c <= '9'; } + +bool is_number(char *value) { + if (value == NULL) { + return false; + } + unsigned long value_len = strlen(value); + int i; + for (i = 0; i < value_len; i++) { + if (!is_digit(value[i])) { + return false; + } + } + return value; +} + +void parse_number(char *arg, char *value, unsigned char color[3]) { + char *tmp; + tmp = strtok(value, ","); + if (!is_number(tmp)) { + invalid_value(arg, "(R)", tmp); + } + color[0] = (unsigned char)atoi(tmp); + tmp = strtok(NULL, ","); + if (!is_number(tmp)) { + invalid_value(arg, "(G)", tmp); + } + color[1] = (unsigned char)atoi(tmp); + tmp = strtok(NULL, ","); + if (!is_number(tmp)) { + invalid_value(arg, "(B)", tmp); + } + color[2] = (unsigned char)atoi(tmp); +} parameters parse_args(int argc, char **argv) { parameters params; + params.quiet = false; params.width = 1920; params.height = 1080; params.file_path = "output.bmp"; + params.size = 1; // TODO random + params.slope = 128; // TODO random + params.start[0] = 128; // TODO random + params.start[1] = 128; // TODO random + params.start[2] = 128; // TODO random + params.var[0] = 20; // TODO random + params.var[1] = 20; // TODO random + params.var[2] = 20; // TODO random - // TODO + int i; + char *arg; + char *value; + for (i = 1; i < argc; i++) { + arg = argv[i]; + if (is_arg(arg, "--help")) { + print_help(0); + } else if (is_arg(arg, "-q") || is_arg(arg, "--quiet")) { + params.quiet = true; + } else if (is_arg(arg, "-w") || is_arg(arg, "--width")) { + value = get_arg_value(arg); + if (!is_number(value)) { + invalid_value(arg, NULL, value); + } + params.width = (unsigned long)atol(value); + } else if (is_arg(arg, "-h") || is_arg(arg, "--height")) { + value = get_arg_value(arg); + if (!is_number(value)) { + invalid_value(arg, NULL, value); + } + params.height = (unsigned long)atol(value); + } else if (is_arg(arg, "-o") || is_arg(arg, "--output")) { + value = get_arg_value(arg); + params.file_path = value; + } else if (is_arg(arg, "-p") || is_arg(arg, "--pixel")) { + value = get_arg_value(arg); + if (!is_number(value)) { + invalid_value(arg, NULL, value); + } + params.size = (unsigned char)atoi(value); + } else if (is_arg(arg, "-s") || is_arg(arg, "--slope")) { + value = get_arg_value(arg); + if (!is_number(value)) { + invalid_value(arg, NULL, value); + } + params.size = (unsigned char)atoi(value); + } else if (is_arg(arg, "-c") || is_arg(arg, "--color")) { + value = get_arg_value(arg); + parse_number(arg, value, params.start); + } else if (is_arg(arg, "-v") || is_arg(arg, "--variation")) { + value = get_arg_value(arg); + parse_number(arg, value, params.start); + } else { + invalid_arg(arg); + } + } return params; } \ No newline at end of file diff --git a/src/args.h b/src/args.h index 65563af..bb1dd73 100644 --- a/src/args.h +++ b/src/args.h @@ -1,6 +1,4 @@ #include "types.h" -#include -#include #ifndef ARGS_H #define ARGS_H diff --git a/src/generator.c b/src/generator.c index 9a92aa8..ede8e02 100644 --- a/src/generator.c +++ b/src/generator.c @@ -10,8 +10,9 @@ void generate_line(unsigned long y, char *data_buffer) { memset(data_buffer, y, global_params.width * COLOR_DEPTH); } -void generate(parameters params) { +int generate(parameters params) { global_params = params; bmp_generate(params.width, params.height, COLOR_DEPTH, params.file_path, generate_line); + return 0; } \ No newline at end of file diff --git a/src/generator.h b/src/generator.h index 63cbc56..677293e 100644 --- a/src/generator.h +++ b/src/generator.h @@ -1,8 +1,8 @@ -#include "args.h" +#include "types.h" #ifndef GENERATOR_H #define GENERATOR_H -void generate(parameters params); +int generate(parameters params); #endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index f35de5c..5fe0fcf 100644 --- a/src/main.c +++ b/src/main.c @@ -4,6 +4,5 @@ int main(int argc, char **argv) { parameters params; params = parse_args(argc, argv); - generate(params); - return 0; + return generate(params); } \ No newline at end of file diff --git a/src/types.h b/src/types.h index fe7be35..0e90411 100644 --- a/src/types.h +++ b/src/types.h @@ -1,14 +1,17 @@ +#include + #ifndef TYPES_H #define TYPES_H struct Parameters { + bool quiet; unsigned long width; unsigned long height; char *file_path; - unsigned int size; - float slope; - float start[3]; - float var[3]; + unsigned char size; + unsigned char slope; + unsigned char start[3]; + unsigned char var[3]; }; typedef struct Parameters parameters;