commit 2edc8c01fba711f4410279b59c784a43cf2dde41 parent 9ef630eefb683dcdbe56e96e51b10bf356f20505 Author: Sebastiano Tronto <sebastiano@tronto.net> Date: Sun, 8 Oct 2023 14:04:11 +0200 Added write to SRC format Diffstat:
31 files changed, 186 insertions(+), 63 deletions(-)
diff --git a/.gitignore b/.gitignore @@ -2,3 +2,4 @@ test/*/runtest test/run test/last.* test/*.o +*.o diff --git a/src/cube.h b/src/cube.h @@ -7,12 +7,11 @@ typedef uint8_t trans_t; extern cube_t solvedcube; -/* For the textual representation of the cube, see utils/FORMAT.txt */ -cube_t readcube(char *); -void writecube(cube_t, char *); - -/* Writes a cube in C source code format */ -void writecubesrc(cube_t, char *); +/* Not all formats are supported for both read and write. */ +/* See utils/FORMAT.txt for details. */ +typedef enum {H48, SRC} format_t; +cube_t readcube(format_t, char *); +void writecube(format_t, cube_t, char *); bool issolvable(cube_t); bool equal(cube_t, cube_t); diff --git a/src/cube_array.c b/src/cube_array.c @@ -156,6 +156,10 @@ static uint8_t readeo(char *); static uint8_t readep(char *); static uint8_t readmove(char); static uint8_t readmodifier(char); +static cube_t readcube_H48(char *); +static void writecube_H48(cube_t, char *); +static int writepiece_SRC(uint8_t, char *); +static void writecube_SRC(cube_t, char *); static int permsign(uint8_t *, int); static uint8_t @@ -219,8 +223,8 @@ readep(char *str) return _error; } -cube_t -readcube(char *buf) +static cube_t +readcube_H48(char *buf) { int i; uint8_t piece, orient; @@ -231,10 +235,10 @@ readcube(char *buf) while (*b == ' ' || *b == '\t' || *b == '\n') b++; if ((piece = readep(b)) == _error) - goto readcube_error; + return errorcube; b += 2; if ((orient = readeo(b)) == _error) - goto readcube_error; + return errorcube; b++; ret.e[i] = piece | orient; } @@ -242,36 +246,46 @@ readcube(char *buf) while (*b == ' ' || *b == '\t' || *b == '\n') b++; if ((piece = readcp(b)) == _error) - goto readcube_error; + return errorcube; b += 3; if ((orient = readco(b)) == _error) - goto readcube_error; + return errorcube; b++; ret.c[i] = piece | orient; } return ret; +} + +cube_t +readcube(format_t format, char *buf) +{ + cube_t ret; + + switch (format) { + case H48: + ret = readcube_H48(buf); + break; + default: + #ifdef DEBUG + fprintf(stderr, "Cannot read cube in the given format\n"); + #endif + ret = errorcube; + } -readcube_error: #ifdef DEBUG - fprintf(stderr, "readcube error\n"); + if (iserror(ret)) + fprintf(stderr, "readcube error\n"); #endif - return errorcube; + return ret; } -void -writecube(cube_t cube, char *buf) +static void +writecube_H48(cube_t cube, char *buf) { - char *errormsg; uint8_t piece, orient; - size_t len; int i; - if (!isconsistent(cube)) { - errormsg = "ERROR: cannot write inconsistent cube"; - goto writecube_error; - } - for (i = 0; i < 12; i++) { piece = cube.e[i] & _pbits; orient = (cube.e[i] & _eobit) >> _eoshift; @@ -291,6 +305,73 @@ writecube(cube_t cube, char *buf) } buf[48+39] = '\0'; +} + +static int +writepiece_SRC(uint8_t piece, char *buf) +{ + char digits[3]; + int i, len = 0; + + while (piece != 0) { + digits[len++] = (piece % 10) + '0'; + piece /= 10; + } + + 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 void +writecube_SRC(cube_t cube, char *buf) +{ + int i, ptr; + + memcpy(buf, "{\n\t.c = {", 9); + ptr = 9; + + for (i = 0; i < 8; i++) + ptr += writepiece_SRC(cube.c[i], buf + ptr); + + memcpy(buf+ptr-2, "},\n\t.e = {", 10); + ptr += 8; + + for (i = 0; i < 12; i++) + ptr += writepiece_SRC(cube.e[i], buf + ptr); + + memcpy(buf+ptr-2, "}\n}\0", 4); +} + +void +writecube(format_t format, cube_t cube, char *buf) +{ + char *errormsg; + size_t len; + + if (!isconsistent(cube)) { + errormsg = "ERROR: cannot write inconsistent cube"; + goto writecube_error; + } + + switch (format) { + case H48: + writecube_H48(cube, buf); + break; + case SRC: + writecube_SRC(cube, buf); + break; + default: + errormsg = "ERROR: cannot write cube in the given format"; + goto writecube_error; + } return; @@ -304,7 +385,6 @@ writecube_error: buf[len+1] = '\0'; } - static uint8_t readmove(char c) { diff --git a/test/01_io/00_garbage.in b/test/010_io_H48/00_garbage.in diff --git a/test/01_io/00_garbage.out b/test/010_io_H48/00_garbage.out diff --git a/test/01_io/01_solved_oneline.in b/test/010_io_H48/01_solved_oneline.in diff --git a/test/01_io/01_solved_oneline.out b/test/010_io_H48/01_solved_oneline.out diff --git a/test/01_io/02_solved_oneline_whitespace.in b/test/010_io_H48/02_solved_oneline_whitespace.in diff --git a/test/01_io/02_solved_oneline_whitespace.out b/test/010_io_H48/02_solved_oneline_whitespace.out diff --git a/test/01_io/03_solved_multiline.in b/test/010_io_H48/03_solved_multiline.in diff --git a/test/01_io/03_solved_multiline.out b/test/010_io_H48/03_solved_multiline.out diff --git a/test/01_io/04_unsolvable_ep.in b/test/010_io_H48/04_unsolvable_ep.in diff --git a/test/01_io/04_unsolvable_ep.out b/test/010_io_H48/04_unsolvable_ep.out diff --git a/test/01_io/05_unsolvable_eo.in b/test/010_io_H48/05_unsolvable_eo.in diff --git a/test/01_io/05_unsolvable_eo.out b/test/010_io_H48/05_unsolvable_eo.out diff --git a/test/01_io/06_unsolvable_cp.in b/test/010_io_H48/06_unsolvable_cp.in diff --git a/test/01_io/06_unsolvable_cp.out b/test/010_io_H48/06_unsolvable_cp.out diff --git a/test/01_io/07_unsolvable_co.in b/test/010_io_H48/07_unsolvable_co.in diff --git a/test/01_io/07_unsolvable_co.out b/test/010_io_H48/07_unsolvable_co.out diff --git a/test/01_io/08_unsolved.in b/test/010_io_H48/08_unsolved.in diff --git a/test/01_io/08_unsolved.out b/test/010_io_H48/08_unsolved.out diff --git a/test/010_io_H48/io_H48_tests.c b/test/010_io_H48/io_H48_tests.c @@ -0,0 +1,28 @@ +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> + +#include "../../src/cube.h" + +#define STRLENMAX 10000 + +int main() { + char *c, str[STRLENMAX]; + cube_t cube; + + for (c = str; (*c = getchar()) != EOF; c++) ; + *c = '\0'; + + cube = readcube(H48, str); + + if (iserror(cube)) { + printf("Error reading cube\n"); + } else if (!issolvable(cube)) { + printf("Cube is not solvable\n"); + } else { + writecube(H48, cube, str); + printf("%s\n", str); + } + + return 0; +} diff --git a/test/01_io/01_solved_oneline.in b/test/011_io_SRC/01_solved.in diff --git a/test/011_io_SRC/01_solved.out b/test/011_io_SRC/01_solved.out @@ -0,0 +1,4 @@ +{ + .c = {0, 1, 2, 3, 4, 5, 6, 7}, + .e = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} +} diff --git a/test/011_io_SRC/io_SRC_tests.c b/test/011_io_SRC/io_SRC_tests.c @@ -0,0 +1,28 @@ +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> + +#include "../../src/cube.h" + +#define STRLENMAX 10000 + +int main() { + char *c, str[STRLENMAX]; + cube_t cube; + + for (c = str; (*c = getchar()) != EOF; c++) ; + *c = '\0'; + + cube = readcube(H48, str); + + if (iserror(cube)) { + printf("Error reading cube\n"); + } else if (!issolvable(cube)) { + printf("Cube is not solvable\n"); + } else { + writecube(SRC, cube, str); + printf("%s\n", str); + } + + return 0; +} diff --git a/test/01_io/io_tests.c b/test/01_io/io_tests.c @@ -1,28 +0,0 @@ -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> - -#include "../../src/cube.h" - -#define STRLENMAX 10000 - -int main() { - char *c, str[STRLENMAX]; - cube_t cube; - - for (c = str; (*c = getchar()) != EOF; c++) ; - *c = '\0'; - - cube = readcube(str); - - if (iserror(cube)) { - printf("Error reading cube\n"); - } else if (!issolvable(cube)) { - printf("Cube is not solvable\n"); - } else { - writecube(cube, str); - printf("%s\n", str); - } - - return 0; -} diff --git a/test/02_move/move_tests.c b/test/02_move/move_tests.c @@ -22,7 +22,7 @@ int main() { } fgets(str, STRLENMAX, stdin); - cube = readcube(str); + cube = readcube(H48, str); for (i = 0; i < n; i++) cube = move(cube, moves[i]); @@ -32,7 +32,7 @@ int main() { } else if (!issolvable(cube)) { printf("Moved cube is not solvable\n"); } else { - writecube(cube, str); + writecube(H48, cube, str); printf("%s\n", str); } diff --git a/test/03_inverse/inverse_tests.c b/test/03_inverse/inverse_tests.c @@ -11,7 +11,7 @@ int main() { cube_t cube, inv; fgets(str, STRLENMAX, stdin); - cube = readcube(str); + cube = readcube(H48, str); inv = inverse(cube); if (iserror(inv)) { @@ -19,7 +19,7 @@ int main() { } else if (!issolvable(inv)) { printf("Inverted cube is not solvable\n"); } else { - writecube(inv, str); + writecube(H48, inv, str); printf("%s\n", str); } diff --git a/test/04_compose/compose_tests.c b/test/04_compose/compose_tests.c @@ -11,9 +11,9 @@ int main() { cube_t c1, c2, c3; fgets(str, STRLENMAX, stdin); - c1 = readcube(str); + c1 = readcube(H48, str); fgets(str, STRLENMAX, stdin); - c2 = readcube(str); + c2 = readcube(H48, str); c3 = compose(c1, c2); @@ -22,7 +22,7 @@ int main() { } else if (!issolvable(c3)) { printf("Composed cube is not solvable\n"); } else { - writecube(c3, str); + writecube(H48, c3, str); printf("%s\n", str); } diff --git a/test/test.sh b/test/test.sh @@ -11,7 +11,7 @@ TESTOUT="test/last.out" TESTERR="test/last.err" CUBEOBJ="test/cube.o" -$CC -c $SRC -o $CUBEOBJ +$CC -c $SRC -o $CUBEOBJ || exit 1 for t in test/*; do if [ ! -d $t ]; then continue; fi diff --git a/utils/FORMAT.txt b/utils/FORMAT.txt @@ -1,4 +1,8 @@ -The functions readcube() and writecube() use the following format. +The functions readcube() and writecube() use different formats to read +and write a cube to text. Not all formats are supported for both input +and output. + +# H48 - standard format for h48 (read, write) Each edge is represented by two letters denoting the sides it belongs to and one number denoting its orientation (0 oriented, 1 mis-oriented). @@ -21,4 +25,11 @@ The cube after the moves R'U'F looks like this: FL1 BR0 DB0 UR1 UF0 UB0 DL0 FR0 UL1 DF1 BL0 DR0 UBL1 DBR1 UFR2 DFR2 DFL2 UBL2 UFL2 DBL0 -More formats might be supported in the future. +# SRC - representation of the object in C code (write) + +The exact format depends on the internal cube representation. It is +guaranteed that, if OUT is the output in this format, the line + +cube_t cube = OUT; + +is interpreted correctly by h48.