diff options
| author | bozo.kopic <bozo@kopic.xyz> | 2021-12-22 19:35:48 +0100 |
|---|---|---|
| committer | bozo.kopic <bozo@kopic.xyz> | 2021-12-22 19:35:48 +0100 |
| commit | 1a19c238e3741931db9e61b6a0b79259b5ed0753 (patch) | |
| tree | 7e5d705e423583188b346bbb7e7486f808b66bc8 /src_c/main.c | |
| parent | 923e73a50320792bbedb945b45c54dab12d44708 (diff) | |
WIP c implementation
Diffstat (limited to 'src_c/main.c')
| -rw-r--r-- | src_c/main.c | 145 |
1 files changed, 113 insertions, 32 deletions
diff --git a/src_c/main.c b/src_c/main.c index 9cc71ed..9648f7c 100644 --- a/src_c/main.c +++ b/src_c/main.c @@ -1,24 +1,74 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <argparse.h> #include "common.h" +#include "csp.h" -static int read_stdin(opcut_str_t *json) { - size_t json_data_size = 0; - json->data = NULL; - json->len = 0; +typedef struct { + opcut_method_t method; + char *input_path; + char *output_path; +} args_t; - while (!(json->len < json_data_size)) { - char *old_json_data = json->data; - json_data_size += 4096; - json->data = realloc(json->data, json_data_size); - if (!json->data) { - free(old_json_data); - return OPCUT_ERROR; + +static int parse_args(args_t *args, int argc, char **argv) { + char *method = NULL; + char *output_path = NULL; + + char *usages[] = { + "opcut-calculate [options] [[--] -|path]", + NULL, + }; + + struct argparse_option options[] = { + OPT_HELP(), OPT_STRING(0, "method", &method, "calculate method"), + OPT_STRING(0, "output", &output_path, "output path"), OPT_END()}; + + struct argparse argparse; + argparse_init(&argparse, options, (const char *const *)usages, 0); + argc = argparse_parse(&argparse, argc, (const char **)argv); + + if (method && strcmp(method, "greedy") == 0) { + args->method = OPCUT_METHOD_GREEDY; + } else if (method && strcmp(method, "forward_greedy") == 0) { + args->method = OPCUT_METHOD_FORWARD_GREEDY; + } else { + return OPCUT_ERROR; + } + + if (!argc) { + args->input_path = NULL; + } else if (argc == 1) { + if (strcmp(argv[0], "-") == 0) { + args->input_path = NULL; + } else { + args->input_path = argv[0]; } - json->len += - fread(json->data + json->len, 1, json_data_size - json->len, stdin); + } else { + return OPCUT_ERROR; + } + + if (output_path && strcmp(output_path, "-") == 0) { + args->output_path = NULL; + } else { + args->output_path = output_path; + } + + return OPCUT_SUCCESS; +} + + +static int read_stream(FILE *stream, opcut_str_t *json) { + size_t size = 0; + + while (!(json->len < size)) { + size += 4096; + if (opcut_str_resize(json, size)) + return OPCUT_ERROR; + + json->len += fread(json->data + json->len, 1, size - json->len, stream); } return OPCUT_SUCCESS; @@ -26,32 +76,63 @@ static int read_stdin(opcut_str_t *json) { int main(int argc, char **argv) { - char *method = NULL; - for (size_t i = 1; i < argc - 1; ++i) { - if (strcmp("--method", argv[i]) == 0) - method = argv[++i]; + args_t args; + FILE *input_stream = NULL; + FILE *output_stream = NULL; + opcut_str_t json = OPCUT_STR_EMPTY; + opcut_params_t params = OPCUT_PARAMS_EMPTY; + opcut_result_t result = OPCUT_RESULT_EMPTY; + int exit_code; + + exit_code = parse_args(&args, argc, argv); + if (exit_code) { + fprintf(stderr, "error parsing command line arguments\n"); + goto cleanup; } - opcut_str_t json; - if (!read_stdin(&json)) - return OPCUT_ERROR; + input_stream = (args.input_path ? fopen(args.input_path, "r") : stdin); + if (!input_stream) { + fprintf(stderr, "error opening input stream\n"); + exit_code = OPCUT_ERROR; + goto cleanup; + } - opcut_params_t params; - if (!opcut_params_init(¶ms, &json)) { - free(json.data); - return OPCUT_ERROR; + output_stream = (args.output_path ? fopen(args.output_path, "w") : stdout); + if (!output_stream) { + fprintf(stderr, "error opening output stream\n"); + exit_code = OPCUT_ERROR; + goto cleanup; + } + + exit_code = read_stream(input_stream, &json); + if (exit_code) { + fprintf(stderr, "error reading input stream\n"); + goto cleanup; + } + + exit_code = opcut_params_init(¶ms, &json); + if (exit_code) { + fprintf(stderr, "error parsing calculation parameters\n"); + goto cleanup; + } + + exit_code = opcut_calculate(args.method, ¶ms, &result); + if (exit_code) { + fprintf(stderr, "calculation error\n"); + goto cleanup; } - opcut_result_t result = {.params = ¶ms, - .used = NULL, - .used_len = 0, - .unused = NULL, - .unused_len = 0}; + exit_code = opcut_result_write(&result, output_stream); - size_t res = opcut_result_write(&result, stdout); +cleanup: + opcut_result_destroy(&result); opcut_params_destroy(¶ms); - free(json.data); + opcut_str_destroy(&json); + if (output_stream) + fclose(output_stream); + if (input_stream) + fclose(input_stream); - return res; + return exit_code; } |
