1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <argparse.h>
#include "common.h"
#include "csp.h"
typedef struct {
opcut_method_t method;
char *input_path;
char *output_path;
} args_t;
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];
}
} 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;
}
int main(int argc, char **argv) {
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;
}
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;
}
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;
}
opcut_sort_params(¶ms);
exit_code = opcut_calculate(args.method, ¶ms, &result);
if (exit_code) {
fprintf(stderr, "calculation error\n");
goto cleanup;
}
exit_code = opcut_result_write(&result, output_stream);
cleanup:
opcut_result_destroy(&result);
opcut_params_destroy(¶ms);
opcut_str_destroy(&json);
if (output_stream)
fclose(output_stream);
if (input_stream)
fclose(input_stream);
return exit_code;
}
|