From 1d9b8acfeece68c4f55d2499d8aed127f98a383c Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Mon, 21 Apr 2025 10:33:46 +0200 Subject: Merged some files, renamed another --- src/core/core.h | 4 +- src/core/io_cube.h | 403 -------------------------------------------------- src/core/io_formats.h | 403 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/core/io_moves.h | 127 ---------------- src/core/io_trans.h | 24 --- src/core/moves.h | 128 ++++++++++++++++ src/core/transform.h | 25 ++++ 7 files changed, 557 insertions(+), 557 deletions(-) delete mode 100644 src/core/io_cube.h create mode 100644 src/core/io_formats.h delete mode 100644 src/core/io_moves.h delete mode 100644 src/core/io_trans.h (limited to 'src') diff --git a/src/core/core.h b/src/core/core.h index f041178..de1c198 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -1,7 +1,5 @@ #include "constant_cubes.h" -#include "io_moves.h" -#include "io_trans.h" #include "cube.h" -#include "io_cube.h" +#include "io_formats.h" #include "moves.h" #include "transform.h" diff --git a/src/core/io_cube.h b/src/core/io_cube.h deleted file mode 100644 index f5668d4..0000000 --- a/src/core/io_cube.h +++ /dev/null @@ -1,403 +0,0 @@ -STATIC cube_t readcube(const char *, const char *); -STATIC int64_t writecube(const char *, cube_t, size_t n, char [n]); -STATIC void log_available_formats(void); -STATIC uint8_t readco(const char *); -STATIC uint8_t readcp(const char *); -STATIC uint8_t readeo(const char *); -STATIC uint8_t readep(const char *); -STATIC cube_t readcube_B32(const char *); -STATIC cube_t readcube_H48(const char *); -STATIC uint8_t readpiece_LST(const char **); -STATIC cube_t readcube_LST(const char *); - -STATIC int64_t writepiece_LST(uint8_t, size_t n, char [n]); -STATIC int64_t writecube_B32(cube_t, size_t n, char [n]); -STATIC int64_t writecube_H48(cube_t, size_t n, char [n]); -STATIC int64_t writecube_LST(cube_t, size_t n, char [n]); - -STATIC uint8_t b32toedge(char); -STATIC uint8_t b32tocorner(char); -STATIC char edgetob32(uint8_t); -STATIC char cornertob32(uint8_t); - -STATIC struct { - const char *name; - cube_t (*read)(const char *); - int64_t (*write)(cube_t, size_t n, char [n]); -} ioformat[] = -{ - { .name = "B32", .read = readcube_B32, .write = writecube_B32 }, - { .name = "LST", .read = readcube_LST, .write = writecube_LST }, - { .name = "H48", .read = readcube_H48, .write = writecube_H48 }, - { .name = "NONE", .read = NULL, .write = NULL }, -}; - -STATIC cube_t -readcube(const char *format, const char *buf) -{ - int i; - - for (i = 0; ioformat[i].read != NULL; i++) - if (!strcmp(format, ioformat[i].name)) - return ioformat[i].read(buf); - - LOG("Cannot read cube: unknown format '%s'\n", format); - log_available_formats(); - return ZERO_CUBE; -} - -STATIC int64_t -writecube(const char *format, cube_t cube, size_t buf_size, char buf[buf_size]) -{ - int i; - - for (i = 0; ioformat[i].write != NULL; i++) - if (!strcmp(format, ioformat[i].name)) - return ioformat[i].write(cube, buf_size, buf); - - LOG("Cannot write cube: unknown format '%s'\n", format); - log_available_formats(); - return NISSY_ERROR_INVALID_FORMAT; -} - -STATIC void -log_available_formats(void) -{ - int i; - - LOG("Available formats: "); - for (i = 0; ioformat[i].read != NULL; i++) - LOG("'%s' ", ioformat[i].name); - LOG("\n"); -} - -STATIC uint8_t -readco(const char *str) -{ - if (*str == '0') - return 0; - if (*str == '1') - return CTWIST_CW; - if (*str == '2') - return CTWIST_CCW; - - LOG("Error reading CO\n"); - return UINT8_ERROR; -} - -STATIC uint8_t -readcp(const char *str) -{ - uint8_t c; - - for (c = 0; c < 8; c++) - if (!strncmp(str, cornerstr[c], 3) || - !strncmp(str, cornerstralt[c], 3)) - return c; - - LOG("Error reading CP\n"); - return UINT8_ERROR; -} - -STATIC uint8_t -readeo(const char *str) -{ - if (*str == '0') - return 0; - if (*str == '1') - return EFLIP; - - LOG("Error reading EO\n"); - return UINT8_ERROR; -} - -STATIC uint8_t -readep(const char *str) -{ - uint8_t e; - - for (e = 0; e < 12; e++) - if (!strncmp(str, edgestr[e], 2)) - return e; - - LOG("Error reading EP\n"); - return UINT8_ERROR; -} - -STATIC cube_t -readcube_B32(const char *buf) -{ - int i; - uint8_t c[8], e[12]; - - for (i = 0; i < 8; i++) { - c[i] = b32tocorner(buf[i]); - if (c[i] == UINT8_ERROR) { - LOG("Error reading B32 corner %d ", i); - if (buf[i] == 0) { - LOG("(string terminated early)\n"); - } else { - LOG("(char '%c')\n", buf[i]); - } - return ZERO_CUBE; - } - } - - if (buf[8] != '=') { - LOG("Error reading B32 separator: a single '=' " - "must be used to separate edges and corners\n"); - return ZERO_CUBE; - } - - for (i = 0; i < 12; i++) { - e[i] = b32toedge(buf[i+9]); - if (e[i] == UINT8_ERROR) { - LOG("Error reading B32 edge %d ", i); - if (buf[i+9] == 0) { - LOG("(string terminated early)\n"); - } else { - LOG("(char '%c')\n", buf[i+9]); - } - return ZERO_CUBE; - } - } - - return cubefromarray(c, e); -} - -STATIC cube_t -readcube_H48(const char *buf) -{ - int i; - uint8_t piece, orient, c[8], e[12]; - const char *b; - - b = buf; - - for (i = 0; i < 12; i++) { - while (*b == ' ' || *b == '\t' || *b == '\n') - b++; - if ((piece = readep(b)) == UINT8_ERROR) - return ZERO_CUBE; - b += 2; - if ((orient = readeo(b)) == UINT8_ERROR) - return ZERO_CUBE; - b++; - e[i] = piece | orient; - } - for (i = 0; i < 8; i++) { - while (*b == ' ' || *b == '\t' || *b == '\n') - b++; - if ((piece = readcp(b)) == UINT8_ERROR) - return ZERO_CUBE; - b += 3; - if ((orient = readco(b)) == UINT8_ERROR) - return ZERO_CUBE; - b++; - c[i] = piece | orient; - } - - return cubefromarray(c, e); -} - -STATIC uint8_t -readpiece_LST(const char **b) -{ - uint8_t ret; - bool read; - - while (**b == ',' || **b == ' ' || **b == '\t' || **b == '\n') - (*b)++; - - for (ret = 0, read = false; **b >= '0' && **b <= '9'; (*b)++) { - read = true; - ret = ret * 10 + (**b) - '0'; - } - - return read ? ret : UINT8_ERROR; -} - -STATIC cube_t -readcube_LST(const char *buf) -{ - int i; - uint8_t c[8], e[12]; - - for (i = 0; i < 8; i++) - c[i] = readpiece_LST(&buf); - - for (i = 0; i < 12; i++) - e[i] = readpiece_LST(&buf); - - return cubefromarray(c, e); -} - -STATIC int64_t -writepiece_LST(uint8_t piece, size_t buf_size, char buf[buf_size]) -{ - char digits[3]; - size_t i, len; - - if (piece > 99 || buf_size < 3) - return 0; - - len = 0; - while (piece != 0) { - digits[len++] = (piece % 10) + '0'; - piece /= 10; - } - - if (buf_size < len+2) - return 0; - - if (len == 0) - digits[len++] = '0'; - - for (i = 0; i < len; i++) - buf[i] = digits[len-i-1]; - - buf[len] = ','; - buf[len+1] = ' '; - - return len+2; -} - -STATIC int64_t -writecube_B32(cube_t cube, size_t buf_size, char buf[buf_size]) -{ - int i; - uint8_t corner[8], edge[12]; - - if (buf_size < NISSY_SIZE_B32) { - LOG("Cannot write cube in B32 format: buffer size must be at " - "least %u bytes, but the provided one is %zu bytes.\n", - NISSY_SIZE_B32, buf_size); - return NISSY_ERROR_BUFFER_SIZE; - } - - pieces(&cube, corner, edge); - - for (i = 0; i < 8; i++) - buf[i] = cornertob32(corner[i]); - - buf[8] = '='; - - for (i = 0; i < 12; i++) - buf[i+9] = edgetob32(edge[i]); - - buf[21] = '\0'; - - return NISSY_OK; -} - -STATIC int64_t -writecube_H48(cube_t cube, size_t buf_size, char buf[buf_size]) -{ - uint8_t piece, perm, orient, corner[8], edge[12]; - int i; - - if (buf_size < NISSY_SIZE_H48) { - LOG("Cannot write cube in H48 format: buffer size must be " - "at least %u bytes, but the provided one is %zu bytes.\n", - NISSY_SIZE_H48, buf_size); - return NISSY_ERROR_BUFFER_SIZE; - } - - pieces(&cube, corner, edge); - - for (i = 0; i < 12; i++) { - piece = edge[i]; - perm = piece & PBITS; - orient = (piece & EOBIT) >> EOSHIFT; - buf[4*i ] = edgestr[perm][0]; - buf[4*i + 1] = edgestr[perm][1]; - buf[4*i + 2] = orient + '0'; - buf[4*i + 3] = ' '; - } - for (i = 0; i < 8; i++) { - piece = corner[i]; - perm = piece & PBITS; - orient = (piece & COBITS) >> COSHIFT; - buf[48 + 5*i ] = cornerstr[perm][0]; - buf[48 + 5*i + 1] = cornerstr[perm][1]; - buf[48 + 5*i + 2] = cornerstr[perm][2]; - buf[48 + 5*i + 3] = orient + '0'; - buf[48 + 5*i + 4] = ' '; - } - - buf[48+39] = '\0'; - - return NISSY_OK; -} - -STATIC int64_t -writecube_LST(cube_t cube, size_t buf_size, char buf[buf_size]) -{ - int i; - uint64_t ptr; - uint8_t piece, corner[8], edge[12]; - - ptr = 0; - pieces(&cube, corner, edge); - - for (i = 0; i < 8; i++) { - piece = corner[i]; - ptr += writepiece_LST(piece, buf_size - ptr, buf + ptr); - if (ptr == 0) - goto writecube_LST_error; - } - - for (i = 0; i < 12; i++) { - piece = edge[i]; - ptr += writepiece_LST(piece, buf_size - ptr, buf + ptr); - if (ptr == 0) - goto writecube_LST_error; - } - - *(buf+ptr-2) = '\0'; - - return NISSY_OK; - -writecube_LST_error: - LOG("Cannot write cube in LST: buffer is too small (%" PRIu64 - " bytes given). The LST format has a variable size, try a " - "larger buffer.\n", buf_size); - return NISSY_ERROR_BUFFER_SIZE; -} - -STATIC uint8_t -b32toedge(char c) -{ - if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'f'))) - return UINT8_ERROR; - - return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26; -} - -STATIC uint8_t -b32tocorner(char c) { - uint8_t val; - - if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'f'))) - return UINT8_ERROR; - - val = c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26; - - return (val & 7) | ((val & 24) << 2); -} - -STATIC char -edgetob32(uint8_t edge) -{ - return edge < 26 ? 'A' + (char)edge : 'a' + (char)(edge - 26); -} - -STATIC char -cornertob32(uint8_t corner) -{ - uint8_t val; - - val = (corner & 7) | ((corner & 96) >> 2); - - return val < 26 ? 'A' + (char)val : 'a' + (char)(val - 26); -} diff --git a/src/core/io_formats.h b/src/core/io_formats.h new file mode 100644 index 0000000..f5668d4 --- /dev/null +++ b/src/core/io_formats.h @@ -0,0 +1,403 @@ +STATIC cube_t readcube(const char *, const char *); +STATIC int64_t writecube(const char *, cube_t, size_t n, char [n]); +STATIC void log_available_formats(void); +STATIC uint8_t readco(const char *); +STATIC uint8_t readcp(const char *); +STATIC uint8_t readeo(const char *); +STATIC uint8_t readep(const char *); +STATIC cube_t readcube_B32(const char *); +STATIC cube_t readcube_H48(const char *); +STATIC uint8_t readpiece_LST(const char **); +STATIC cube_t readcube_LST(const char *); + +STATIC int64_t writepiece_LST(uint8_t, size_t n, char [n]); +STATIC int64_t writecube_B32(cube_t, size_t n, char [n]); +STATIC int64_t writecube_H48(cube_t, size_t n, char [n]); +STATIC int64_t writecube_LST(cube_t, size_t n, char [n]); + +STATIC uint8_t b32toedge(char); +STATIC uint8_t b32tocorner(char); +STATIC char edgetob32(uint8_t); +STATIC char cornertob32(uint8_t); + +STATIC struct { + const char *name; + cube_t (*read)(const char *); + int64_t (*write)(cube_t, size_t n, char [n]); +} ioformat[] = +{ + { .name = "B32", .read = readcube_B32, .write = writecube_B32 }, + { .name = "LST", .read = readcube_LST, .write = writecube_LST }, + { .name = "H48", .read = readcube_H48, .write = writecube_H48 }, + { .name = "NONE", .read = NULL, .write = NULL }, +}; + +STATIC cube_t +readcube(const char *format, const char *buf) +{ + int i; + + for (i = 0; ioformat[i].read != NULL; i++) + if (!strcmp(format, ioformat[i].name)) + return ioformat[i].read(buf); + + LOG("Cannot read cube: unknown format '%s'\n", format); + log_available_formats(); + return ZERO_CUBE; +} + +STATIC int64_t +writecube(const char *format, cube_t cube, size_t buf_size, char buf[buf_size]) +{ + int i; + + for (i = 0; ioformat[i].write != NULL; i++) + if (!strcmp(format, ioformat[i].name)) + return ioformat[i].write(cube, buf_size, buf); + + LOG("Cannot write cube: unknown format '%s'\n", format); + log_available_formats(); + return NISSY_ERROR_INVALID_FORMAT; +} + +STATIC void +log_available_formats(void) +{ + int i; + + LOG("Available formats: "); + for (i = 0; ioformat[i].read != NULL; i++) + LOG("'%s' ", ioformat[i].name); + LOG("\n"); +} + +STATIC uint8_t +readco(const char *str) +{ + if (*str == '0') + return 0; + if (*str == '1') + return CTWIST_CW; + if (*str == '2') + return CTWIST_CCW; + + LOG("Error reading CO\n"); + return UINT8_ERROR; +} + +STATIC uint8_t +readcp(const char *str) +{ + uint8_t c; + + for (c = 0; c < 8; c++) + if (!strncmp(str, cornerstr[c], 3) || + !strncmp(str, cornerstralt[c], 3)) + return c; + + LOG("Error reading CP\n"); + return UINT8_ERROR; +} + +STATIC uint8_t +readeo(const char *str) +{ + if (*str == '0') + return 0; + if (*str == '1') + return EFLIP; + + LOG("Error reading EO\n"); + return UINT8_ERROR; +} + +STATIC uint8_t +readep(const char *str) +{ + uint8_t e; + + for (e = 0; e < 12; e++) + if (!strncmp(str, edgestr[e], 2)) + return e; + + LOG("Error reading EP\n"); + return UINT8_ERROR; +} + +STATIC cube_t +readcube_B32(const char *buf) +{ + int i; + uint8_t c[8], e[12]; + + for (i = 0; i < 8; i++) { + c[i] = b32tocorner(buf[i]); + if (c[i] == UINT8_ERROR) { + LOG("Error reading B32 corner %d ", i); + if (buf[i] == 0) { + LOG("(string terminated early)\n"); + } else { + LOG("(char '%c')\n", buf[i]); + } + return ZERO_CUBE; + } + } + + if (buf[8] != '=') { + LOG("Error reading B32 separator: a single '=' " + "must be used to separate edges and corners\n"); + return ZERO_CUBE; + } + + for (i = 0; i < 12; i++) { + e[i] = b32toedge(buf[i+9]); + if (e[i] == UINT8_ERROR) { + LOG("Error reading B32 edge %d ", i); + if (buf[i+9] == 0) { + LOG("(string terminated early)\n"); + } else { + LOG("(char '%c')\n", buf[i+9]); + } + return ZERO_CUBE; + } + } + + return cubefromarray(c, e); +} + +STATIC cube_t +readcube_H48(const char *buf) +{ + int i; + uint8_t piece, orient, c[8], e[12]; + const char *b; + + b = buf; + + for (i = 0; i < 12; i++) { + while (*b == ' ' || *b == '\t' || *b == '\n') + b++; + if ((piece = readep(b)) == UINT8_ERROR) + return ZERO_CUBE; + b += 2; + if ((orient = readeo(b)) == UINT8_ERROR) + return ZERO_CUBE; + b++; + e[i] = piece | orient; + } + for (i = 0; i < 8; i++) { + while (*b == ' ' || *b == '\t' || *b == '\n') + b++; + if ((piece = readcp(b)) == UINT8_ERROR) + return ZERO_CUBE; + b += 3; + if ((orient = readco(b)) == UINT8_ERROR) + return ZERO_CUBE; + b++; + c[i] = piece | orient; + } + + return cubefromarray(c, e); +} + +STATIC uint8_t +readpiece_LST(const char **b) +{ + uint8_t ret; + bool read; + + while (**b == ',' || **b == ' ' || **b == '\t' || **b == '\n') + (*b)++; + + for (ret = 0, read = false; **b >= '0' && **b <= '9'; (*b)++) { + read = true; + ret = ret * 10 + (**b) - '0'; + } + + return read ? ret : UINT8_ERROR; +} + +STATIC cube_t +readcube_LST(const char *buf) +{ + int i; + uint8_t c[8], e[12]; + + for (i = 0; i < 8; i++) + c[i] = readpiece_LST(&buf); + + for (i = 0; i < 12; i++) + e[i] = readpiece_LST(&buf); + + return cubefromarray(c, e); +} + +STATIC int64_t +writepiece_LST(uint8_t piece, size_t buf_size, char buf[buf_size]) +{ + char digits[3]; + size_t i, len; + + if (piece > 99 || buf_size < 3) + return 0; + + len = 0; + while (piece != 0) { + digits[len++] = (piece % 10) + '0'; + piece /= 10; + } + + if (buf_size < len+2) + return 0; + + if (len == 0) + digits[len++] = '0'; + + for (i = 0; i < len; i++) + buf[i] = digits[len-i-1]; + + buf[len] = ','; + buf[len+1] = ' '; + + return len+2; +} + +STATIC int64_t +writecube_B32(cube_t cube, size_t buf_size, char buf[buf_size]) +{ + int i; + uint8_t corner[8], edge[12]; + + if (buf_size < NISSY_SIZE_B32) { + LOG("Cannot write cube in B32 format: buffer size must be at " + "least %u bytes, but the provided one is %zu bytes.\n", + NISSY_SIZE_B32, buf_size); + return NISSY_ERROR_BUFFER_SIZE; + } + + pieces(&cube, corner, edge); + + for (i = 0; i < 8; i++) + buf[i] = cornertob32(corner[i]); + + buf[8] = '='; + + for (i = 0; i < 12; i++) + buf[i+9] = edgetob32(edge[i]); + + buf[21] = '\0'; + + return NISSY_OK; +} + +STATIC int64_t +writecube_H48(cube_t cube, size_t buf_size, char buf[buf_size]) +{ + uint8_t piece, perm, orient, corner[8], edge[12]; + int i; + + if (buf_size < NISSY_SIZE_H48) { + LOG("Cannot write cube in H48 format: buffer size must be " + "at least %u bytes, but the provided one is %zu bytes.\n", + NISSY_SIZE_H48, buf_size); + return NISSY_ERROR_BUFFER_SIZE; + } + + pieces(&cube, corner, edge); + + for (i = 0; i < 12; i++) { + piece = edge[i]; + perm = piece & PBITS; + orient = (piece & EOBIT) >> EOSHIFT; + buf[4*i ] = edgestr[perm][0]; + buf[4*i + 1] = edgestr[perm][1]; + buf[4*i + 2] = orient + '0'; + buf[4*i + 3] = ' '; + } + for (i = 0; i < 8; i++) { + piece = corner[i]; + perm = piece & PBITS; + orient = (piece & COBITS) >> COSHIFT; + buf[48 + 5*i ] = cornerstr[perm][0]; + buf[48 + 5*i + 1] = cornerstr[perm][1]; + buf[48 + 5*i + 2] = cornerstr[perm][2]; + buf[48 + 5*i + 3] = orient + '0'; + buf[48 + 5*i + 4] = ' '; + } + + buf[48+39] = '\0'; + + return NISSY_OK; +} + +STATIC int64_t +writecube_LST(cube_t cube, size_t buf_size, char buf[buf_size]) +{ + int i; + uint64_t ptr; + uint8_t piece, corner[8], edge[12]; + + ptr = 0; + pieces(&cube, corner, edge); + + for (i = 0; i < 8; i++) { + piece = corner[i]; + ptr += writepiece_LST(piece, buf_size - ptr, buf + ptr); + if (ptr == 0) + goto writecube_LST_error; + } + + for (i = 0; i < 12; i++) { + piece = edge[i]; + ptr += writepiece_LST(piece, buf_size - ptr, buf + ptr); + if (ptr == 0) + goto writecube_LST_error; + } + + *(buf+ptr-2) = '\0'; + + return NISSY_OK; + +writecube_LST_error: + LOG("Cannot write cube in LST: buffer is too small (%" PRIu64 + " bytes given). The LST format has a variable size, try a " + "larger buffer.\n", buf_size); + return NISSY_ERROR_BUFFER_SIZE; +} + +STATIC uint8_t +b32toedge(char c) +{ + if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'f'))) + return UINT8_ERROR; + + return c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26; +} + +STATIC uint8_t +b32tocorner(char c) { + uint8_t val; + + if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'f'))) + return UINT8_ERROR; + + val = c <= 'Z' ? (uint8_t)(c - 'A') : (uint8_t)(c - 'a') + 26; + + return (val & 7) | ((val & 24) << 2); +} + +STATIC char +edgetob32(uint8_t edge) +{ + return edge < 26 ? 'A' + (char)edge : 'a' + (char)(edge - 26); +} + +STATIC char +cornertob32(uint8_t corner) +{ + uint8_t val; + + val = (corner & 7) | ((corner & 96) >> 2); + + return val < 26 ? 'A' + (char)val : 'a' + (char)(val - 26); +} diff --git a/src/core/io_moves.h b/src/core/io_moves.h deleted file mode 100644 index 97926cc..0000000 --- a/src/core/io_moves.h +++ /dev/null @@ -1,127 +0,0 @@ -STATIC uint8_t readmove(char); -STATIC int64_t readmoves(const char *, size_t n, uint8_t [n]); -STATIC int64_t countmoves(const char *); -STATIC uint8_t readmodifier(char); -STATIC int64_t writemoves(size_t n, const uint8_t [n], size_t m, char [m]); - -#define FOREACH_READMOVE(ARG_BUF, ARG_MOVE, ARG_C, ARG_MAX, \ - RET_ERROR, ARG_ACTION) \ - const char *VAR_B; \ - uint8_t VAR_MOVE_NOMOD, VAR_MOD; \ - for (VAR_B = ARG_BUF, ARG_C = 0; *VAR_B != '\0'; VAR_B++, ARG_C++) { \ - while (*VAR_B == ' ' || *VAR_B == '\t' || *VAR_B == '\n') \ - VAR_B++; \ - if (*VAR_B == '\0' || ARG_C == ARG_MAX) \ - break; \ - if ((VAR_MOVE_NOMOD = readmove(*VAR_B)) == UINT8_ERROR) { \ - LOG("Unknown move: %c\n", *VAR_B); \ - return RET_ERROR; \ - } \ - if ((VAR_MOD = readmodifier(*(VAR_B+1))) != 0) \ - VAR_B++; \ - ARG_MOVE = VAR_MOVE_NOMOD + VAR_MOD; \ - ARG_ACTION \ - } - -STATIC uint8_t -readmove(char c) -{ - switch (c) { - case 'U': - return MOVE_U; - case 'D': - return MOVE_D; - case 'R': - return MOVE_R; - case 'L': - return MOVE_L; - case 'F': - return MOVE_F; - case 'B': - return MOVE_B; - default: - return UINT8_ERROR; - } -} - -STATIC uint8_t -readmodifier(char c) -{ - switch (c) { - case '1': /* Fallthrough */ - case '2': /* Fallthrough */ - case '3': - return c - '0' - 1; - case '\'': - return 2; - default: - return 0; - } -} - -STATIC int64_t -readmoves(const char *buf, size_t n, uint8_t ret[n]) -{ - uint8_t m; - uint64_t c; - - FOREACH_READMOVE(buf, m, c, n, NISSY_ERROR_INVALID_MOVES, - ret[c] = m; - ) - - return (int64_t)c; -} - -STATIC int64_t -countmoves(const char *buf) -{ - uint8_t m; - uint64_t c; - - FOREACH_READMOVE(buf, m, c, INT_MAX, NISSY_ERROR_INVALID_MOVES, - {} - ) - - (void)m; /* Ignore "variable set but not used" warning */ - - return (int64_t)c; -} - -STATIC int64_t -writemoves( - size_t nmoves, - const uint8_t m[nmoves], - size_t buf_size, - char buf[buf_size] -) -{ - size_t i, len, w; - const char *s; - - if (buf_size == 0) { - LOG("Error: cannot write moves to buffer of size 0.\n"); - return NISSY_ERROR_BUFFER_SIZE; - } - - for (i = 0, w = 0; i < nmoves; i++, w++) { - s = movestr[m[i]]; - len = strlen(s); - if (len + w >= buf_size) { - LOG("Error: the given buffer is too small for " - "writing the given moves.\n"); - goto writemoves_error; - } - memcpy(buf+w, s, len); - w += len; - buf[w] = ' '; - } - - if (w > 0) w--; /* Remove last space */ - buf[w] = '\0'; - - return (int64_t)w; - -writemoves_error: - *buf = '\0'; - return NISSY_ERROR_BUFFER_SIZE; -} diff --git a/src/core/io_trans.h b/src/core/io_trans.h deleted file mode 100644 index 71b2287..0000000 --- a/src/core/io_trans.h +++ /dev/null @@ -1,24 +0,0 @@ -STATIC uint8_t readtrans(const char [static NISSY_SIZE_TRANSFORMATION]); -STATIC void writetrans(uint8_t, char [static NISSY_SIZE_TRANSFORMATION]); - -STATIC uint8_t -readtrans(const char buf[static NISSY_SIZE_TRANSFORMATION]) -{ - uint8_t t; - - for (t = 0; t < NTRANS; t++) - if (!strncmp(buf, transstr[t], 11)) - return t; - - return UINT8_ERROR; -} - -STATIC void -writetrans(uint8_t t, char buf[static NISSY_SIZE_TRANSFORMATION]) -{ - if (t >= 48) - memcpy(buf, "error trans", 11); - else - memcpy(buf, transstr[t], 11); - buf[11] = '\0'; -} diff --git a/src/core/moves.h b/src/core/moves.h index cc91706..8f91167 100644 --- a/src/core/moves.h +++ b/src/core/moves.h @@ -1,6 +1,12 @@ #define MOVE(M, c) compose(c, MOVE_CUBE_ ## M) #define PREMOVE(M, c) compose(MOVE_CUBE_ ## M, c) +STATIC uint8_t readmove(char); +STATIC int64_t readmoves(const char *, size_t n, uint8_t [n]); +STATIC int64_t countmoves(const char *); +STATIC uint8_t readmodifier(char); +STATIC int64_t writemoves(size_t n, const uint8_t [n], size_t m, char [m]); + STATIC_INLINE bool allowednextmove(uint8_t, uint8_t); STATIC bool allowedmoves(size_t n, const uint8_t [n]); @@ -17,6 +23,128 @@ STATIC bool are_lastmoves_singlecw(size_t n, const uint8_t [n]); STATIC cube_t applymoves(cube_t, const char *); +#define FOREACH_READMOVE(ARG_BUF, ARG_MOVE, ARG_C, ARG_MAX, \ + RET_ERROR, ARG_ACTION) \ + const char *VAR_B; \ + uint8_t VAR_MOVE_NOMOD, VAR_MOD; \ + for (VAR_B = ARG_BUF, ARG_C = 0; *VAR_B != '\0'; VAR_B++, ARG_C++) { \ + while (*VAR_B == ' ' || *VAR_B == '\t' || *VAR_B == '\n') \ + VAR_B++; \ + if (*VAR_B == '\0' || ARG_C == ARG_MAX) \ + break; \ + if ((VAR_MOVE_NOMOD = readmove(*VAR_B)) == UINT8_ERROR) { \ + LOG("Unknown move: %c\n", *VAR_B); \ + return RET_ERROR; \ + } \ + if ((VAR_MOD = readmodifier(*(VAR_B+1))) != 0) \ + VAR_B++; \ + ARG_MOVE = VAR_MOVE_NOMOD + VAR_MOD; \ + ARG_ACTION \ + } + +STATIC uint8_t +readmove(char c) +{ + switch (c) { + case 'U': + return MOVE_U; + case 'D': + return MOVE_D; + case 'R': + return MOVE_R; + case 'L': + return MOVE_L; + case 'F': + return MOVE_F; + case 'B': + return MOVE_B; + default: + return UINT8_ERROR; + } +} + +STATIC uint8_t +readmodifier(char c) +{ + switch (c) { + case '1': /* Fallthrough */ + case '2': /* Fallthrough */ + case '3': + return c - '0' - 1; + case '\'': + return 2; + default: + return 0; + } +} + +STATIC int64_t +readmoves(const char *buf, size_t n, uint8_t ret[n]) +{ + uint8_t m; + uint64_t c; + + FOREACH_READMOVE(buf, m, c, n, NISSY_ERROR_INVALID_MOVES, + ret[c] = m; + ) + + return (int64_t)c; +} + +STATIC int64_t +countmoves(const char *buf) +{ + uint8_t m; + uint64_t c; + + FOREACH_READMOVE(buf, m, c, INT_MAX, NISSY_ERROR_INVALID_MOVES, + {} + ) + + (void)m; /* Ignore "variable set but not used" warning */ + + return (int64_t)c; +} + +STATIC int64_t +writemoves( + size_t nmoves, + const uint8_t m[nmoves], + size_t buf_size, + char buf[buf_size] +) +{ + size_t i, len, w; + const char *s; + + if (buf_size == 0) { + LOG("Error: cannot write moves to buffer of size 0.\n"); + return NISSY_ERROR_BUFFER_SIZE; + } + + for (i = 0, w = 0; i < nmoves; i++, w++) { + s = movestr[m[i]]; + len = strlen(s); + if (len + w >= buf_size) { + LOG("Error: the given buffer is too small for " + "writing the given moves.\n"); + goto writemoves_error; + } + memcpy(buf+w, s, len); + w += len; + buf[w] = ' '; + } + + if (w > 0) w--; /* Remove last space */ + buf[w] = '\0'; + + return (int64_t)w; + +writemoves_error: + *buf = '\0'; + return NISSY_ERROR_BUFFER_SIZE; +} + STATIC_INLINE bool allowednextmove(uint8_t m1, uint8_t m2) { diff --git a/src/core/transform.h b/src/core/transform.h index b480593..28b8d93 100644 --- a/src/core/transform.h +++ b/src/core/transform.h @@ -17,6 +17,9 @@ invertco(compose(compose(TRANS_CUBE_ ## T, c), \ TRANS_CUBE_ ## T ## _INVERSE)) +STATIC uint8_t readtrans(const char [static NISSY_SIZE_TRANSFORMATION]); +STATIC void writetrans(uint8_t, char [static NISSY_SIZE_TRANSFORMATION]); + STATIC cube_t transform_edges(cube_t, uint8_t); STATIC cube_t transform_corners(cube_t, uint8_t); STATIC cube_t transform(cube_t, uint8_t); @@ -25,6 +28,28 @@ STATIC_INLINE uint8_t inverse_trans(uint8_t); STATIC uint8_t transform_move(uint8_t, uint8_t); STATIC uint64_t symmetry_mask(cube_t); +STATIC uint8_t +readtrans(const char buf[static NISSY_SIZE_TRANSFORMATION]) +{ + uint8_t t; + + for (t = 0; t < NTRANS; t++) + if (!strncmp(buf, transstr[t], 11)) + return t; + + return UINT8_ERROR; +} + +STATIC void +writetrans(uint8_t t, char buf[static NISSY_SIZE_TRANSFORMATION]) +{ + if (t >= 48) + memcpy(buf, "error trans", 11); + else + memcpy(buf, transstr[t], 11); + buf[11] = '\0'; +} + STATIC cube_t transform_edges(cube_t c, uint8_t t) { -- cgit v1.3