From 22141040a52c362a60f4feb7d03e4f7d346dcae3 Mon Sep 17 00:00:00 2001 From: JP Appel Date: Fri, 26 Apr 2024 13:19:12 -0400 Subject: add cli options to renderer, improved grid_print --- src/fractal_render.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 123 insertions(+), 7 deletions(-) (limited to 'src/fractal_render.c') diff --git a/src/fractal_render.c b/src/fractal_render.c index bac8202..b9ffa09 100644 --- a/src/fractal_render.c +++ b/src/fractal_render.c @@ -1,18 +1,134 @@ #include +#include +#include +#include +#include + #include "grids.h" #include "precision.h" #include "fractal_render.h" +void print_usage(FILE* file, const char* program_name) { + fprintf(file, "Usage: %s -i input.grid [-r renderer] [-o output.ext]\n", program_name); +} + +void print_help(){ + printf("Options:\n" + " -i, --input the grid to be rendered, if the file name is '-' reads from stdin\n" + " -r, --renderer the renderer to use, defaults to the text renderer\n" + " renderers: txt, png (TODO), gif (TODO, with additional features)\n" + " -o, --output the file to output the result of rendering, if not given defaults to output.\n" + " where is the renderer used\n" + " -v, --verbose verbose output\n" + " -h, --help prints this help and exits\n" + ); +} + +jmp_buf error_buffer; + +/* + * Error logger that causes used file streams to be closed + */ +void error_exit(const char* message, const char* issue) { + if(issue){ + fprintf(stderr, "%s: %s\n", message, issue); + } + else { + fprintf(stderr, "%s\n", message); + } + longjmp(error_buffer, 1); +} + +/* + * Cleanup io files and a grid + */ +void cleanup(FILE* output_file, FILE* input_file, grid_t* grid) { + if(output_file) fclose(output_file); + // closing stdin is not recommended, can supposedly cause odd behvaior + if(input_file && input_file != stdin) fclose(input_file); + if(grid) free_grid(grid); +} + + int main(const int argc, char* argv[]){ - char* input_file = "test.grid"; - FILE* file = fopen(input_file, "rb"); - grid_t* grid = read_grid(file); - fclose(file); + char* input_filename = "fractal.grid"; + char* output_filename = "fractal.txt"; + renderer_func renderer = print_grid; + bool verbose = false; + + static struct option long_options[] = { + {"input", required_argument, NULL, 'i'}, + {"renderer", required_argument, NULL, 'r'}, + {"output", required_argument, NULL, 'o'}, + {"verbose", no_argument, NULL, 'v'}, + {"help", no_argument, NULL, 'h'}, + {0, 0, 0, 0} + }; + + int opt; + while((opt = getopt_long(argc, argv, "i:r:o:vh", long_options, NULL)) != -1){ + switch(opt){ + case 'i': + input_filename = optarg; + break; + case 'r': + //TODO: update with other renderers + renderer = print_grid; + break; + case 'o': + output_filename = optarg; + break; + case 'v': + verbose = true; + break; + case 'h': + print_usage(stdout, argv[0]); + print_help(); + return 0; + default: + print_usage(stderr, argv[0]); + fprintf(stderr, "See --help for more info\n"); + return 1; + + } + } + //TODO: logic to set output_filename if o flag is not used + + FILE* input_file = NULL; + FILE* output_file = NULL; + grid_t* grid = NULL; + + if (setjmp(error_buffer) != 0) { + cleanup(output_file, input_file, grid); + exit(EXIT_FAILURE); + } + + if(strcmp(output_filename, "-") == 0){ + output_file = stdout; + } + else { + output_file = fopen(output_filename, "wb"); + if (!output_file) { error_exit("Error opening output file", output_filename); } + } + + if(strcmp(input_filename, "-") == 0){ + grid = read_grid(stdin); + if (!grid) { error_exit("Error reading from stdin", NULL); } + } + else { + input_file = fopen(input_filename, "rb"); + if (!input_file) { error_exit("Error opening input file", input_filename); } + grid = read_grid(input_file); + if (!grid) { error_exit("Error reading from file", input_filename); } + } + + if(verbose){ + print_grid_info(grid); + } - if(!grid) return 1; + renderer(output_file, grid); - print_grid_info(grid); + cleanup(output_file, input_file, grid); - free_grid(grid); return 0; } -- cgit v1.2.3