commit 79c9c600f7a620e3e804ff7783511ad7da7d8f93
parent 5e291466fbbc45aed74f67a1b2e555d1f0c44d8f
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Fri, 11 Oct 2024 12:04:02 +0200
Error codes, documentation, change nisstype from string to flags
Diffstat:
M | shell.c | | | 25 | ++++++++++++++----------- |
M | src/nissy.c | | | 300 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------ |
M | src/nissy.h | | | 229 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------- |
3 files changed, 460 insertions(+), 94 deletions(-)
diff --git a/shell.c b/shell.c
@@ -49,7 +49,7 @@ typedef struct {
char *str_moves;
char *str_trans;
char *str_solver;
- char *str_nisstype; /* TODO: remove, use flags */
+ char *str_nisstype;
int8_t minmoves;
int8_t maxmoves;
int8_t optimal;
@@ -108,7 +108,7 @@ struct {
OPTION(FLAG_MOVES, 1, set_str_moves),
OPTION(FLAG_TRANS, 1, set_str_trans),
OPTION(FLAG_SOLVER, 1, set_str_solver),
- OPTION(FLAG_NISSTYPE, 1, set_str_nisstype), /* TODO: remove, use flags */
+ OPTION(FLAG_NISSTYPE, 1, set_str_nisstype), /* TODO: more args ? */
OPTION(FLAG_MINMOVES, 1, set_minmoves),
OPTION(FLAG_MAXMOVES, 1, set_maxmoves),
OPTION(FLAG_OPTIMAL, 1, set_optimal),
@@ -244,7 +244,7 @@ compose_exec(args_t *args)
int64_t ret;
ret = nissy_compose(args->cube, args->cube_perm, result);
- if (ret == 0)
+ if (ret == NISSY_OK || ret == NISSY_WARNING_UNSOLVABLE)
printf("%s\n", result);
return ret;
@@ -257,7 +257,7 @@ inverse_exec(args_t *args)
int64_t ret;
ret = nissy_inverse(args->cube, result);
- if (ret == 0)
+ if (ret == NISSY_OK || ret == NISSY_WARNING_UNSOLVABLE)
printf("%s\n", result);
return ret;
@@ -270,7 +270,7 @@ applymoves_exec(args_t *args)
int64_t ret;
ret = nissy_applymoves(args->cube, args->str_moves, result);
- if (ret == 0)
+ if (ret == NISSY_OK || ret == NISSY_WARNING_UNSOLVABLE)
printf("%s\n", result);
return ret;
@@ -283,7 +283,7 @@ applytrans_exec(args_t *args)
int64_t ret;
ret = nissy_applytrans(args->cube, args->str_trans, result);
- if (ret == 0)
+ if (ret == NISSY_OK || ret == NISSY_WARNING_UNSOLVABLE)
printf("%s\n", result);
return ret;
@@ -296,7 +296,7 @@ frommoves_exec(args_t *args)
int64_t ret;
ret = nissy_frommoves(args->str_moves, result);
- if (ret == 0)
+ if (ret == NISSY_OK || ret == NISSY_WARNING_UNSOLVABLE)
printf("%s\n", result);
return ret;
@@ -310,7 +310,7 @@ convert_exec(args_t *args)
ret = nissy_convert(
args->str_format_in, args->str_format_out, args->str_cube, result);
- if (ret == 0)
+ if (ret == NISSY_OK || ret == NISSY_WARNING_UNSOLVABLE)
printf("%s\n", result);
return ret;
@@ -327,7 +327,7 @@ randomcube_exec(args_t *args)
cp = rand64();
co = rand64();
ret = nissy_getcube(ep, eo, cp, co, "fix", result);
- if (ret == 0)
+ if (ret == NISSY_OK || ret == NISSY_WARNING_UNSOLVABLE)
printf("%s\n", result);
return ret;
@@ -418,11 +418,14 @@ static int64_t
solve_exec(args_t *args)
{
int i;
+ uint8_t nissflag;
FILE *file;
char *buf, solutions[SOLUTIONS_BUFFER_SIZE], path[MAX_PATH_LENGTH];
int64_t ret, gendata_ret, size;
size_t read;
+ nissflag = NISSY_NISSFLAG_NORMAL; /* TODO: parse str_nisstype */
+
for (i = 0; tablepaths[i] != NULL; i++) {
strcpy(path, tablepaths[i]);
strcat(path, args->str_solver);
@@ -469,12 +472,12 @@ solve_exec(args_t *args)
}
ret = nissy_solve(
- args->cube, args->str_solver, args->str_nisstype, args->minmoves,
+ args->cube, args->str_solver, nissflag, args->minmoves,
args->maxmoves, args->maxsolutions, args->optimal, buf, solutions);
free(buf);
- if (ret == 0)
+ if (ret == NISSY_OK || ret == NISSY_WARNING_UNSOLVABLE)
fprintf(stderr, "No solutions found\n");
else
printf("%s", solutions);
diff --git a/src/nissy.c b/src/nissy.c
@@ -109,20 +109,14 @@ distribution_equal(
STATIC int64_t
write_result(cube_t cube, char result[static 22])
{
- if (!isconsistent(cube)) {
- LOG("Error: resulting cube is invalid\n");
- writecube("B32", ZERO_CUBE, result);
- return 8;
- }
-
writecube("B32", cube, result);
if (!issolvable(cube)) {
LOG("Warning: resulting cube is not solvable\n");
- return 9;
+ return NISSY_WARNING_UNSOLVABLE;
}
- return 0;
+ return NISSY_OK;
}
int64_t
@@ -133,24 +127,37 @@ nissy_compose(
)
{
cube_t c, p, res;
+ int64_t err;
c = readcube("B32", cube);
if (!isconsistent(c)) {
LOG("Error in nissy_compose: given cube is invalid\n");
- return 1;
+ err = NISSY_ERROR_INVALID_CUBE;
+ goto nissy_compose_error;
}
p = readcube("B32", permutation);
if (!isconsistent(p)) {
LOG("Error in nissy_compose: given permutation is invalid\n");
- return 2;
+ err = NISSY_ERROR_INVALID_CUBE;
+ goto nissy_compose_error;
}
res = compose(c, p);
+ if (!isconsistent(res)) {
+ LOG("Unknown error: resulting cube is invalid\n");
+ err = NISSY_ERROR_UNKNOWN;
+ goto nissy_compose_error;
+ }
+
return write_result(res, result);
+
+nissy_compose_error:
+ writecube("B32", ZERO_CUBE, result);
+ return err;
}
int64_t
@@ -160,17 +167,29 @@ nissy_inverse(
)
{
cube_t c, res;
+ int64_t err;
c = readcube("B32", cube);
if (iserror(c)) {
LOG("Error in nissy_inverse: given cube is invalid\n");
- return 1;
+ err = NISSY_ERROR_INVALID_CUBE;
+ goto nissy_inverse_error;
}
res = inverse(c);
+ if (!isconsistent(res)) {
+ LOG("Unknown error: inverted cube is invalid\n");
+ err = NISSY_ERROR_UNKNOWN;
+ goto nissy_inverse_error;
+ }
+
return write_result(res, result);
+
+nissy_inverse_error:
+ writecube("B32", ZERO_CUBE, result);
+ return err;
}
int64_t
@@ -181,17 +200,29 @@ nissy_applymoves(
)
{
cube_t c, res;
+ int64_t err;
c = readcube("B32", cube);
if (!isconsistent(c)) {
LOG("Error in nissy_applymoves: given cube is invalid\n");
- return 1;
+ err = NISSY_ERROR_INVALID_CUBE;
+ goto nissy_applymoves_error;
}
res = applymoves(c, moves);
+ if (!isconsistent(res)) {
+ /* Assume we got a reasonable error message from applymoves */
+ err = NISSY_ERROR_INVALID_MOVES;
+ goto nissy_applymoves_error;
+ }
+
return write_result(res, result);
+
+nissy_applymoves_error:
+ writecube("B32", ZERO_CUBE, result);
+ return err;
}
int64_t
@@ -202,17 +233,29 @@ nissy_applytrans(
)
{
cube_t c, res;
+ int64_t err;
c = readcube("B32", cube);
if (!isconsistent(c)) {
LOG("Error in nissy_applytrans: given cube is invalid\n");
- return 1;
+ err = NISSY_ERROR_INVALID_CUBE;
+ goto nissy_applytrans_error;
}
res = applytrans(c, transformation);
+ if (!isconsistent(res)) {
+ /* Assume we got a reasonable error message from applytrans */
+ err = NISSY_ERROR_INVALID_TRANS;
+ goto nissy_applytrans_error;
+ }
+
return write_result(res, result);
+
+nissy_applytrans_error:
+ writecube("B32", ZERO_CUBE, result);
+ return err;
}
int64_t
@@ -222,15 +265,21 @@ nissy_frommoves(
)
{
cube_t res;
+ int64_t err;
res = applymoves(SOLVED_CUBE, moves);
if (!isconsistent(res)) {
- /* Moves must be invalid */
- return 1;
+ /* Assume we got a reasonable error message from applymoves */
+ err = NISSY_ERROR_INVALID_MOVES;
+ goto nissy_frommoves_error;
}
return write_result(res, result);
+
+nissy_frommoves_error:
+ writecube("B32", ZERO_CUBE, result);
+ return err;
}
int64_t
@@ -241,20 +290,35 @@ nissy_convert(
char *result
)
{
- int ret;
cube_t c;
+ int ret;
+ int64_t err;
c = readcube(format_in, cube_string);
- if (iserror(c))
- return 1;
+ if (iserror(c)) {
+ err = NISSY_ERROR_INVALID_CUBE;
+ goto nissy_convert_error;
+ }
ret = writecube(format_out, c, result);
- if (ret != 0)
- return 2;
+ if (ret != 0) {
+ /* Assume the format was invalid */
+ err = NISSY_ERROR_INVALID_FORMAT;
+ goto nissy_convert_error;
+ }
+
+ if (!isconsistent(c)) {
+ err = NISSY_ERROR_UNKNOWN;
+ goto nissy_convert_error;
+ }
- return isconsistent(c) ? 0 : 3;
+ return NISSY_OK;
+
+nissy_convert_error:
+ /* We don't write anything to result, we don't know the format */
+ return err;
}
int64_t
@@ -276,6 +340,13 @@ nissy_getcube(
c = getcube(ep, eo, cp, co);
+ if (!isconsistent(c)) {
+ LOG("Error: could not get cube with ep=%" PRId64 ", eo=%"
+ PRId64 ", cp=%" PRId64 ", co=%" PRId64 ".\n",
+ ep, eo, cp, co);
+ return NISSY_ERROR_OPTIONS;
+ }
+
return write_result(c, result);
}
@@ -290,14 +361,14 @@ nissy_datasize(
int64_t
nissy_datainfo(
- const void *table,
+ const void *data,
void (*write)(const char *, ...)
)
{
uint8_t i;
tableinfo_t info;
- readtableinfo(table, &info);
+ readtableinfo(data, &info);
write("\n---------\n\n");
write("Table information for '%s'\n", info.solver);
@@ -321,16 +392,15 @@ nissy_datainfo(
break;
default:
LOG("datainfo: unknown table type\n");
- return 1;
+ return NISSY_ERROR_DATA;
}
- if (info.next != 0) {
- return nissy_datainfo((char *)table + info.next, write);
- }
+ if (info.next != 0)
+ return nissy_datainfo((char *)data + info.next, write);
write("\n---------\n");
- return 0;
+ return NISSY_OK;
}
int64_t
@@ -340,20 +410,19 @@ nissy_gendata(
)
{
int p;
- int64_t ret;
gendata_h48_arg_t arg;
arg.buf = data;
if (!strncmp(solver, "h48", 3)) {
p = parse_h48_solver(solver, &arg.h, &arg.k);
arg.maxdepth = 20;
- ret = p == 0 ? (int64_t)gendata_h48(&arg) : -1;
+ if (p != 0)
+ return NISSY_ERROR_UNKNOWN;
+ return (int64_t)gendata_h48(&arg);
} else {
LOG("gendata: unknown solver %s\n", solver);
- ret = -1;
+ return NISSY_ERROR_INVALID_SOLVER;
}
-
- return ret;
}
int64_t
@@ -369,20 +438,20 @@ nissy_checkdata(
if (!checkdata(buf, &info)) {
LOG("Error: data for %s is inconsistent with info!\n",
info.solver);
- return 1;
+ return NISSY_ERROR_DATA;
}
if (info.next == 0)
break;
}
- return 0;
+ return NISSY_OK;
}
int64_t
nissy_solve(
const char cube[static 22],
const char *solver,
- const char *nisstype,
+ uint8_t nissflag,
int8_t minmoves,
int8_t maxmoves,
int64_t maxsolutions,
@@ -397,9 +466,14 @@ nissy_solve(
c = readcube_B32(cube);
+ if (!isconsistent(c)) {
+ LOG("solve: cube is invalid\n");
+ return NISSY_ERROR_INVALID_CUBE;
+ }
+
if (!issolvable(c)) {
LOG("solve: cube is not solvable\n");
- return -1;
+ return NISSY_ERROR_UNSOLVABLE_CUBE;
}
if (minmoves < 0) {
@@ -414,7 +488,7 @@ nissy_solve(
if (maxsolutions < 0) {
LOG("solve: 'maxsols' is negative, stopping\n");
- return -1;
+ return NISSY_ERROR_OPTIONS;
}
if (maxsolutions == 0) {
@@ -424,7 +498,7 @@ nissy_solve(
if (solutions == NULL) {
LOG("solve: return parameter 'solutions' is NULL, stopping\n");
- return -1;
+ return NISSY_ERROR_NULL_POINTER;
}
if (!strncmp(solver, "h48", 3)) {
@@ -433,7 +507,8 @@ nissy_solve(
p = parse_h48_solver(solver, &h, &k);
if (p != 0) {
- return -1;
+ LOG("solve: unknown solver %s\n", solver);
+ return NISSY_ERROR_INVALID_SOLVER;
} else {
return THREADS > 1 ?
solve_h48_multithread(c, minmoves,
@@ -446,12 +521,151 @@ nissy_solve(
c, minmoves, maxmoves, maxsolutions, optimal, solutions);
} else {
LOG("solve: unknown solver '%s'\n", solver);
- return -1;
+ return NISSY_ERROR_INVALID_SOLVER;
}
}
-void
-nissy_setlogger(void (*log)(const char *, ...))
+int64_t
+nissy_setlogger(
+ void (*log)(const char *, ...)
+)
{
nissy_log = log;
+
+ if (log == NULL)
+ return NISSY_WARNING_NULL_CALLBACK;
+
+ return NISSY_OK;
+}
+
+int64_t
+nissy_explainerror(
+ int64_t error_code,
+ void (*write)(const char *, ...)
+)
+{
+ if (write == NULL)
+ return NISSY_WARNING_NULL_CALLBACK;
+
+ switch (error_code) {
+ case NISSY_OK:
+ write(
+ "The value %" PRId64 " denotes a success.\n"
+ "If returned by solve, it means that no solutions has "
+ "been found.\n", NISSY_OK
+ );
+ return NISSY_OK;
+ case NISSY_WARNING_UNSOLVABLE:
+ write(
+ "The value %" PRId64 " is a warning. It means that the "
+ "operation was completed succesfully, but the resulting "
+ "cube is in an unsolvable state. This could be intended, "
+ "for example if the user has provided an unsolvable cube "
+ "as input.\n", NISSY_WARNING_UNSOLVABLE
+ );
+ return NISSY_OK;
+ case NISSY_WARNING_NULL_CALLBACK:
+ write(
+ "The value %" PRId64 " is a warning. It means that the "
+ "provided pointer to a writer function is NULL.\n"
+ "If returned by nissy_setlogger, it means that any future "
+ "log messages will not be printed.\n",
+ NISSY_WARNING_NULL_CALLBACK
+ );
+ return NISSY_OK;
+ case NISSY_ERROR_INVALID_CUBE:
+ write(
+ "The value %" PRId64 " means that the provided cube is "
+ "invalid. It could be written in an unknown format, or "
+ "in a format different from what specified, or simply "
+ "ill-formed.\n", NISSY_ERROR_INVALID_CUBE
+ );
+ return NISSY_OK;
+ case NISSY_ERROR_UNSOLVABLE_CUBE:
+ write(
+ "The value %" PRId64 " means that the provided cube is "
+ "in an unsolvable state.\n", NISSY_ERROR_INVALID_CUBE
+ );
+ return NISSY_OK;
+ case NISSY_ERROR_INVALID_MOVES:
+ write(
+ "The value %" PRId64 " means that the given moves are "
+ "invalid.\n", NISSY_ERROR_INVALID_MOVES
+ );
+ return NISSY_OK;
+ case NISSY_ERROR_INVALID_TRANS:
+ write(
+ "The value %" PRId64 " means that the given transformation "
+ "is invalid.\n", NISSY_ERROR_INVALID_TRANS
+ );
+ return NISSY_OK;
+ case NISSY_ERROR_INVALID_FORMAT:
+ write(
+ "The value %" PRId64 " means that the given format is not "
+ "known.\n", NISSY_ERROR_INVALID_FORMAT
+ );
+ return NISSY_OK;
+ case NISSY_ERROR_INVALID_SOLVER:
+ write(
+ "The value %" PRId64 " means that the given solver is not "
+ "known.\n", NISSY_ERROR_INVALID_SOLVER
+ );
+ return NISSY_OK;
+ case NISSY_ERROR_NULL_POINTER:
+ write(
+ "The value %" PRId64 " means that one of the provided "
+ "pointer arguments is NULL. For example, it may be "
+ "returned by solve when called with a solver that "
+ "requires some pre-computed data, but the provided data "
+ "is NULL.\n", NISSY_ERROR_NULL_POINTER
+ );
+ return NISSY_OK;
+ case NISSY_ERROR_DATA:
+ write(
+ "The value %" PRId64 " means that the provided data is "
+ "invalid. For example, it may be returned by solve when "
+ "called with incompatible solver and data arguments.\n",
+ NISSY_ERROR_DATA
+ );
+ return NISSY_OK;
+ case NISSY_ERROR_OPTIONS:
+ write(
+ "The value %" PRId64 " means that one or more of the "
+ "given options are invalid. For example, it may be "
+ "returned by solve when called with a negative maximum "
+ "number of solutions.\n", NISSY_ERROR_OPTIONS
+ );
+ return NISSY_OK;
+ case NISSY_ERROR_INVALID_CODE:
+ write(
+ "The value %" PRId64 " means that the given error code "
+ "is not known. It may be returned by explainerror.\n",
+ NISSY_ERROR_INVALID_CODE
+ );
+ return NISSY_OK;
+ case NISSY_ERROR_UNKNOWN:
+ write(
+ "The value %" PRId64 " denotes an unexpected error. It "
+ "probably means that there some bug in this library.\n"
+ "If you can, report any error of this kind to "
+ "sebastiano@tronto.net. Thanks!\n", NISSY_ERROR_UNKNOWN
+ );
+ return NISSY_OK;
+ default:
+ break;
+ }
+
+ if (error_code > 0) {
+ write(
+ "A positive return values does not denote an error\n"
+ "If returned by gendata or datasize, it denotes the size "
+ "of the data, in bytes\n"
+ "If returned by solve, it denotes the number of solutions "
+ "found.\n"
+ );
+ return NISSY_OK;
+ } else {
+ write("Unknown error code %" PRId64 "\n", error_code);
+ return NISSY_ERROR_INVALID_CODE;
+ }
}
diff --git a/src/nissy.h b/src/nissy.h
@@ -8,10 +8,9 @@ If you include this file, you should also use the following includes:
#include <stdbool>
#include <string>
-All the functions below return 0 in case of success and a positive number
-in case of error, unless otherwise specified. Errors are checked in code
-order: for example if error code 1 is returned then it could that also
-an error with code 2 or higher occurred.
+All the functions return 0 or a positive integer in case of success and
+a negative integer in case of error, unless otherwise specified.
+You can see the list of error codes below, or use nissy_explainerror().
Arguments of type char [static 22] denote a cube in B32 format.
Other available formats are H48 and SRC. See README.md for more info on
@@ -25,14 +24,48 @@ A transformation must be given in the format
for example 'rotation UF' or 'mirrored BL'.
*/
+/* Error codes */
+#define NISSY_OK INT64_C(0)
+#define NISSY_WARNING_UNSOLVABLE INT64_C(-1)
+#define NISSY_WARNING_NULL_CALLBACK INT64_C(-2)
+#define NISSY_ERROR_INVALID_CUBE INT64_C(-10)
+#define NISSY_ERROR_UNSOLVABLE_CUBE INT64_C(-11)
+#define NISSY_ERROR_INVALID_MOVES INT64_C(-20)
+#define NISSY_ERROR_INVALID_TRANS INT64_C(-30)
+#define NISSY_ERROR_INVALID_FORMAT INT64_C(-40)
+#define NISSY_ERROR_INVALID_SOLVER INT64_C(-50)
+#define NISSY_ERROR_NULL_POINTER INT64_C(-60)
+#define NISSY_ERROR_DATA INT64_C(-70)
+#define NISSY_ERROR_OPTIONS INT64_C(-80)
+#define NISSY_ERROR_INVALID_CODE INT64_C(-90)
+#define NISSY_ERROR_UNKNOWN INT64_C(-999)
+
+/* Flags for NISS options */
+#define NISSY_NISSFLAG_NORMAL UINT8_C(1)
+#define NISSY_NISSFLAG_INVERSE UINT8_C(2)
+#define NISSY_NISSFLAG_MIXED UINT8_C(4)
+#define NISSY_NISSFLAG_LINEAR \
+ (NISSY_NISSFLAG_NORMAL | NISSY_NISSFLAG_INVERSE)
+#define NISSY_NISSFLAG_ALL \
+ (NISSY_NISSFLAG_NORMAL | NISSY_NISSFLAG_INVERSE | NISSY_NISSFLAG_MIXED)
+
/*
Apply the secod argument as a permutation on the first argument.
+Parameters:
+ cube - The first cube, in B32 format.
+ permutation - The second cube, in B32 format. This cube is treated as a
+ permutation and "applied" to the first cube.
+ result - The return parameter for the resulting cube, in B32 format.
+
Return values:
- 0 Valid result
- 1 The given cube is invalid
- 2 The given permutation is invalid
- 9 The resulting cube is not solvable
+ NISSY_OK - The cubes were composed succesfully.
+ NISSY_WARNING_UNSOLVABLE - The resulting cube is not solvable. This is
+ either because at least on of the given cubes
+ was not solvable, or due to an unknown internal
+ error.
+ NISSY_ERROR_INVALID_CUBE - At least one of the given cubes is invalid.
+ NISSY_ERROR_UNKNOWN - An unknown error occurred.
*/
int64_t nissy_compose(
const char cube[static 22],
@@ -43,10 +76,17 @@ int64_t nissy_compose(
/*
Compute the inverse of the given cube.
+Parameters:
+ cube - The cube to be inverted, in B32 format.
+ result - The return parameter for the resulting cube, in B32 format.
+
Return values:
- 0 Valid result
- 1 The given cube is invalid
- 9 The resulting cube is not solvable
+ NISSY_OK - The cube was inverted succesfully.
+ NISSY_WARNING_UNSOLVABLE - The resulting cube is not solvable. This is
+ either because the given cube was not solvable,
+ or due to an unknown internal error.
+ NISSY_ERROR_INVALID_CUBE - The given cube is invalid.
+ NISSY_ERROR_UNKNOWN - An unknown error occurred.
*/
int64_t nissy_inverse(
const char cube[static 22],
@@ -56,11 +96,18 @@ int64_t nissy_inverse(
/*
Apply the given sequence of moves on the given cube.
+Parameters:
+ cube - The cube to move, in B32 format.
+ moves - The moves to apply to the cube.
+ result - The return parameter for the resulting cube, in B32 format.
+
Return values:
- 0 Valid result
- 1 The given cube is invalid
- 8 The given moves are invalid
- 9 The resulting cube is not solvable
+ NISSY_OK - The moves were applied succesfully.
+ NISSY_WARNING_UNSOLVABLE - The resulting cube is not solvable. This is
+ either because the given cube was not solvable,
+ or due to an unknown internal error.
+ NISSY_ERROR_INVALID_CUBE - The given cube is invalid.
+ NISSY_ERROR_INVALID_MOVES - The given moves are invalid.
*/
int64_t nissy_applymoves(
const char cube[static 22],
@@ -71,11 +118,17 @@ int64_t nissy_applymoves(
/*
Apply the single given transformation to the given cube.
+Parameters:
+ cube - The cube to be transformed, in B32 format.
+ transformation - The transformation in (rotation|mirrored) xy format.
+ result - The return parameter for the resulting cube, in B32 format.
+
Return values:
- 0 Valid result
- 1 The given cube is invalid
- 8 The given transformation is invalid
- 9 The resulting cube is not solvable
+ NISSY_OK - The transformation was performed succesfully.
+ NISSY_WARNING_UNSOLVABLE - The resulting cube is not solvable. This is
+ probably due to an unknown internal error.
+ NISSY_ERROR_INVALID_CUBE - The given cube is invalid.
+ NISSY_ERROR_INVALID_TRANS - The given transformation is invalid.
*/
int64_t nissy_applytrans(
const char cube[static 22],
@@ -86,9 +139,15 @@ int64_t nissy_applytrans(
/*
Apply the given moves to the solved cube.
+Parameters:
+ moves - The moves to be applied to the solved cube.
+ result - Return parameter for the resulting cube, in B32 format.
+
Return values:
- 0 Valid result
- 1 The given moves are invalid
+ NISSY_OK - The moves were performed succesfully.
+ NISSY_WARNING_UNSOLVABLE - The resulting cube is not solvable. This is
+ probably due to an unknown internal error.
+ NISSY_ERROR_INVALID_MOVES - The given moves are invalid.
*/
int64_t nissy_frommoves(
const char *moves,
@@ -98,20 +157,45 @@ int64_t nissy_frommoves(
/*
Convert the given cube between the two given formats.
+Parameters:
+ format_in - The input format.
+ format_out - The output format.
+ string - The cube, in format_in format.
+ result - Return parameter for the cube in format_out format. Must be
+ large enough to contains the cube in this format.
+
Return values:
- 0 Valid result
- 1 The given cube or format_in is invalid
- 2 The resulting cube or format_out is invalid
- 3 The resulting cube is inconsistent
+ NISSY_OK - The conversion was performed succesfully.
+ NISSY_ERROR_INVALID_CUBE - The given cube is invalid.
+ NISSY_ERROR_INVALID_FORMAT - At least one of the given formats is invalid.
+ NISSY_ERROR_UNKNOWN - An unknown error occurred.
*/
int64_t nissy_convert(
const char *format_in,
const char *format_out,
- const char *cube_string,
+ const char *cube,
char *result
);
-/* Get the cube with the given ep, eo, cp and co values. */
+/*
+Get the cube with the given ep, eo, cp and co values. The values must be in the
+ranges specified below, but if the option "fix" is given any values outside its
+range will be adjusted before using it. The option "fix" also fixes parity and
+orientation issues, resulting always in a solvable cube.
+
+Parameters:
+ ep - The edge permutation, 0 <= ep <= 479001600 (12!)
+ eo - The edge orientation, 0 <= eo <= 2047 (2^11)
+ cp - The corner permutation, 0 <= cp <= 40320 (8!)
+ co - The corner orientation, 0 <= co <= 2187 (3^7)
+ options - Other options.
+ result - The return parameter for the resulting cube, in B32 format.
+
+Return values:
+ NISSY_OK - The cube was generated succesfully.
+ NISSY_WARNING_UNSOLVABLE - The resulting cube is unsolvable.
+ NISSY_ERROR_OPTIONS - One or more of the given parameters is invalid.
+*/
int64_t nissy_getcube(
int64_t ep,
int64_t eo,
@@ -125,9 +209,13 @@ int64_t nissy_getcube(
Compute the size of the data generated by nissy_gendata, when called with
the same parameters, or -1 in case of error.
+Parameters:
+ solver - The name of the solver.
+
Return values:
- -1 Error
- >=0 The size of the table, in bytes
+ NISSY_ERROR_INVALID_SOLVER - The given solver is not known.
+ NISSY_ERROR_UNKNOWN - An unknown error occurred.
+ Any value >= 0 - The size of the data, in bytes.
*/
int64_t nissy_datasize(
const char *solver
@@ -136,38 +224,71 @@ int64_t nissy_datasize(
/*
Compute the data for the given solver and store it in generated_data.
+Parameters:
+ solver - The name of the solver.
+ data - The return parameter for the generated data. Must be large enoguh
+ to contain the whole data. It is advised to use nissy_datasize to
+ check how much memory is needed.
+
Return values:
- -1 Error
- >=0 The size of the table, in bytes
+ NISSY_ERROR_INVALID_SOLVER - The given solver is not known.
+ NISSY_ERROR_UNKNOWN - An error occurred while generating the data.
+ Any value >= 0 - The size of the data, in bytes.
*/
int64_t nissy_gendata(
const char *solver,
- void *generated_data
+ void *data
);
/*
Print information on a data table via the provided callback writer.
+Parameters:
+ data - The data
+ write - A callback writer with the same signature as printf(3).
+
Return values:
- 0 No error
- 1 The given data could not be read correctly
+ NISSY_OK - The data is correct.
+ NISSY_ERROR_DATA - The data contains errors.
*/
int64_t nissy_datainfo(
- const void *table,
+ const void *data,
void (*write)(const char *, ...)
);
/*
-Solve the given cube using the given solver and options
+Solve the given cube using the given solver and options.
+
+Parameters:
+ cube - The cube to solver, in B32 format.
+ solver - The name of the solver.
+ nissflag - The flags for NISS (linear, inverse, mixed, or combinations).
+ minmoves - The minimum number of moves for a solution.
+ maxmoves - The maximum number of moves for a solution.
+ maxsolutions - The maximum number of solutions.
+ optimal - If set to a non-negative value, the maximum number of moves
+ above the optimal solution length.
+ data - The data for the solver. Can be computed with gendata.
+ solutions - The return parameter for the solutions. Must be large enough
+ to store all found solutions. The solutions are separated by
+ a '\n' (newline) and a '\0' (NULL character) terminates the
+ list.
+ TODO: replace with callback writer.
Return values:
- -1 Error
- >=0 The number of solutions found
+ NISSY_OK - Cube solved succesfully.
+ NISSY_ERROR_INVALID_CUBE - The given cube is invalid.
+ NISSY_ERROR_UNSOLVABLE_CUBE - The given cube is valid, but not solvable with
+ the given solver.
+ NISSY_ERROR_OPTIONS - One or more of the given options are invalid.
+ NISSY_ERROR_NULL_POINTER - One of the provided pointers is null.
+ NISSY_ERROR_INVALID_SOLVER - The given solver is not known.
+ Any value >= 0 - The number of solutions found.
*/
int64_t nissy_solve(
const char cube[static 22],
const char *solver,
- const char *nisstype, /* TODO: remove, use flags */
+ uint8_t nissflag,
int8_t minmoves,
int8_t maxmoves,
int64_t maxsolutions,
@@ -178,5 +299,33 @@ int64_t nissy_solve(
/*
Set a global logger function used by this library.
+
+Parameters:
+ write - A callback writer with the same signature as printf(3).
+
+Return values:
+ NISSY_OK - Logger set succesfully.
+ NISSY_WARNING_NULL_CALLBACK - The provided callback writer is NULL.
*/
-void nissy_setlogger(void (*logger_function)(const char *, ...));
+int64_t nissy_setlogger(
+ void (*logger_function)(const char *, ...)
+);
+
+/*
+Print an explanation of the given error code via the provided callback writer.
+
+Parameters:
+ error_code - The error code to be explained. It can be any value returned
+ by a function in this library, not necessarily an error.
+ write - A callback writer with the same signature as printf(3).
+ Must be non-NULL.
+
+Return values:
+ NISSY_OK - The error code is known.
+ NISSY_WARNING_NULL_CALLBACK - The provided callback writer is NULL.
+ NISSY_ERROR_INVALID_CODE - The error code is unknown.
+*/
+int64_t nissy_explainerror(
+ int64_t error_code,
+ void (*write)(const char *, ...)
+);