From ba11946be5d900191c545ba351f6d537f9e85452 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Tue, 10 Nov 2020 17:25:43 +0100 Subject: [PATCH] add option parsing --- meson.build | 2 ++ src/main.c | 11 ++++++++--- src/options.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/options.h | 15 +++++++++++++++ 4 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 src/options.c create mode 100644 src/options.h diff --git a/meson.build b/meson.build index 3c37359..23c07a8 100644 --- a/meson.build +++ b/meson.build @@ -11,10 +11,12 @@ project( sources = [ 'src/image.c', 'src/main.c', + 'src/options.c', 'src/ppm.c', ] executable( 'buddhabrot', sources : sources, + c_args : '-D_XOPEN_SOURCE', ) diff --git a/src/main.c b/src/main.c index 03cd9d9..d83f1b7 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ #include #include "image.h" +#include "options.h" #include "ppm.h" static void fill_image(struct image *image) { @@ -16,13 +17,17 @@ static void fill_image(struct image *image) { } } -int main(void) { - struct image *image = create_image(960, 540); +int main(int argc, char *argv[]) { + struct options opt = parse_options(&argc, &argv); + + struct image *image = create_image(opt.w, opt.h); if (!image) err(EXIT_FAILURE, "could not allocate image"); fill_image(image); - print_ppm(image, stdout); + print_ppm(image, opt.output); + + fclose(opt.output); destroy_image(image); return EXIT_SUCCESS; diff --git a/src/options.c b/src/options.c new file mode 100644 index 0000000..44f9d1d --- /dev/null +++ b/src/options.c @@ -0,0 +1,43 @@ +#include "options.h" + +#include +#include +#include + +struct options parse_options(int *argc, char **argv[]) { + struct options opts = { + .output = stdout, + .w = 960, + .h = 540, + }; + + opterr = 0; // Deactivate error message from `getopt` + + int opt; + while ((opt = getopt(*argc, *argv, "h:o:w:")) != -1) { + switch (opt) { + case 'h': + if (!sscanf(optarg, "%zu", &opts.h)) + errx(EXIT_FAILURE, "could not parse height"); + break; + case 'o': + if (!freopen(optarg, "w", opts.output)) + err(EXIT_FAILURE, "could not open output file"); + break; + case 'w': + if (!sscanf(optarg, "%zu", &opts.w)) + errx(EXIT_FAILURE, "could not parse width"); + break; + default: + fprintf(stderr, "Usage: %s [-o FILE] [-h HEIGHT] [-w WIDTH]\n", + (*argv)[0]); + exit(EXIT_FAILURE); + } + } + + + *argc -= optind; + *argv += optind; + + return opts; +} diff --git a/src/options.h b/src/options.h new file mode 100644 index 0000000..2cf0b68 --- /dev/null +++ b/src/options.h @@ -0,0 +1,15 @@ +#ifndef OPTIONS_H +#define OPTIONS_H + +#include +#include + +struct options { + FILE *output; + size_t w; + size_t h; +}; + +struct options parse_options(int *argc, char **argv[]); + +#endif /* !OPTIONS_H */