diff options
| -rw-r--r-- | src/core/io_moves.h | 27 | ||||
| -rw-r--r-- | src/core/io_trans.h | 8 | ||||
| -rw-r--r-- | src/nissy.c | 3 | ||||
| -rw-r--r-- | src/solvers/h48/solve.h | 22 | ||||
| -rw-r--r-- | src/solvers/h48/solve_multithread.h | 23 | ||||
| -rw-r--r-- | test/032_invertmoves/invertmoves_tests.c | 4 | ||||
| -rw-r--r-- | test/061_inverse_trans/inverse_trans_tests.c | 2 |
7 files changed, 66 insertions, 23 deletions
diff --git a/src/core/io_moves.h b/src/core/io_moves.h index a49a38b..be43568 100644 --- a/src/core/io_moves.h +++ b/src/core/io_moves.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | STATIC uint8_t readmove(char); | 1 | STATIC uint8_t readmove(char); |
| 2 | STATIC uint8_t readmodifier(char); | 2 | STATIC uint8_t readmodifier(char); |
| 3 | STATIC int writemoves(uint8_t *, int, char *); | 3 | STATIC int64_t writemoves(uint8_t *, int, uint64_t, char *); |
| 4 | 4 | ||
| 5 | STATIC uint8_t | 5 | STATIC uint8_t |
| 6 | readmove(char c) | 6 | readmove(char c) |
| @@ -38,18 +38,29 @@ readmodifier(char c) | |||
| 38 | } | 38 | } |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | STATIC int | 41 | STATIC int64_t |
| 42 | writemoves(uint8_t *m, int n, char *buf) | 42 | writemoves(uint8_t *m, int n, uint64_t buf_size, char *buf) |
| 43 | { | 43 | { |
| 44 | int i; | 44 | int i; |
| 45 | size_t len; | 45 | uint64_t len; |
| 46 | const char *s; | 46 | const char *s; |
| 47 | char *b; | 47 | char *b; |
| 48 | 48 | ||
| 49 | for (i = 0, b = buf; i < n; i++, b++) { | 49 | if (buf_size == 0) { |
| 50 | LOG("Error: cannot write moves to buffer of size 0.\n"); | ||
| 51 | return NISSY_ERROR_BUFFER_SIZE; | ||
| 52 | } | ||
| 53 | |||
| 54 | for (i = 0, b = buf; i < n; i++, b++, buf_size--) { | ||
| 50 | s = movestr[m[i]]; | 55 | s = movestr[m[i]]; |
| 51 | len = strlen(s); | 56 | len = strlen(s); |
| 57 | if (len >= buf_size) { | ||
| 58 | LOG("Error: the given buffer is too small for " | ||
| 59 | "writing the given moves.\n"); | ||
| 60 | goto writemoves_error; | ||
| 61 | } | ||
| 52 | memcpy(b, s, len); | 62 | memcpy(b, s, len); |
| 63 | buf_size -= len; | ||
| 53 | b += len; | 64 | b += len; |
| 54 | *b = ' '; | 65 | *b = ' '; |
| 55 | } | 66 | } |
| @@ -58,5 +69,9 @@ writemoves(uint8_t *m, int n, char *buf) | |||
| 58 | b--; /* Remove last space */ | 69 | b--; /* Remove last space */ |
| 59 | *b = '\0'; | 70 | *b = '\0'; |
| 60 | 71 | ||
| 61 | return b - buf; | 72 | return buf_size; |
| 73 | |||
| 74 | writemoves_error: | ||
| 75 | *buf = '\0'; | ||
| 76 | return NISSY_ERROR_BUFFER_SIZE; | ||
| 62 | } | 77 | } |
diff --git a/src/core/io_trans.h b/src/core/io_trans.h index f4e8ace..f0db095 100644 --- a/src/core/io_trans.h +++ b/src/core/io_trans.h | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | STATIC uint8_t readtrans(const char *); | 1 | STATIC uint8_t readtrans(const char [static NISSY_SIZE_TRANSFORMATION]); |
| 2 | STATIC void writetrans(uint8_t, char *); | 2 | STATIC void writetrans(uint8_t, char [static NISSY_SIZE_TRANSFORMATION]); |
| 3 | 3 | ||
| 4 | STATIC uint8_t | 4 | STATIC uint8_t |
| 5 | readtrans(const char *buf) | 5 | readtrans(const char buf[static NISSY_SIZE_TRANSFORMATION]) |
| 6 | { | 6 | { |
| 7 | uint8_t t; | 7 | uint8_t t; |
| 8 | 8 | ||
| @@ -14,7 +14,7 @@ readtrans(const char *buf) | |||
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | STATIC void | 16 | STATIC void |
| 17 | writetrans(uint8_t t, char *buf) | 17 | writetrans(uint8_t t, char buf[static NISSY_SIZE_TRANSFORMATION]) |
| 18 | { | 18 | { |
| 19 | if (t >= 48) | 19 | if (t >= 48) |
| 20 | memcpy(buf, "error trans", 11); | 20 | memcpy(buf, "error trans", 11); |
diff --git a/src/nissy.c b/src/nissy.c index d3ff58a..d5d0270 100644 --- a/src/nissy.c +++ b/src/nissy.c | |||
| @@ -559,9 +559,6 @@ nissy_solve( | |||
| 559 | solve_h48(c, minmoves, maxmoves, maxsols, | 559 | solve_h48(c, minmoves, maxmoves, maxsols, |
| 560 | data_size, data, sols_size, sols); | 560 | data_size, data, sols_size, sols); |
| 561 | } | 561 | } |
| 562 | } else if (!strcmp(solver, "simple")) { | ||
| 563 | return solve_simple( | ||
| 564 | c, minmoves, maxmoves, maxsols, optimal, sols); | ||
| 565 | } else { | 562 | } else { |
| 566 | LOG("solve: unknown solver '%s'\n", solver); | 563 | LOG("solve: unknown solver '%s'\n", solver); |
| 567 | return NISSY_ERROR_INVALID_SOLVER; | 564 | return NISSY_ERROR_INVALID_SOLVER; |
diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index f2babdf..bcc8b33 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h | |||
| @@ -10,6 +10,7 @@ typedef struct { | |||
| 10 | uint8_t k; | 10 | uint8_t k; |
| 11 | const uint32_t *cocsepdata; | 11 | const uint32_t *cocsepdata; |
| 12 | const uint8_t *h48data; | 12 | const uint8_t *h48data; |
| 13 | uint64_t solutions_size; | ||
| 13 | char **nextsol; | 14 | char **nextsol; |
| 14 | uint8_t nissbranch; | 15 | uint8_t nissbranch; |
| 15 | int8_t npremoves; | 16 | int8_t npremoves; |
| @@ -55,26 +56,40 @@ allowednextmove_h48(uint8_t *moves, uint8_t n, uint32_t h48branch) | |||
| 55 | STATIC void | 56 | STATIC void |
| 56 | solve_h48_appendsolution(dfsarg_solveh48_t *arg) | 57 | solve_h48_appendsolution(dfsarg_solveh48_t *arg) |
| 57 | { | 58 | { |
| 58 | int strl; | 59 | int64_t strl; |
| 59 | uint8_t invertedpremoves[MAXLEN]; | 60 | uint8_t invertedpremoves[MAXLEN]; |
| 60 | char *solution = *arg->nextsol; | 61 | char *solution = *arg->nextsol; |
| 61 | 62 | ||
| 62 | strl = writemoves(arg->moves, arg->nmoves, *arg->nextsol); | 63 | strl = writemoves( |
| 64 | arg->moves, arg->nmoves, arg->solutions_size, *arg->nextsol); | ||
| 65 | |||
| 66 | if (strl < 0) | ||
| 67 | goto solve_h48_appendsolution_error; | ||
| 63 | *arg->nextsol += strl; | 68 | *arg->nextsol += strl; |
| 69 | arg->solutions_size -= strl; | ||
| 64 | 70 | ||
| 65 | if (arg->npremoves) { | 71 | if (arg->npremoves) { |
| 66 | **arg->nextsol = ' '; | 72 | **arg->nextsol = ' '; |
| 67 | (*arg->nextsol)++; | 73 | (*arg->nextsol)++; |
| 68 | 74 | ||
| 69 | invertmoves(arg->premoves, arg->npremoves, invertedpremoves); | 75 | invertmoves(arg->premoves, arg->npremoves, invertedpremoves); |
| 70 | strl = writemoves(invertedpremoves, arg->npremoves, *arg->nextsol); | 76 | strl = writemoves(invertedpremoves, |
| 77 | arg->npremoves, arg->solutions_size, *arg->nextsol); | ||
| 78 | |||
| 79 | if (strl < 0) | ||
| 80 | goto solve_h48_appendsolution_error; | ||
| 71 | *arg->nextsol += strl; | 81 | *arg->nextsol += strl; |
| 82 | arg->solutions_size -= strl; | ||
| 72 | } | 83 | } |
| 73 | LOG("Solution found: %s\n", solution); | 84 | LOG("Solution found: %s\n", solution); |
| 74 | 85 | ||
| 75 | **arg->nextsol = '\n'; | 86 | **arg->nextsol = '\n'; |
| 76 | (*arg->nextsol)++; | 87 | (*arg->nextsol)++; |
| 77 | (*arg->nsols)++; | 88 | (*arg->nsols)++; |
| 89 | |||
| 90 | solve_h48_appendsolution_error: | ||
| 91 | /* We could add some logging, but writemoves() already does */ | ||
| 92 | return; | ||
| 78 | } | 93 | } |
| 79 | 94 | ||
| 80 | STATIC_INLINE bool | 95 | STATIC_INLINE bool |
| @@ -188,6 +203,7 @@ solve_h48( | |||
| 188 | .k = info.bits, | 203 | .k = info.bits, |
| 189 | .cocsepdata = get_cocsepdata_constptr(data), | 204 | .cocsepdata = get_cocsepdata_constptr(data), |
| 190 | .h48data = get_h48data_constptr(data), | 205 | .h48data = get_h48data_constptr(data), |
| 206 | .solutions_size = solutions_size, | ||
| 191 | .nextsol = &solutions | 207 | .nextsol = &solutions |
| 192 | }; | 208 | }; |
| 193 | 209 | ||
diff --git a/src/solvers/h48/solve_multithread.h b/src/solvers/h48/solve_multithread.h index 3ba914a..8e00404 100644 --- a/src/solvers/h48/solve_multithread.h +++ b/src/solvers/h48/solve_multithread.h | |||
| @@ -27,12 +27,17 @@ STATIC void | |||
| 27 | solve_h48_appendsolution_thread(dfsarg_solveh48_t *arg, task_queue_t *tq) | 27 | solve_h48_appendsolution_thread(dfsarg_solveh48_t *arg, task_queue_t *tq) |
| 28 | { | 28 | { |
| 29 | pthread_mutex_lock(&tq->mutex); | 29 | pthread_mutex_lock(&tq->mutex); |
| 30 | int strl = 0; | 30 | int64_t strl = 0; |
| 31 | uint8_t invertedpremoves[MAXLEN]; | 31 | uint8_t invertedpremoves[MAXLEN]; |
| 32 | char *solution = *arg->nextsol; | 32 | char *solution = *arg->nextsol; |
| 33 | 33 | ||
| 34 | strl = writemoves(arg->moves, arg->nmoves, *arg->nextsol); | 34 | strl = writemoves( |
| 35 | arg->moves, arg->nmoves, arg->solutions_size, *arg->nextsol); | ||
| 36 | |||
| 37 | if (strl < 0) | ||
| 38 | goto solve_h48_appendsolution_thread_error; | ||
| 35 | *arg->nextsol += strl; | 39 | *arg->nextsol += strl; |
| 40 | arg->solutions_size -= strl; | ||
| 36 | 41 | ||
| 37 | if (arg->npremoves) | 42 | if (arg->npremoves) |
| 38 | { | 43 | { |
| @@ -40,14 +45,22 @@ solve_h48_appendsolution_thread(dfsarg_solveh48_t *arg, task_queue_t *tq) | |||
| 40 | (*arg->nextsol)++; | 45 | (*arg->nextsol)++; |
| 41 | 46 | ||
| 42 | invertmoves(arg->premoves, arg->npremoves, invertedpremoves); | 47 | invertmoves(arg->premoves, arg->npremoves, invertedpremoves); |
| 43 | strl = writemoves(invertedpremoves, arg->npremoves, *arg->nextsol); | 48 | strl = writemoves(invertedpremoves, |
| 49 | arg->npremoves, arg->solutions_size, *arg->nextsol); | ||
| 50 | |||
| 51 | if (strl < 0) | ||
| 52 | goto solve_h48_appendsolution_thread_error; | ||
| 44 | *arg->nextsol += strl; | 53 | *arg->nextsol += strl; |
| 54 | arg->solutions_size -= strl; | ||
| 45 | } | 55 | } |
| 46 | LOG("Solution found: %s\n", solution); | 56 | LOG("Solution found: %s\n", solution); |
| 47 | 57 | ||
| 48 | **arg->nextsol = '\n'; | 58 | **arg->nextsol = '\n'; |
| 49 | (*arg->nextsol)++; | 59 | (*arg->nextsol)++; |
| 50 | (*arg->nsols)++; | 60 | (*arg->nsols)++; |
| 61 | |||
| 62 | solve_h48_appendsolution_thread_error: | ||
| 63 | /* We could add some logging, but writemoves() already does */ | ||
| 51 | pthread_mutex_unlock(&tq->mutex); | 64 | pthread_mutex_unlock(&tq->mutex); |
| 52 | } | 65 | } |
| 53 | 66 | ||
| @@ -264,7 +277,9 @@ solve_h48_multithread( | |||
| 264 | .k = info.bits, | 277 | .k = info.bits, |
| 265 | .cocsepdata = get_cocsepdata_constptr(data), | 278 | .cocsepdata = get_cocsepdata_constptr(data), |
| 266 | .h48data = get_h48data_constptr(data), | 279 | .h48data = get_h48data_constptr(data), |
| 267 | .nextsol = &solutions}; | 280 | .solutions_size = solutions_size, |
| 281 | .nextsol = &solutions | ||
| 282 | }; | ||
| 268 | 283 | ||
| 269 | task_queue_t q; | 284 | task_queue_t q; |
| 270 | init_queue(&q); | 285 | init_queue(&q); |
diff --git a/test/032_invertmoves/invertmoves_tests.c b/test/032_invertmoves/invertmoves_tests.c index acb2adc..d5da323 100644 --- a/test/032_invertmoves/invertmoves_tests.c +++ b/test/032_invertmoves/invertmoves_tests.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | #define MAXMOVES 20 | 3 | #define MAXMOVES 20 |
| 4 | 4 | ||
| 5 | int64_t readmoves(const char *, int, uint8_t *); | 5 | int64_t readmoves(const char *, int, uint8_t *); |
| 6 | void writemoves(uint8_t *, int, char *); | 6 | void writemoves(uint8_t *, int, uint64_t, char *); |
| 7 | void invertmoves(uint8_t *, uint8_t, uint8_t *); | 7 | void invertmoves(uint8_t *, uint8_t, uint8_t *); |
| 8 | 8 | ||
| 9 | void run(void) { | 9 | void run(void) { |
| @@ -15,7 +15,7 @@ void run(void) { | |||
| 15 | c = readmoves(movestr, MAXMOVES, moves); | 15 | c = readmoves(movestr, MAXMOVES, moves); |
| 16 | 16 | ||
| 17 | invertmoves(moves, c, ret); | 17 | invertmoves(moves, c, ret); |
| 18 | writemoves(ret, c, outstr); | 18 | writemoves(ret, c, STRLENMAX, outstr); |
| 19 | 19 | ||
| 20 | printf("%s\n", outstr); | 20 | printf("%s\n", outstr); |
| 21 | } | 21 | } |
diff --git a/test/061_inverse_trans/inverse_trans_tests.c b/test/061_inverse_trans/inverse_trans_tests.c index bbc1ac9..441fef8 100644 --- a/test/061_inverse_trans/inverse_trans_tests.c +++ b/test/061_inverse_trans/inverse_trans_tests.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #include "../test.h" | 1 | #include "../test.h" |
| 2 | 2 | ||
| 3 | uint8_t readtrans(char *); | 3 | uint8_t readtrans(char [static NISSY_SIZE_TRANSFORMATION]); |
| 4 | uint8_t inverse_trans(uint8_t); | 4 | uint8_t inverse_trans(uint8_t); |
| 5 | cube_t applymoves(cube_t, char *); | 5 | cube_t applymoves(cube_t, char *); |
| 6 | cube_t applytrans(cube_t, char *); | 6 | cube_t applytrans(cube_t, char *); |
