Tue, 28 Aug 2018 14:37:09 +0200
adds error messages to PGN reader
src/chess/pgn.c | file | annotate | diff | comparison | revisions | |
src/chess/pgn.h | file | annotate | diff | comparison | revisions | |
src/game.c | file | annotate | diff | comparison | revisions | |
src/server.c | file | annotate | diff | comparison | revisions | |
src/terminal-chess.h | file | annotate | diff | comparison | revisions |
--- a/src/chess/pgn.c Tue Aug 28 14:16:30 2018 +0200 +++ b/src/chess/pgn.c Tue Aug 28 14:37:09 2018 +0200 @@ -32,6 +32,27 @@ #include <stdlib.h> #include <string.h> +enum { + pgn_error_missing_quote = 1, + pgn_error_missing_bracket, + pgn_error_missing_dot, + pgn_error_move_syntax, + pgn_error_move_semantics +}; + +static const char* pgn_error_strings[] = { + "No Error.", + "Tag values must be enclosed in double-quotes.", + "Tags must be enclosed in square brackets: '[Key \"Value\"]'.", + "Move numbers must be terminated with a dot (e.g. '13.' - not '13').", + "Move is syntactically incorrect.", + "Move is not valid according to chess rules." +}; + +const char* pgn_error_str(int code) { + return pgn_error_strings[code]; +} + int read_pgn(FILE* stream, GameState *gamestate, GameInfo *gameinfo) { int c, i; @@ -49,7 +70,7 @@ break; } if (c != '[') { - return 1; + return pgn_error_missing_bracket; } while (isspace(c = fgetc(stream))); i = 0; @@ -59,18 +80,18 @@ tagkey[i] = '\0'; while (isspace(c = fgetc(stream))); if (c != '"') { - return 1; + return pgn_error_missing_quote; } i = 0; while ((c = fgetc(stream)) != '"') { - if (c == '\n') { - return 1; + if (c == '\n' || c == EOF) { + return pgn_error_missing_quote; } tagvalue[i++] = c; } tagvalue[i] = '\0'; if (fgetc(stream) != ']') { - return 1; + return pgn_error_missing_bracket; } if (strcmp("Result", tagkey) == 0) { @@ -80,7 +101,7 @@ // read moves if (fgetc(stream) != '.') { - return 1; + return pgn_error_missing_dot; } char movestr[10]; @@ -100,10 +121,10 @@ movestr[i] = '\0'; if (eval_move(gamestate, movestr, &move, curcol) != VALID_MOVE_SYNTAX) { - return 1; + return pgn_error_move_syntax; } if (validate_move(gamestate, &move) != VALID_MOVE_SEMANTICS) { - return 1; + return pgn_error_move_semantics; } apply_move(gamestate, &move); @@ -135,7 +156,7 @@ if (curcol == BLACK) { while (isdigit(c = fgetc(stream))); if (c != '.') { - return 1; + return pgn_error_missing_dot; } } curcol = opponent_color(curcol);
--- a/src/chess/pgn.h Tue Aug 28 14:16:30 2018 +0200 +++ b/src/chess/pgn.h Tue Aug 28 14:37:09 2018 +0200 @@ -42,6 +42,8 @@ size_t write_pgn(FILE* stream, GameState *gamestate, GameInfo *gameinfo); void compute_fen(char *str, GameState *gamestate); +const char* pgn_error_str(int code); + #ifdef __cplusplus } #endif
--- a/src/game.c Tue Aug 28 14:16:30 2018 +0200 +++ b/src/game.c Tue Aug 28 14:37:09 2018 +0200 @@ -498,9 +498,11 @@ FILE *pgnfile = fopen(settings->continuepgn, "r"); if (pgnfile) { int result = read_pgn(pgnfile, &gamestate, &(settings->gameinfo)); + long position = ftell(pgnfile); fclose(pgnfile); if (result) { - addstr("Invalid PGN file content.\n"); + printw("Invalid PGN file content at position %ld:\n%s\n", + position, pgn_error_str(result)); return; } if (!is_game_running(&gamestate)) {
--- a/src/server.c Tue Aug 28 14:16:30 2018 +0200 +++ b/src/server.c Tue Aug 28 14:37:09 2018 +0200 @@ -74,9 +74,11 @@ if (pgnfile) { int result = read_pgn(pgnfile, &continuegame, &(settings->gameinfo)); + long position = ftell(pgnfile); fclose(pgnfile); if (result) { - addstr("Invalid PGN file content.\n"); + printw("Invalid PGN file content at position %ld:\n%s\n", + position, pgn_error_str(result)); return 1; } if (!is_game_running(&continuegame)) {