src/chess/pgn.c

Wed, 02 Sep 2026 17:11:56 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 02 Sep 2026 17:11:56 +0200
changeset 209
dc4f34426c66
parent 194
619f07c95894
permissions
-rw-r--r--

improve error reporting in PGN parser - resolves #958

50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1 /*
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
3 *
55
54ea19938d57 updated copyright and version info
Mike Becker <universe@uap-core.de>
parents: 54
diff changeset
4 * Copyright 2016 Mike Becker. All rights reserved.
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
5 *
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
8 *
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
11 *
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
15 *
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
27 *
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
28 */
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
29
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
30 #include "pgn.h"
107
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
31
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
32 #include <stdlib.h>
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
33 #include <ctype.h>
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
34 #include <string.h>
120
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
35 #include <sys/time.h>
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
36 #include <time.h>
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
37
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
38 static const char* pgn_error_strings[] = {
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
39 "No Error.",
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
40 "Tag values must be enclosed in double-quotes.",
70
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
41 "Missing closing brace '}' for comment.",
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
42 "Tags must be enclosed in square brackets: '[Key \"Value\"]'.",
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
43 "Move numbers must be terminated with a dot (e.g. '13.' - not '13').",
126
d58b2abdd330 fix wrong game state when the waiting player resigns
Mike Becker <universe@uap-core.de>
parents: 121
diff changeset
44 "Result syntax is incorrect. Expected 1-0, 0-1, 1/2-1/2, or *.",
145
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
45 "Result at end of move text does not match result in tag roster.",
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
46 "Unexpected end of data.",
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
47 "Invalid move.",
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
48 };
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
49
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
50 const char* pgn_error_str(int code) {
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
51 return pgn_error_strings[code];
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
52 }
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
53
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
54 static const char *pgn_game_result(const GameState *gamestate) {
173
e541b6002933 implement first naive draw by threefold repetition
Mike Becker <universe@uap-core.de>
parents: 163
diff changeset
55 if (is_game_drawn(gamestate)) {
145
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
56 return "1/2-1/2";
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
57 } else if (gamestate->wresign) {
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
58 return "0-1";
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
59 } else if (gamestate->bresign) {
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
60 return "1-0";
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
61 } else if (gamestate->checkmate) {
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
62 if (current_color(gamestate) == BLACK) {
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
63 return "1-0";
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
64 } else {
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
65 return "0-1";
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
66 }
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
67 } else {
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
68 return "*";
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
69 }
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
70 }
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
71
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
72 static pgn_result create_pgn_result(
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
73 const char *datastart, const char *datacur,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
74 enum pgn_error_code code, unsigned move_half_number) {
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
75 return (pgn_result) {
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
76 .position = (size_t)(datacur - datastart),
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
77 .code = code,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
78 .move_half_number = move_half_number
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
79 };
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
80 }
150
7d57a252948e fix regression: position reporting about PGN errors
Mike Becker <universe@uap-core.de>
parents: 149
diff changeset
81
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
82 static pgn_result create_pgn_move_error(
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
83 const char *datastart, const char *datacur,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
84 int move_error_code, unsigned move_half_number) {
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
85 return (pgn_result) {
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
86 .position = (size_t)(datacur - datastart),
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
87 .code = pgn_error_move,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
88 .move_error = move_error_code,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
89 .move_half_number = move_half_number
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
90 };
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
91 }
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
92
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
93 pgn_result parse_pgn(const char *pgndata, GameState *gamestate) {
150
7d57a252948e fix regression: position reporting about PGN errors
Mike Becker <universe@uap-core.de>
parents: 149
diff changeset
94 const char * const pgndata0 = pgndata;
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
95 int i;
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
96 char c;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
97
145
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
98 char result[8] = {0};
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
99
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
100 char tagkey[32];
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
101 char tagvalue[128];
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
102
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
103 /* read tag pairs */
82
e75865d90111 remove unnecessary loop variable
Mike Becker <universe@uap-core.de>
parents: 81
diff changeset
104 while (true) {
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
105 while (isspace(c = *(pgndata++)));
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
106 if (c == '1') {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
107 break;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
108 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
109 if (c != '[') {
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
110 return create_pgn_result(pgndata0, pgndata,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
111 pgn_error_missing_bracket, 0);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
112 }
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
113 while (isspace(c = *(pgndata++)));
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
114 i = 0;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
115 do {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
116 tagkey[i++] = c;
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
117 } while (!isspace(c = *(pgndata++)));
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
118 tagkey[i] = '\0';
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
119 while (isspace(c = *(pgndata++)));
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
120 if (c != '"') {
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
121 return create_pgn_result(pgndata0, pgndata,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
122 pgn_error_missing_quote, 0);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
123 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
124 i = 0;
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
125 while ((c = *(pgndata++)) != '"') {
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
126 if (c == '\n' || c == 0) {
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
127 return create_pgn_result(pgndata0, pgndata,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
128 pgn_error_missing_quote, 0);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
129 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
130 tagvalue[i++] = c;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
131 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
132 tagvalue[i] = '\0';
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
133 if (*(pgndata++) != ']') {
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
134 return create_pgn_result(pgndata0, pgndata,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
135 pgn_error_missing_bracket, 0);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
136 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
137
126
d58b2abdd330 fix wrong game state when the waiting player resigns
Mike Becker <universe@uap-core.de>
parents: 121
diff changeset
138 // TODO: read clock info
145
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
139
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
140 if (strcmp("Result", tagkey) == 0) {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
141 memcpy(result, tagvalue, 8);
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
142 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
143 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
144
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
145 /* read moves */
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
146 if (*(pgndata++) != '.') {
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
147 return create_pgn_result(pgndata0, pgndata,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
148 pgn_error_missing_dot, 1);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
149 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
150
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
151 char movestr[10];
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
152 Move move;
194
619f07c95894 rename Row to Rank
Mike Becker <universe@uap-core.de>
parents: 193
diff changeset
153 Color curcol = WHITE;
145
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
154 bool movetext_ends_with_result = false;
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
155 unsigned move_half_number = 1;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
156
82
e75865d90111 remove unnecessary loop variable
Mike Becker <universe@uap-core.de>
parents: 81
diff changeset
157 while (true) {
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
158 /* move */
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
159 while (isspace(c = *(pgndata++)));
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
160 i = 0;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
161 do {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
162 movestr[i++] = c;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
163 if (i >= 10) {
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
164 return create_pgn_move_error(pgndata0, pgndata,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
165 INVALID_MOVE_SYNTAX, move_half_number);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
166 }
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
167 } while (!isspace(c = *(pgndata++)));
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
168 movestr[i] = '\0';
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
169 int move_result = eval_move_strict(gamestate, movestr, curcol, &move);
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
170 if (!move_result) {
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
171 move_result = validate_move(gamestate, &move);
146
942a0cef9ff5 fix fucked up indentation
Mike Becker <universe@uap-core.de>
parents: 145
diff changeset
172 }
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
173 if (move_result) {
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
174 return create_pgn_move_error(pgndata0, pgndata,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
175 move_result, move_half_number);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
176 }
186
8230904458a7 fix regression in network play: we have to transmit capture/check(mate) flags
Mike Becker <universe@uap-core.de>
parents: 182
diff changeset
177 format_move(gamestate, &move);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
178 apply_move(gamestate, &move);
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
179
70
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
180 /* skip spaces */
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
181 while (isspace(c = *(pgndata++)));
70
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
182
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
183 /* parse possible comment */
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
184 if (c == '{') {
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
185 // TODO: interpret comment (may contain clock info)
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
186 do {
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
187 c = *(pgndata++);
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
188 } while (c != '}' && c != 0);
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
189 if (c == 0) {
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
190 return create_pgn_result(pgndata0, pgndata,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
191 pgn_error_missing_brace, move_half_number);
70
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
192 }
88
e4a648fe6ce7 fix PGN parser
Mike Becker <universe@uap-core.de>
parents: 82
diff changeset
193 /* skip spaces */
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
194 while (isspace(c = *(pgndata++)));
70
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
195 }
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
196
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
197 /* end of game data encountered */
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
198 if (c == 0) {
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
199 break;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
200 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
201 if (c == '1' || c == '0') {
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
202 c = *(pgndata++);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
203 if (c == '-') {
126
d58b2abdd330 fix wrong game state when the waiting player resigns
Mike Becker <universe@uap-core.de>
parents: 121
diff changeset
204 if (!gamestate->checkmate) {
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
205 c = *(pgndata++);
126
d58b2abdd330 fix wrong game state when the waiting player resigns
Mike Becker <universe@uap-core.de>
parents: 121
diff changeset
206 if (c == '1') {
d58b2abdd330 fix wrong game state when the waiting player resigns
Mike Becker <universe@uap-core.de>
parents: 121
diff changeset
207 gamestate->wresign = true;
d58b2abdd330 fix wrong game state when the waiting player resigns
Mike Becker <universe@uap-core.de>
parents: 121
diff changeset
208 } else if (c == '0') {
d58b2abdd330 fix wrong game state when the waiting player resigns
Mike Becker <universe@uap-core.de>
parents: 121
diff changeset
209 gamestate->bresign = true;
d58b2abdd330 fix wrong game state when the waiting player resigns
Mike Becker <universe@uap-core.de>
parents: 121
diff changeset
210 } else {
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
211 return create_pgn_result(pgndata0, pgndata,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
212 pgn_error_result_syntax, 0);
126
d58b2abdd330 fix wrong game state when the waiting player resigns
Mike Becker <universe@uap-core.de>
parents: 121
diff changeset
213 }
d58b2abdd330 fix wrong game state when the waiting player resigns
Mike Becker <universe@uap-core.de>
parents: 121
diff changeset
214 }
145
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
215 movetext_ends_with_result = true;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
216 break;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
217 } else if (c == '/') {
173
e541b6002933 implement first naive draw by threefold repetition
Mike Becker <universe@uap-core.de>
parents: 163
diff changeset
218 /* only set remis flag if the game was not drawn otherwise */
e541b6002933 implement first naive draw by threefold repetition
Mike Becker <universe@uap-core.de>
parents: 163
diff changeset
219 gamestate->remis = !is_game_drawn(gamestate);
145
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
220 movetext_ends_with_result = true;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
221 break;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
222 } else {
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
223 /* oops, it was a move number, go back! */
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
224 pgndata--;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
225 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
226 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
227
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
228 /* we have eaten the next valuable byte, so go back */
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
229 pgndata--;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
230
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
231 /* skip move number after black move */
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
232 if (curcol == BLACK) {
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
233 while (isdigit(c = *(pgndata++)));
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
234 if (c != '.') {
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
235 return create_pgn_result(pgndata0, pgndata,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
236 pgn_error_missing_dot, move_half_number + 1);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
237 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
238 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
239 curcol = opponent_color(curcol);
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
240 move_half_number++;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
241 }
145
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
242
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
243 /* sanity check result - if it was specified */
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
244 if (movetext_ends_with_result && result[0]) {
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
245 if (strncmp(result, pgn_game_result(gamestate), 8) != 0) {
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
246 return create_pgn_result(pgndata0, pgndata,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
247 pgn_error_result_mismatch, 0);
145
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
248 }
21b76056a178 add sanity check for result in PGN move text
Mike Becker <universe@uap-core.de>
parents: 143
diff changeset
249 }
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
250
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
251 return create_pgn_result(pgndata0, pgndata, pgn_no_error, 0);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
252 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
253
150
7d57a252948e fix regression: position reporting about PGN errors
Mike Becker <universe@uap-core.de>
parents: 149
diff changeset
254 #undef return
7d57a252948e fix regression: position reporting about PGN errors
Mike Becker <universe@uap-core.de>
parents: 149
diff changeset
255
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
256 pgn_result read_pgn(FILE *stream, GameState *gamestate) {
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
257 fseek(stream, 0, SEEK_END);
193
d1420f5c5704 increase type safety + add backwards compatibility including C99
Mike Becker <universe@uap-core.de>
parents: 186
diff changeset
258 size_t size = ftell(stream);
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
259 fseek(stream, 0, SEEK_SET);
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
260 char *data = malloc(size + 1);
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
261 memset(data, 0, size + 1);
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
262 size_t read = 0;
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
263 do {
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
264 size_t r = fread(data + read, 1, size - read, stream);
150
7d57a252948e fix regression: position reporting about PGN errors
Mike Becker <universe@uap-core.de>
parents: 149
diff changeset
265 if (r == 0) {
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
266 return (pgn_result) {
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
267 .position = read,
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
268 .code = pgn_error_unexpected_eof
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
269 };
150
7d57a252948e fix regression: position reporting about PGN errors
Mike Becker <universe@uap-core.de>
parents: 149
diff changeset
270 }
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
271 read += r;
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
272 } while (read < size);
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
273 pgn_result result = parse_pgn(data, gamestate);
143
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
274 free(data);
e9159c70ff9e improve implementation of read_pgn() and parse_pgn()
Mike Becker <universe@uap-core.de>
parents: 142
diff changeset
275 return result;
140
e92ffe046659 add parse_pgn function which can later be used for automated testing
Mike Becker <universe@uap-core.de>
parents: 133
diff changeset
276 }
e92ffe046659 add parse_pgn function which can later be used for automated testing
Mike Becker <universe@uap-core.de>
parents: 133
diff changeset
277
107
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
278 static void pgn_insert_newlines(char *block) {
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
279 size_t pos = 0;
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
280 size_t last_space_pos = 0;
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
281 size_t line_len = 0;
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
282 while (block[pos] != '\0') {
118
0f2ffbc408ce prettier line breaking in exported PGNs
Mike Becker <universe@uap-core.de>
parents: 117
diff changeset
283 if (block[pos] == 0x1f) {
0f2ffbc408ce prettier line breaking in exported PGNs
Mike Becker <universe@uap-core.de>
parents: 117
diff changeset
284 block[pos++] = ' ';
0f2ffbc408ce prettier line breaking in exported PGNs
Mike Becker <universe@uap-core.de>
parents: 117
diff changeset
285 continue;
0f2ffbc408ce prettier line breaking in exported PGNs
Mike Becker <universe@uap-core.de>
parents: 117
diff changeset
286 }
107
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
287 if (block[pos] == ' ') {
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
288 last_space_pos = pos;
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
289 }
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
290 line_len++;
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
291 if (line_len > 80) {
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
292 block[last_space_pos] = '\n';
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
293 line_len = pos - last_space_pos;
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
294 }
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
295 pos++;
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
296 }
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
297 }
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
298
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
299 static const char *pgn_date(const GameState *gamestate) {
120
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
300 static char date[16];
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
301 time_t dateseconds;
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
302 if (gamestate->movecount == 0) {
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
303 struct timeval curtimestamp;
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
304 gettimeofday(&curtimestamp, NULL);
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
305 dateseconds = curtimestamp.tv_sec;
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
306 } else {
181
8bda076d0a16 simplify how the elapsed move time is recorded
Mike Becker <universe@uap-core.de>
parents: 178
diff changeset
307 dateseconds = (time_t) gamestate->moves[0].timestamp.sec;
120
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
308 }
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
309 struct tm *tm = gmtime(&dateseconds);
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
310 if (tm == NULL) {
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
311 /* fallback - should never happen in reality */
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
312 strncpy(date, "????.??.??", sizeof(date));
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
313 } else {
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
314 int year = tm->tm_year + 1900;
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
315 int month = tm->tm_mon + 1;
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
316 int day = tm->tm_mday;
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
317 #ifdef __GNUC__
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
318 /* this is required to tell GCC that it does not need to warn
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
319 * about the small buffer size of the date string.
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
320 */
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
321 if (year < 1900 || year > 9999) __builtin_unreachable();
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
322 if (month < 1 || month > 12) __builtin_unreachable();
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
323 if (day < 1 || day > 31) __builtin_unreachable();
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
324 #endif
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
325 snprintf(date, sizeof(date), "%04d.%02d.%02d",
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
326 year, month, day);
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
327 }
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
328 return date;
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
329 }
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
330
194
619f07c95894 rename Row to Rank
Mike Becker <universe@uap-core.de>
parents: 193
diff changeset
331 const char *pgn_player_name(const GameState *gamestate, Color color) {
127
7258a46bf5ae ask for player names during PGN export
Mike Becker <universe@uap-core.de>
parents: 126
diff changeset
332 const char *name = color == WHITE ? gamestate->wname : gamestate->bname;
7258a46bf5ae ask for player names during PGN export
Mike Becker <universe@uap-core.de>
parents: 126
diff changeset
333 return name[0] != '\0' ? name : "Anonymous";
7258a46bf5ae ask for player names during PGN export
Mike Becker <universe@uap-core.de>
parents: 126
diff changeset
334 }
7258a46bf5ae ask for player names during PGN export
Mike Becker <universe@uap-core.de>
parents: 126
diff changeset
335
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
336 int write_pgn(FILE* stream, const GameState *gamestate, bool export_comments) {
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
337 char *pgn = create_pgn(gamestate, export_comments);
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
338 if (pgn == NULL) return 1;
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
339 fputs(pgn, stream);
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
340 free(pgn);
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
341 return 0;
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
342 }
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
343
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
344 char *create_pgn(const GameState *gamestate, bool export_comments) {
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
345 size_t resultcap = 4096;
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
346 char *result = malloc(resultcap);
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
347 if (result == NULL) return NULL;
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
348 char *resp = result;
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
349
120
57577c9af5d3 add remaining missing STR tags to PGN exports
Mike Becker <universe@uap-core.de>
parents: 118
diff changeset
350 /* STR tag pairs */
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
351 resp += sprintf(resp, "[Event \"%s\"]\n", "terminal-chess game");
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
352 resp += sprintf(resp, "[Site \"%s\"]\n", "Somewhere on Earth");
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
353 resp += sprintf(resp, "[Date \"%s\"]\n", pgn_date(gamestate));
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
354 resp += sprintf(resp, "[Round \"%s\"]\n", "-");
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
355 resp += sprintf(resp, "[White \"%s\"]\n", pgn_player_name(gamestate, WHITE));
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
356 resp += sprintf(resp, "[Black \"%s\"]\n", pgn_player_name(gamestate, BLACK));
209
dc4f34426c66 improve error reporting in PGN parser - resolves #958
Mike Becker <universe@uap-core.de>
parents: 194
diff changeset
357 const char *gameresult = pgn_game_result(gamestate);
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
358 resp += sprintf(resp, "[Result \"%s\"]\n\n", gameresult);
126
d58b2abdd330 fix wrong game state when the waiting player resigns
Mike Becker <universe@uap-core.de>
parents: 121
diff changeset
359
d58b2abdd330 fix wrong game state when the waiting player resigns
Mike Becker <universe@uap-core.de>
parents: 121
diff changeset
360 // TODO: add optional clock info
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
361
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
362 /* moves */
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
363 char *moveblk = resp; /* remember where the move block starts */
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
364
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
365 for (unsigned i = 0 ; i < gamestate->movecount ; i++) {
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
366 /* reallocate buffer if needed */
107
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
367 {
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
368 size_t rsize = resp - result;
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
369 if (rsize + 128 > resultcap) {
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
370 resultcap *= 2;
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
371 char *newresult = realloc(result, resultcap);
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
372 if (newresult == NULL) {
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
373 free(result);
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
374 return NULL;
107
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
375 }
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
376 result = newresult;
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
377 resp = result + rsize;
107
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
378 }
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
379 }
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
380
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
381 if (i % 2 == 0) {
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
382 resp += snprintf(resp, 16, "%d.\x1f%s",
107
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
383 1+i/2, gamestate->moves[i].string);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
384 } else {
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
385 resp += snprintf(resp, 16, "%s",
107
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
386 gamestate->moves[i].string);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
387 }
101
d4f19182fdc2 add clock times to PGN output
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
388
117
ee539a9691f0 add prompt whether PGN should be exported with comments
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
389 if (!export_comments) {
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
390 *(resp++) = ' ';
117
ee539a9691f0 add prompt whether PGN should be exported with comments
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
391 continue;
ee539a9691f0 add prompt whether PGN should be exported with comments
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
392 }
ee539a9691f0 add prompt whether PGN should be exported with comments
Mike Becker <universe@uap-core.de>
parents: 107
diff changeset
393
101
d4f19182fdc2 add clock times to PGN output
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
394 /* add clock times when the game was under time control */
130
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 127
diff changeset
395 if (gamestate->info.timecontrol) {
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
396 memcpy(resp, " {[%clk ", 8);
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
397 resp += 8;
101
d4f19182fdc2 add clock times to PGN output
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
398 unsigned clkmv = i + 2; /* time for the next move! */
130
3fc6b1d6cbe9 implement optional delay - resolves #820
Mike Becker <universe@uap-core.de>
parents: 127
diff changeset
399 uint16_t clk = remaining_movetime2(gamestate, clkmv);
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
400 resp += print_clk(clk, resp, true);
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
401 *(resp++) = ']';
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
402 *(resp++) = '}';
106
bdc9528d3e2b add elapsed move time commands to PGN exports
Mike Becker <universe@uap-core.de>
parents: 102
diff changeset
403
bdc9528d3e2b add elapsed move time commands to PGN exports
Mike Becker <universe@uap-core.de>
parents: 102
diff changeset
404 /* elapsed move time */
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
405 memcpy(resp, " {[%emt ", 8);
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
406 resp += 8;
181
8bda076d0a16 simplify how the elapsed move time is recorded
Mike Becker <universe@uap-core.de>
parents: 178
diff changeset
407 uint16_t emt = gamestate->moves[i].movetime / 1000000ull;
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
408 resp += print_clk(emt, resp, true);
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
409 *(resp++) = ']';
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
410 *(resp++) = '}';
101
d4f19182fdc2 add clock times to PGN output
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
411 }
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
412
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
413 *(resp++) = ' ';
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
414 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
415
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
416 if (gameresult[0] != '*') {
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
417 size_t rlen = strlen(gameresult);
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
418 memcpy(resp, gameresult, rlen);
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
419 resp += rlen;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
420 }
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
421 *(resp++) = '\n';
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
422 *resp = 0;
107
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
423
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
424 /* post-process move block and format it nicely */
107
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
425 pgn_insert_newlines(moveblk);
36dd94278142 fix that PGN (with comments) can exceed 80 chars
Mike Becker <universe@uap-core.de>
parents: 106
diff changeset
426
178
724e8acff6f8 add create_pgn() function and use it in test-real-pgn
Mike Becker <universe@uap-core.de>
parents: 175
diff changeset
427 return result;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
428 }

mercurial