src/chess/pgn.c

Thu, 03 Sep 2026 12:13:05 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 03 Sep 2026 12:13:05 +0200
changeset 214
31d73d150c76
parent 209
dc4f34426c66
permissions
-rw-r--r--

make all should really build all (including the tests)

we removed the tests from the all-target initially
because they will cause warnings with compilers not
supporting C23

but we should not care too much about this

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