Fix buffer overrun during loadding opening names
[capablanca.git] / lasker-2.2.3 / src / gamedb_old.c
1 /*
2    Copyright (c) 1993 Richard V. Nash.
3    Copyright (c) 2000 Dan Papasian
4    Copyright (C) Andrew Tridgell 2002
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 #if 0
24 /* One line has everything on it */
25 static int WriteMoves(FILE * fp, struct move_t *m)
26 {
27   unsigned long MoveInfo = (m->color == BLACK);
28   int piece, castle;
29   int useFile = 0, useRank = 0, check = 0;
30   int i;
31
32   castle = (m->moveString[0] == 'o');
33   if (castle)
34     piece = KING;
35   else
36     piece = piecetype(CharToPiece(m->moveString[0]));
37
38   MoveInfo = (MoveInfo <<= 3) | piece;
39   MoveInfo = (MoveInfo <<= 3) | m->fromFile;
40   MoveInfo = (MoveInfo <<= 3) | m->fromRank;
41   MoveInfo = (MoveInfo <<= 3) | m->toFile;
42   MoveInfo = (MoveInfo <<= 3) | m->toRank;
43   MoveInfo = (MoveInfo <<= 3) | (m->pieceCaptured & 7);
44   MoveInfo = (MoveInfo <<= 3) | (m->piecePromotionTo & 7);
45   MoveInfo = (MoveInfo <<= 1) | (m->enPassant != 0);
46
47   /* Are we using from-file or from-rank in algString? */
48   i = strlen(m->algString) - 1;
49   if (m->algString[i] == '+') {
50     check = 1;
51     i--;
52   }
53   if (piece != PAWN && !castle) {
54     i -= 2;
55     if (i < 0)
56       return -1;
57     if (m->algString[i] == 'x')
58       i--;
59     if (i < 0)
60       return -1;
61     if (isdigit(m->algString[i])) {
62       useRank = 2;
63       i--;
64     }
65     if (i < 0)
66       return -1;
67     useFile = (islower(m->algString[i]) ? 4 : 0);
68   }
69   MoveInfo = (MoveInfo << 3) | useFile | useRank | check;
70   fprintf(fp, "%lx %x %x\n", MoveInfo, m->tookTime, m->atTime);
71
72   return 0;
73 }
74 #endif
75
76 static int ReadMove(FILE * fp, struct move_t *m)
77 {
78   char line[MAX_GLINE_SIZE];
79   fgets(line, MAX_GLINE_SIZE - 1, fp);
80   if (sscanf(line, "%d %d %d %d %d %d %d %d %d \"%[^\"]\" \"%[^\"]\" %u %u\n",
81              &m->color, &m->fromFile, &m->fromRank, &m->toFile, &m->toRank,
82      &m->pieceCaptured, &m->piecePromotionTo, &m->enPassant, &m->doublePawn,
83              m->moveString, m->algString, &m->atTime, &m->tookTime) != 13)
84     return -1;
85   return 0;
86 }
87
88 #if 0
89 static void WriteGameState(FILE * fp, struct game_state_t *gs)
90 {
91   int i, j;
92
93   for (i = 0; i < 8; i++)
94     for (j = 0; j < 8; j++) {
95       fprintf(fp, "%c", PieceToChar(gs->board[i][j]));
96     }
97   fprintf(fp, "%d %d %d %d %d %d",
98           gs->wkmoved, gs->wqrmoved, gs->wkrmoved,
99           gs->bkmoved, gs->bqrmoved, gs->bkrmoved);
100   for (i = 0; i < 8; i++)
101     fprintf(fp, " %d %d", gs->ep_possible[0][i], gs->ep_possible[1][i]);
102   fprintf(fp, " %d %d %d\n", gs->lastIrreversable, gs->onMove, gs->moveNum);
103 }
104 #endif
105
106 #if 0
107 static void WriteGameFile(FILE * fp, int g)
108 {
109   int i;
110   struct game *gg = &game_globals.garray[g];
111   struct player *wp = &player_globals.parray[gg->white], *bp = &player_globals.parray[gg->black];
112
113   fprintf(fp, "v %d\n", GAMEFILE_VERSION);
114   fprintf(fp, "%s %s\n", wp->name, bp->name);
115   fprintf(fp, "%d %d\n", gg->white_rating, gg->black_rating);
116   fprintf(fp, "%d %d %d %d\n", gg->wInitTime, gg->wIncrement,
117           gg->bInitTime, gg->bIncrement);
118   fprintf(fp, "%lx\n", gg->timeOfStart);
119   fprintf(fp, "%d %d\n",
120     (net_globals.con[wp->socket]->timeseal ? gg->wRealTime/100 : gg->wTime),
121     (net_globals.con[bp->socket]->timeseal ? gg->bRealTime/100 : gg->bTime));
122   fprintf(fp, "%d %d\n", gg->result, gg->winner);
123   fprintf(fp, "%d %d %d %d\n", gg->private, gg->type,
124           gg->rated, gg->clockStopped);
125   fprintf(fp, "%d\n", gg->numHalfMoves);
126   for (i = 0; i < game_globals.garray[g].numHalfMoves; i++) {
127     WriteMoves(fp, &game_globals.garray[g].moveList[i]);
128   }
129 /* took out the next 3 lines to see if it helps with the crash bug we are
130    having on examine...  fb 2.25.96 */
131 /* The next three lines stop wild games crashing the system - they are vital.
132    I fixed the problem with examine - don't remove these again - DAV */
133   if (strcmp(gg->FENstartPos, INITIAL_FEN) != 0)
134     fprintf (fp, "%s\n",gg->FENstartPos);
135   else
136     fprintf (fp, "d w\n");
137   WriteGameState(fp, &game_globals.garray[g].game_state);
138 }
139 #endif
140
141
142
143 static int ReadGameState(FILE * fp, struct game_state_t *gs, int version)
144 {
145   int i, j;
146   char pieceChar;
147   int wkmoved, wqrmoved, wkrmoved, bkmoved, bqrmoved, bkrmoved;
148
149   if (version == 0) {
150     for (i = 0; i < 8; i++)
151       for (j = 0; j < 8; j++)
152         if (fscanf(fp, "%d ", &gs->board[i][j]) != 1)
153           return -1;
154   } else {
155     for (i = 0; i < 8; i++)
156       for (j = 0; j < 8; j++) {
157         pieceChar = getc(fp);
158         gs->board[i][j] = CharToPiece(pieceChar, NULL);
159       }
160   }
161   if (fscanf(fp, "%d %d %d %d %d %d",
162              &wkmoved, &wqrmoved, &wkrmoved,
163              &bkmoved, &bqrmoved, &bkrmoved) != 6)
164     return -1;
165   gs->wkmoved = wkmoved;
166   gs->wqrmoved = wqrmoved;
167   gs->wkrmoved = wkrmoved;
168   gs->bkmoved = bkmoved;
169   gs->bqrmoved = bqrmoved;
170   gs->bkrmoved = bkrmoved;
171   for (i = 0; i < 8; i++)
172     if (fscanf(fp, " %d %d", &gs->ep_possible[0][i], &gs->ep_possible[1][i]) != 2)
173       return -1;
174   if (fscanf(fp, " %d %d %d\n", &gs->lastIrreversable, &gs->onMove, &gs->moveNum) != 3)
175     return -1;
176   return 0;
177 }
178
179
180 static int got_attr_value(int g, char *attr, char *value, FILE * fp)
181 {
182   int i;
183
184   if (!strcmp(attr, "w_init:")) {
185     game_globals.garray[g].wInitTime = atoi(value);
186   } else if (!strcmp(attr, "w_inc:")) {
187     game_globals.garray[g].wIncrement = atoi(value);
188   } else if (!strcmp(attr, "b_init:")) {
189     game_globals.garray[g].bInitTime = atoi(value);
190   } else if (!strcmp(attr, "b_inc:")) {
191     game_globals.garray[g].bIncrement = atoi(value);
192   } else if (!strcmp(attr, "white_name:")) {
193     strcpy(game_globals.garray[g].white_name, value);
194   } else if (!strcmp(attr, "black_name:")) {
195     strcpy(game_globals.garray[g].black_name, value);
196   } else if (!strcmp(attr, "white_rating:")) {
197     game_globals.garray[g].white_rating = atoi(value);
198   } else if (!strcmp(attr, "black_rating:")) {
199     game_globals.garray[g].black_rating = atoi(value);
200   } else if (!strcmp(attr, "result:")) {
201     game_globals.garray[g].result = atoi(value);
202   } else if (!strcmp(attr, "timestart:")) {
203     game_globals.garray[g].timeOfStart = atoi(value);
204   } else if (!strcmp(attr, "w_time:")) {
205     game_globals.garray[g].wTime = atoi(value);
206   } else if (!strcmp(attr, "b_time:")) {
207     game_globals.garray[g].bTime = atoi(value);
208   } else if (!strcmp(attr, "clockstopped:")) {
209     game_globals.garray[g].clockStopped = atoi(value);
210   } else if (!strcmp(attr, "rated:")) {
211     game_globals.garray[g].rated = atoi(value);
212   } else if (!strcmp(attr, "private:")) {
213     game_globals.garray[g].private = atoi(value);
214   } else if (!strcmp(attr, "type:")) {
215     game_globals.garray[g].type = atoi(value);
216   } else if (!strcmp(attr, "halfmoves:")) {
217     game_globals.garray[g].numHalfMoves = atoi(value);
218     if (game_globals.garray[g].numHalfMoves == 0)
219       return 0;
220     game_globals.garray[g].moveListSize = game_globals.garray[g].numHalfMoves;
221     game_globals.garray[g].moveList = (struct move_t *) malloc(sizeof(struct move_t) * game_globals.garray[g].moveListSize);
222     for (i = 0; i < game_globals.garray[g].numHalfMoves; i++) {
223       if (ReadMove(fp, &game_globals.garray[g].moveList[i])) {
224         d_printf( "CHESSD: Trouble reading moves\n");
225         return -1;
226       }
227     }
228   } else if (!strcmp(attr, "gamestate:")) {     /* Value meaningless */
229     if (game_globals.garray[g].status != GAME_EXAMINE && game_globals.garray[g].status != GAME_SETUP &&
230         ReadGameState(fp, &game_globals.garray[g].game_state, 0)) {
231       d_printf( "CHESSD: Trouble reading game state\n");
232       return -1;
233     }
234   } else {
235     d_printf( "CHESSD: Error bad attribute >%s<\n", attr);
236   }
237   return 0;
238 }
239
240 static void ReadOneV1Move(FILE * fp, struct move_t *m)
241 {
242   int i;
243   char PieceChar;
244   int useFile, useRank, check, piece;
245   unsigned long MoveInfo;
246
247   fscanf(fp, "%lx %x %x", &MoveInfo, &m->tookTime, &m->atTime);
248   check = MoveInfo & 1;
249   useRank = MoveInfo & 2;
250   useFile = MoveInfo & 4;
251   MoveInfo >>= 3;
252   m->enPassant = MoveInfo & 1;  /* may have to negate later. */
253   MoveInfo >>= 1;
254   m->piecePromotionTo = MoveInfo & 7;   /* may have to change color. */
255   MoveInfo >>= 3;
256   m->pieceCaptured = MoveInfo & 7;      /* may have to change color. */
257   MoveInfo >>= 3;
258   m->toRank = MoveInfo & 7;
259   MoveInfo >>= 3;
260   m->toFile = MoveInfo & 7;
261   MoveInfo >>= 3;
262   m->fromRank = MoveInfo & 7;
263   MoveInfo >>= 3;
264   m->fromFile = MoveInfo & 7;
265   MoveInfo >>= 3;
266   piece = MoveInfo & 7;
267
268   m->color = (MoveInfo & 8) ? BLACK : WHITE;
269   if (m->pieceCaptured != NOPIECE) {
270     if (m->color == BLACK)
271       m->pieceCaptured |= WHITE;
272     else
273       m->pieceCaptured |= BLACK;
274   }
275   if (piece == PAWN) {
276     PieceChar = 'P';
277     if ((m->toRank == 3 && m->fromRank == 1)
278         || (m->toRank == 4 && m->fromRank == 6))
279       m->doublePawn = m->toFile;
280     else
281       m->doublePawn = -1;
282     if (m->pieceCaptured)
283       sprintf(m->algString, "%cx%c%d", 'a' + m->fromFile,
284               'a' + m->toFile, m->toRank + 1);
285     else
286       sprintf(m->algString, "%c%d", 'a' + m->toFile, m->toRank + 1);
287     if (m->piecePromotionTo != 0) {
288       if (m->piecePromotionTo == KNIGHT)
289         strcat(m->algString, "=N");
290       else if (m->piecePromotionTo == BISHOP)
291         strcat(m->algString, "=B");
292       else if (m->piecePromotionTo == ROOK)
293         strcat(m->algString, "=R");
294       else if (m->piecePromotionTo == QUEEN)
295         strcat(m->algString, "=Q");
296       m->piecePromotionTo |= m->color;
297     }
298     if (m->enPassant)
299       m->enPassant = m->toFile - m->fromFile;
300   } else {
301     m->doublePawn = -1;
302     PieceChar = PieceToChar(piecetype(piece) | WHITE);
303     if (PieceChar == 'K' && m->fromFile == 4 && m->toFile == 6) {
304       strcpy(m->algString, "O-O");
305       strcpy(m->moveString, "o-o");
306     } else if (PieceChar == 'K' && m->fromFile == 4 && m->toFile == 2) {
307       strcpy(m->algString, "O-O-O");
308       strcpy(m->moveString, "o-o-o");
309     } else {
310       i = 0;
311       m->algString[i++] = PieceChar;
312       if (useFile)
313         m->algString[i++] = 'a' + m->fromFile;
314       if (useRank)
315         m->algString[i++] = '1' + m->fromRank;
316       if (m->pieceCaptured != 0)
317         m->algString[i++] = 'x';
318       m->algString[i++] = 'a' + m->toFile;
319       m->algString[i++] = '1' + m->toRank;
320       m->algString[i] = '\0';
321     }
322     if (m->piecePromotionTo != 0) { // must be Shogi promotion
323         strcat(m->algString, "=+");
324       m->piecePromotionTo |= m->color;
325     }
326   }
327   if (m->algString[0] != 'O')
328     sprintf(m->moveString, "%c/%c%d-%c%d", PieceChar, 'a' + m->fromFile,
329             m->fromRank + 1, 'a' + m->toFile, m->toRank + 1);
330   if (check)
331     strcat(m->algString, "+");
332 }
333
334 static int ReadV1Moves(struct game *g, FILE * fp)
335 {
336   int i;
337
338   g->moveListSize = g->numHalfMoves;
339   g->moveList = (struct move_t *) malloc(sizeof(struct move_t) * g->moveListSize);
340   for (i = 0; i < g->numHalfMoves; i++) {
341     ReadOneV1Move(fp, &g->moveList[i]);
342   }
343   return 0;
344 }
345
346 static int ReadV1GameFmt(struct game *g, FILE * fp, int version)
347 {
348   char* FEN;
349   char tmp[MAX_STRING_LENGTH];
350   unsigned result;
351
352   fscanf(fp, "%s %s", g->white_name, g->black_name);
353   fscanf(fp, "%d %d", &g->white_rating, &g->black_rating);
354   fscanf(fp, "%d %d %d %d", &g->wInitTime, &g->wIncrement,
355          &g->bInitTime, &g->bIncrement);
356   if ((version < 3) && (!(g->bInitTime)))
357     g->bInitTime = g->wInitTime;
358                        /*PRE-V3 assumed bInitTime was 0 if balanced clocks*/
359   fscanf(fp, "%lx", &g->timeOfStart);
360   fscanf(fp, "%d %d", &g->wTime, &g->bTime);
361
362 /* fixing an (apparently) old bug: winner not saved */
363   if (version > 1)
364     fscanf(fp, "%d %d", &result, &g->winner);
365   else
366     fscanf(fp, "%d", &result);
367
368   g->result = (enum gameend)result;
369
370   fscanf(fp, "%d %d %d %d", &g->private, (int *) &g->type,
371          &g->rated, &g->clockStopped);
372   fscanf(fp, "%d", &g->numHalfMoves);
373   ReadV1Moves(g, fp);
374
375   if (version >= 4) {
376     getc(fp);                   /* Skip past a newline. */ 
377
378     fgets(tmp, MAX_LINE_SIZE, fp);
379     tmp [strlen(tmp)-1] = '\0'; /* kill the newline char */
380
381     if ((tmp[0] == '\0') || (!strcmp(tmp,"d w"))) {
382             /* default position */
383             strcpy (g->FENstartPos,INITIAL_FEN);
384     } else {
385       if (!strcmp(tmp,"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR"))
386                  /* missing colour for default pos 1.7.1 bug */
387               strcpy(g->FENstartPos,INITIAL_FEN);
388       else {
389         strcpy (g->FENstartPos,tmp);
390         FEN = g->FENstartPos;
391         while (*(FEN) != '/') { /* check for missing fen pos (1.7.1 bug) */
392           if (*(FEN++) == '\0') {
393             d_printf("Corrupt game %s vs %s!\n",g->white_name,g->black_name);
394             return -1;
395           }
396         }
397       }
398     }
399   } else
400     getc(fp);                   /* Skip past a newline. */
401
402   if (g->status != GAME_EXAMINE && g->status != GAME_SETUP) { 
403     if (ReadGameState(fp, &g->game_state, version)) {
404       d_printf( "CHESSD: Trouble reading game state\n");
405       return -1;
406     }
407   } else if (g->status == GAME_EXAMINE)
408     FEN_to_board(g->FENstartPos, &g->game_state);
409   return 0;
410 }
411
412
413 int ReadGameAttrs_old(FILE * fp, int g,int version)
414 {
415   int len;
416   char *attr, *value;
417   char line[MAX_GLINE_SIZE];
418
419   if (version > 0) {
420     if ((ReadV1GameFmt(&game_globals.garray[g], fp, version)) < 0)
421       return -1;
422   }
423   /* Read the game file here */
424   else
425     do {
426       if ((len = strlen(line)) <= 1) {
427         fgets(line, MAX_GLINE_SIZE - 1, fp);
428         continue;
429       }
430       line[len - 1] = '\0';
431       attr = eatwhite(line);
432       if (attr[0] == '#')
433         continue;               /* Comment */
434       value = eatword(attr);
435       if (!*value) {
436         d_printf( "CHESSD: Error reading file\n");
437         fgets(line, MAX_GLINE_SIZE - 1, fp);
438         continue;
439       }
440       *value = '\0';
441       value++;
442       value = eatwhite(value);
443       if (!*value) {
444         d_printf( "CHESSD: Error reading file\n");
445         fgets(line, MAX_GLINE_SIZE - 1, fp);
446         continue;
447       }
448       stolower(attr);
449       if (got_attr_value(g, attr, value, fp)) {
450         return -1;
451       }
452       fgets(line, MAX_GLINE_SIZE - 1, fp);
453     } while (!feof(fp)); 
454   if (!(game_globals.garray[g].bInitTime))
455      game_globals.garray[g].bInitTime = game_globals.garray[g].wInitTime;
456
457   return 0;
458 }