aboutsummaryrefslogtreecommitdiff
path: root/src_c/main.c
diff options
context:
space:
mode:
authorbozo.kopic <bozo@kopic.xyz>2021-12-22 19:35:48 +0100
committerbozo.kopic <bozo@kopic.xyz>2021-12-22 19:35:48 +0100
commit1a19c238e3741931db9e61b6a0b79259b5ed0753 (patch)
tree7e5d705e423583188b346bbb7e7486f808b66bc8 /src_c/main.c
parent923e73a50320792bbedb945b45c54dab12d44708 (diff)
WIP c implementation
Diffstat (limited to 'src_c/main.c')
-rw-r--r--src_c/main.c145
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(&params, &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(&params, &json);
+ if (exit_code) {
+ fprintf(stderr, "error parsing calculation parameters\n");
+ goto cleanup;
+ }
+
+ exit_code = opcut_calculate(args.method, &params, &result);
+ if (exit_code) {
+ fprintf(stderr, "calculation error\n");
+ goto cleanup;
}
- opcut_result_t result = {.params = &params,
- .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(&params);
- free(json.data);
+ opcut_str_destroy(&json);
+ if (output_stream)
+ fclose(output_stream);
+ if (input_stream)
+ fclose(input_stream);
- return res;
+ return exit_code;
}