# HG changeset patch # User Mike Becker # Date 1535459829 -7200 # Node ID 0c50aac49e55be482715179f1232a44253b906b6 # Parent 3fa1de896666308eff8d653633a22299b9f56dc4 adds error messages to PGN reader diff -r 3fa1de896666 -r 0c50aac49e55 src/chess/pgn.c --- 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 #include +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); diff -r 3fa1de896666 -r 0c50aac49e55 src/chess/pgn.h --- 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 diff -r 3fa1de896666 -r 0c50aac49e55 src/game.c --- 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)) { diff -r 3fa1de896666 -r 0c50aac49e55 src/server.c --- 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)) { diff -r 3fa1de896666 -r 0c50aac49e55 src/terminal-chess.h --- a/src/terminal-chess.h Tue Aug 28 14:16:30 2018 +0200 +++ b/src/terminal-chess.h Tue Aug 28 14:37:09 2018 +0200 @@ -36,7 +36,7 @@ #ifndef TERMINAL_CHESS_H #define TERMINAL_CHESS_H -#define PROGRAM_VERSION "0.9-r59" +#define PROGRAM_VERSION "0.9-r60" #ifdef __cplusplus extern "C" {