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);