diff options
Diffstat (limited to 'shell.c')
| -rw-r--r-- | shell.c | 97 |
1 files changed, 47 insertions, 50 deletions
| @@ -1,5 +1,6 @@ | |||
| 1 | #include <inttypes.h> | 1 | #include <inttypes.h> |
| 2 | #include <errno.h> | 2 | #include <errno.h> |
| 3 | #include <stdarg.h> | ||
| 3 | #include <stdbool.h> | 4 | #include <stdbool.h> |
| 4 | #include <stdio.h> | 5 | #include <stdio.h> |
| 5 | #include <stdlib.h> | 6 | #include <stdlib.h> |
| @@ -28,7 +29,6 @@ typedef struct { | |||
| 28 | int8_t maxmoves; | 29 | int8_t maxmoves; |
| 29 | int8_t optimal; | 30 | int8_t optimal; |
| 30 | int64_t maxsolutions; | 31 | int64_t maxsolutions; |
| 31 | int64_t datasize; /* Option for gendata + solve, TODO change? */ | ||
| 32 | } args_t; | 32 | } args_t; |
| 33 | 33 | ||
| 34 | static void print_cube_result(int64_t, char [static 22]); | 34 | static void print_cube_result(int64_t, char [static 22]); |
| @@ -39,9 +39,7 @@ static int64_t inverse_exec(args_t *); | |||
| 39 | static int64_t applymoves_exec(args_t *); | 39 | static int64_t applymoves_exec(args_t *); |
| 40 | static int64_t applytrans_exec(args_t *); | 40 | static int64_t applytrans_exec(args_t *); |
| 41 | static int64_t frommoves_exec(args_t *); | 41 | static int64_t frommoves_exec(args_t *); |
| 42 | static int64_t readcube_exec(args_t *); | 42 | static int64_t convert_exec(args_t *); |
| 43 | static int64_t writecube_exec(args_t *); | ||
| 44 | static int64_t convertcube_exec(args_t *); | ||
| 45 | static int64_t datasize_exec(args_t *); | 43 | static int64_t datasize_exec(args_t *); |
| 46 | static int64_t gendata_exec(args_t *); | 44 | static int64_t gendata_exec(args_t *); |
| 47 | static int64_t solve_exec(args_t *); | 45 | static int64_t solve_exec(args_t *); |
| @@ -76,9 +74,7 @@ struct { | |||
| 76 | COMMAND("applymoves", applymoves_exec), | 74 | COMMAND("applymoves", applymoves_exec), |
| 77 | COMMAND("applytrans", applytrans_exec), | 75 | COMMAND("applytrans", applytrans_exec), |
| 78 | COMMAND("frommoves", frommoves_exec), | 76 | COMMAND("frommoves", frommoves_exec), |
| 79 | COMMAND("readcube", readcube_exec), | 77 | COMMAND("convert", convert_exec), |
| 80 | COMMAND("writecube", writecube_exec), | ||
| 81 | COMMAND("convertcube", convertcube_exec), | ||
| 82 | COMMAND("datasize", datasize_exec), | 78 | COMMAND("datasize", datasize_exec), |
| 83 | COMMAND("gendata", gendata_exec), | 79 | COMMAND("gendata", gendata_exec), |
| 84 | COMMAND("solve", solve_exec), | 80 | COMMAND("solve", solve_exec), |
| @@ -199,43 +195,19 @@ frommoves_exec(args_t *args) | |||
| 199 | char result[22]; | 195 | char result[22]; |
| 200 | int64_t ret; | 196 | int64_t ret; |
| 201 | 197 | ||
| 202 | ret = nissy_frommoves(args->str_trans, result); | 198 | ret = nissy_frommoves(args->str_moves, result); |
| 203 | print_cube_result(ret, result); | 199 | print_cube_result(ret, result); |
| 204 | 200 | ||
| 205 | return ret; | 201 | return ret; |
| 206 | } | 202 | } |
| 207 | 203 | ||
| 208 | static int64_t | 204 | static int64_t |
| 209 | readcube_exec(args_t *args) | 205 | convert_exec(args_t *args) |
| 210 | { | ||
| 211 | char result[22]; | ||
| 212 | int64_t ret; | ||
| 213 | |||
| 214 | ret = nissy_readcube(args->str_format, args->str_cube, result); | ||
| 215 | print_cube_result(ret, result); | ||
| 216 | |||
| 217 | return ret; | ||
| 218 | } | ||
| 219 | |||
| 220 | static int64_t | ||
| 221 | writecube_exec(args_t *args) | ||
| 222 | { | ||
| 223 | char result[PRINTCUBE_BUFFER_SIZE]; | ||
| 224 | int64_t ret; | ||
| 225 | |||
| 226 | ret = nissy_writecube(args->str_format, args->str_cube, result); | ||
| 227 | print_str_result(ret, result); | ||
| 228 | |||
| 229 | return ret; | ||
| 230 | } | ||
| 231 | |||
| 232 | static int64_t | ||
| 233 | convertcube_exec(args_t *args) | ||
| 234 | { | 206 | { |
| 235 | char result[PRINTCUBE_BUFFER_SIZE]; | 207 | char result[PRINTCUBE_BUFFER_SIZE]; |
| 236 | int64_t ret; | 208 | int64_t ret; |
| 237 | 209 | ||
| 238 | ret = nissy_convertcube( | 210 | ret = nissy_convert( |
| 239 | args->str_format_in, args->str_format_out, args->str_cube, result); | 211 | args->str_format_in, args->str_format_out, args->str_cube, result); |
| 240 | print_str_result(ret, result); | 212 | print_str_result(ret, result); |
| 241 | 213 | ||
| @@ -275,14 +247,17 @@ gendata_exec(args_t *args) | |||
| 275 | 247 | ||
| 276 | if (tablepaths[i] == NULL) { | 248 | if (tablepaths[i] == NULL) { |
| 277 | fprintf(stderr, "Cannot write data to file\n"); | 249 | fprintf(stderr, "Cannot write data to file\n"); |
| 250 | fclose(file); | ||
| 278 | return -2; | 251 | return -2; |
| 279 | } | 252 | } |
| 280 | 253 | ||
| 281 | size = nissy_datasize(args->str_solver, args->str_options); | 254 | size = nissy_datasize(args->str_solver, args->str_options); |
| 255 | |||
| 282 | if (size < 0) { | 256 | if (size < 0) { |
| 283 | fprintf(stderr, | 257 | fprintf(stderr, |
| 284 | "Unknown error in retrieving data size" | 258 | "Unknown error in retrieving data size" |
| 285 | "(make sure solver is valid)\n"); | 259 | "(make sure solver is valid)\n"); |
| 260 | fclose(file); | ||
| 286 | return -3; | 261 | return -3; |
| 287 | } | 262 | } |
| 288 | 263 | ||
| @@ -291,19 +266,23 @@ gendata_exec(args_t *args) | |||
| 291 | ret = nissy_gendata(args->str_solver, args->str_options, buf); | 266 | ret = nissy_gendata(args->str_solver, args->str_options, buf); |
| 292 | if (ret < 0) { | 267 | if (ret < 0) { |
| 293 | fprintf(stderr, "Unknown error in generating data\n"); | 268 | fprintf(stderr, "Unknown error in generating data\n"); |
| 269 | fclose(file); | ||
| 294 | free(buf); | 270 | free(buf); |
| 295 | return -4; | 271 | return -4; |
| 296 | } | 272 | } |
| 297 | if (ret != size) { | 273 | if (ret != size) { |
| 298 | fprintf(stderr, "Unknown error: unexpected data size\n"); | 274 | fprintf(stderr, "Unknown error: unexpected data size " |
| 275 | "(got %zu, expected %zu)\n", ret, size); | ||
| 276 | fclose(file); | ||
| 299 | free(buf); | 277 | free(buf); |
| 300 | return -5; | 278 | return -5; |
| 301 | } | 279 | } |
| 302 | 280 | ||
| 303 | written = fwrite(buf, size, 1, file); | 281 | written = fwrite(buf, size, 1, file); |
| 282 | fclose(file); | ||
| 304 | free(buf); | 283 | free(buf); |
| 305 | 284 | ||
| 306 | if (written != (int64_t)size) { | 285 | if (written != 1) { |
| 307 | fprintf(stderr, | 286 | fprintf(stderr, |
| 308 | "Error: data was generated correctly, but could not be " | 287 | "Error: data was generated correctly, but could not be " |
| 309 | "written to file (generated %" PRId64 " bytes, written " | 288 | "written to file (generated %" PRId64 " bytes, written " |
| @@ -311,7 +290,6 @@ gendata_exec(args_t *args) | |||
| 311 | return -6; | 290 | return -6; |
| 312 | } | 291 | } |
| 313 | 292 | ||
| 314 | args->datasize = size; | ||
| 315 | fprintf(stderr, "Data written to %s\n", path); | 293 | fprintf(stderr, "Data written to %s\n", path); |
| 316 | 294 | ||
| 317 | return 0; | 295 | return 0; |
| @@ -323,7 +301,7 @@ solve_exec(args_t *args) | |||
| 323 | int i; | 301 | int i; |
| 324 | FILE *file; | 302 | FILE *file; |
| 325 | char *buf, solutions[SOLUTIONS_BUFFER_SIZE], path[MAX_PATH_LENGTH]; | 303 | char *buf, solutions[SOLUTIONS_BUFFER_SIZE], path[MAX_PATH_LENGTH]; |
| 326 | int64_t ret, gendata_ret; | 304 | int64_t ret, gendata_ret, size; |
| 327 | size_t read; | 305 | size_t read; |
| 328 | 306 | ||
| 329 | for (i = 0; tablepaths[i] != NULL; i++) { | 307 | for (i = 0; tablepaths[i] != NULL; i++) { |
| @@ -344,23 +322,30 @@ solve_exec(args_t *args) | |||
| 344 | } | 322 | } |
| 345 | 323 | ||
| 346 | /* Ugh, this is not elegant TODO */ | 324 | /* Ugh, this is not elegant TODO */ |
| 347 | for (i = 0; tablepaths[i] != NULL; i++) { | 325 | if (file == NULL) { |
| 348 | strcpy(path, tablepaths[i]); | 326 | for (i = 0; tablepaths[i] != NULL; i++) { |
| 349 | strcat(path, args->str_solver); | 327 | strcpy(path, tablepaths[i]); |
| 350 | file = fopen(path, "rb"); | 328 | strcat(path, args->str_solver); |
| 351 | if (file != NULL) | 329 | file = fopen(path, "rb"); |
| 352 | break; | 330 | if (file != NULL) |
| 331 | break; | ||
| 332 | } | ||
| 353 | } | 333 | } |
| 354 | 334 | ||
| 355 | if (tablepaths[i] == NULL) { | 335 | if (tablepaths[i] == NULL) { |
| 356 | fprintf(stderr, "Error: data file not found\n"); | 336 | fprintf(stderr, "Error: data file not found\n"); |
| 337 | fclose(file); | ||
| 357 | return -1; | 338 | return -1; |
| 358 | } | 339 | } |
| 359 | 340 | ||
| 360 | buf = malloc(args->datasize); | 341 | size = nissy_datasize(args->str_solver, args->str_options); |
| 361 | read = fread(buf, args->datasize, 1, file); | 342 | buf = malloc(size); |
| 362 | if (read != args->datasize) { | 343 | read = fread(buf, size, 1, file); |
| 363 | fprintf(stderr, "Error reading data from file\n"); | 344 | fclose(file); |
| 345 | if (read != 1) { | ||
| 346 | fprintf(stderr, "Error reading data from file: " | ||
| 347 | "fread() returned %zu instead of 1 when attempting to" | ||
| 348 | "read %" PRId64 " bytes from file %s\n", read, size, path); | ||
| 364 | return -2; | 349 | return -2; |
| 365 | } | 350 | } |
| 366 | 351 | ||
| @@ -413,7 +398,7 @@ parse_args(int argc, char **argv, args_t *args) | |||
| 413 | options[j].name); | 398 | options[j].name); |
| 414 | return 1; | 399 | return 1; |
| 415 | } | 400 | } |
| 416 | if (!options[j].set(n, argv+i, args)) { | 401 | if (!options[j].set(n, argv+i+1, args)) { |
| 417 | fprintf(stderr, | 402 | fprintf(stderr, |
| 418 | "Error parsing arguments for option %s\n", | 403 | "Error parsing arguments for option %s\n", |
| 419 | options[j].name); | 404 | options[j].name); |
| @@ -448,7 +433,8 @@ parse_int64(char *argv, int64_t *result) | |||
| 448 | { | 433 | { |
| 449 | *result = strtoll(argv, NULL, 10); | 434 | *result = strtoll(argv, NULL, 10); |
| 450 | 435 | ||
| 451 | return errno != 0; | 436 | /* TODO: figure out how errno works and use it */ |
| 437 | return true; | ||
| 452 | } | 438 | } |
| 453 | 439 | ||
| 454 | static bool | 440 | static bool |
| @@ -565,11 +551,22 @@ set_maxsolutions(int argc, char **argv, args_t *args) | |||
| 565 | return parse_int64(argv[0], &args->maxsolutions); | 551 | return parse_int64(argv[0], &args->maxsolutions); |
| 566 | } | 552 | } |
| 567 | 553 | ||
| 554 | void log_stderr(const char *str, ...) | ||
| 555 | { | ||
| 556 | va_list args; | ||
| 557 | |||
| 558 | va_start(args, str); | ||
| 559 | vfprintf(stderr, str, args); | ||
| 560 | va_end(args); | ||
| 561 | } | ||
| 562 | |||
| 568 | int main(int argc, char **argv) | 563 | int main(int argc, char **argv) |
| 569 | { | 564 | { |
| 570 | int parse_error; | 565 | int parse_error; |
| 571 | args_t args; | 566 | args_t args; |
| 572 | 567 | ||
| 568 | nissy_setlogger(log_stderr); | ||
| 569 | |||
| 573 | parse_error = parse_args(argc-1, argv+1, &args); | 570 | parse_error = parse_args(argc-1, argv+1, &args); |
| 574 | if (parse_error) | 571 | if (parse_error) |
| 575 | return parse_error; | 572 | return parse_error; |
