X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=pgntags.c;h=28e607d7b0a86d24c23acda27f7ab270dc8ae97d;hb=e70077aab0199817f37aef9ed0bdba1bbca93b45;hp=0d4b26f7ca8c3108d839e9e339adecb8d1395aad;hpb=bb1c4f8ed2489e4891fe044532a35107d33174d2;p=xboard.git diff --git a/pgntags.c b/pgntags.c index 0d4b26f..28e607d 100644 --- a/pgntags.c +++ b/pgntags.c @@ -1,7 +1,7 @@ /* * pgntags.c -- Functions to manage PGN tags * - * Copyright 1995,2009 Free Software Foundation, Inc. + * Copyright 1995, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. * * Enhancements Copyright 2005 Alessandro Scotti * @@ -47,9 +47,6 @@ #include "backend.h" #include "parser.h" -static char *PGNTagsStatic P((GameInfo *)); - - /* Parse PGN tags; returns 0 for success or error number */ @@ -107,6 +104,10 @@ int ParsePGNTag(tag, gameInfo) else gameInfo->result = GameUnfinished; success = TRUE; + } else if (StrCaseCmp(name, "TimeControl") == 0) { +// int tc, mps, inc = -1; +// if(sscanf(value, "%d/%d", &mps, &tc) == 2 || ) + success = StrSavePtr(value, &gameInfo->timeControl) != NULL; } else if (StrCaseCmp(name, "FEN") == 0) { success = StrSavePtr(value, &gameInfo->fen) != NULL; } else if (StrCaseCmp(name, "SetUp") == 0) { @@ -140,69 +141,29 @@ int ParsePGNTag(tag, gameInfo) } - -/* Return a static buffer with a game's data. - */ -static char *PGNTagsStatic(gameInfo) - GameInfo *gameInfo; -{ - static char buf[8192]; - char buf1[MSG_SIZ]; - - buf[0] = NULLCHAR; - - sprintf(buf1, "[Event \"%s\"]\n", - gameInfo->event ? gameInfo->event : "?"); - strcat(buf, buf1); - sprintf(buf1, "[Site \"%s\"]\n", - gameInfo->site ? gameInfo->site : "?"); - strcat(buf, buf1); - sprintf(buf1, "[Date \"%s\"]\n", - gameInfo->date ? gameInfo->date : "?"); - strcat(buf, buf1); - sprintf(buf1, "[Round \"%s\"]\n", - gameInfo->round ? gameInfo->round : "-"); - strcat(buf, buf1); - sprintf(buf1, "[White \"%s\"]\n", - gameInfo->white ? gameInfo->white : "?"); - strcat(buf, buf1); - sprintf(buf1, "[Black \"%s\"]\n", - gameInfo->black ? gameInfo->black : "?"); - strcat(buf, buf1); - sprintf(buf1, "[Result \"%s\"]\n", PGNResult(gameInfo->result)); - strcat(buf, buf1); - - if (gameInfo->whiteRating >= 0 ) { - sprintf(buf1, "[WhiteElo \"%d\"]\n", gameInfo->whiteRating ); - strcat(buf, buf1); - } - if ( gameInfo->blackRating >= 0 ) { - sprintf(buf1, "[BlackElo \"%d\"]\n", gameInfo->blackRating ); - strcat(buf, buf1); - } - if (gameInfo->timeControl != NULL) { - sprintf(buf1, "[TimeControl \"%s\"]\n", gameInfo->timeControl); - strcat(buf, buf1); - } - if (gameInfo->variant != VariantNormal) { - sprintf(buf1, "[Variant \"%s\"]\n", VariantName(gameInfo->variant)); - strcat(buf, buf1); - } - if (gameInfo->extraTags != NULL) { - strcat(buf, gameInfo->extraTags); - } - return buf; -} - - - /* Print game info */ void PrintPGNTags(fp, gameInfo) FILE *fp; GameInfo *gameInfo; { - fprintf(fp, "%s", PGNTagsStatic(gameInfo)); + fprintf(fp, "[Event \"%s\"]\n", gameInfo->event ? gameInfo->event : "?"); + fprintf(fp, "[Site \"%s\"]\n", gameInfo->site ? gameInfo->site : "?"); + fprintf(fp, "[Date \"%s\"]\n", gameInfo->date ? gameInfo->date : "?"); + fprintf(fp, "[Round \"%s\"]\n", gameInfo->round ? gameInfo->round : "-"); + fprintf(fp, "[White \"%s\"]\n", gameInfo->white ? gameInfo->white : "?"); + fprintf(fp, "[Black \"%s\"]\n", gameInfo->black ? gameInfo->black : "?"); + fprintf(fp, "[Result \"%s\"]\n", PGNResult(gameInfo->result)); + if (gameInfo->whiteRating >= 0) + fprintf(fp, "[WhiteElo \"%d\"]\n", gameInfo->whiteRating); + if (gameInfo->blackRating >= 0) + fprintf(fp, "[BlackElo \"%d\"]\n", gameInfo->blackRating); + if (gameInfo->timeControl) + fprintf(fp, "[TimeControl \"%s\"]\n", gameInfo->timeControl); + if (gameInfo->variant != VariantNormal) + fprintf(fp, "[Variant \"%s\"]\n", VariantName(gameInfo->variant)); + if (gameInfo->extraTags) + fputs(gameInfo->extraTags, fp); } @@ -211,7 +172,48 @@ void PrintPGNTags(fp, gameInfo) char *PGNTags(gameInfo) GameInfo *gameInfo; { - return StrSave(PGNTagsStatic(gameInfo)); + size_t len; + char *buf; + char *p; + + // First calculate the needed buffer size. + // Then we don't have to check the buffer size later. + len = 12 + 11 + 11 + 12 + 12 + 12 + 25 + 1; // The first 7 tags + if (gameInfo->event) len += strlen(gameInfo->event); + if (gameInfo->site) len += strlen(gameInfo->site); + if (gameInfo->date) len += strlen(gameInfo->date); + if (gameInfo->round) len += strlen(gameInfo->round); + if (gameInfo->white) len += strlen(gameInfo->white); + if (gameInfo->black) len += strlen(gameInfo->black); + if (gameInfo->whiteRating >= 0) len += 40; + if (gameInfo->blackRating >= 0) len += 40; + if (gameInfo->timeControl) len += strlen(gameInfo->timeControl) + 20; + if (gameInfo->variant != VariantNormal) len += 50; + if (gameInfo->extraTags) len += strlen(gameInfo->extraTags); + + buf = malloc(len); + if (!buf) + return 0; + + p = buf; + p += sprintf(p, "[Event \"%s\"]\n", gameInfo->event ? gameInfo->event : "?"); + p += sprintf(p, "[Site \"%s\"]\n", gameInfo->site ? gameInfo->site : "?"); + p += sprintf(p, "[Date \"%s\"]\n", gameInfo->date ? gameInfo->date : "?"); + p += sprintf(p, "[Round \"%s\"]\n", gameInfo->round ? gameInfo->round : "-"); + p += sprintf(p, "[White \"%s\"]\n", gameInfo->white ? gameInfo->white : "?"); + p += sprintf(p, "[Black \"%s\"]\n", gameInfo->black ? gameInfo->black : "?"); + p += sprintf(p, "[Result \"%s\"]\n", PGNResult(gameInfo->result)); + if (gameInfo->whiteRating >= 0) + p += sprintf(p, "[WhiteElo \"%d\"]\n", gameInfo->whiteRating); + if (gameInfo->blackRating >= 0) + p += sprintf(p, "[BlackElo \"%d\"]\n", gameInfo->blackRating); + if (gameInfo->timeControl) + p += sprintf(p, "[TimeControl \"%s\"]\n", gameInfo->timeControl); + if (gameInfo->variant != VariantNormal) + p += sprintf(p, "[Variant \"%s\"]\n", VariantName(gameInfo->variant)); + if (gameInfo->extraTags) + strcpy(p, gameInfo->extraTags); + return buf; } @@ -231,7 +233,7 @@ char *PGNResult(result) case GameIsDrawn: return "1/2-1/2"; } -} +} /* Returns 0 for success, nonzero for error */ int @@ -246,13 +248,13 @@ ReplaceTags(tags, gameInfo) yynewstr(tags); for (;;) { yyboardindex = 0; - moveType = (ChessMove) yylex(); + moveType = (ChessMove) Myylex(); if (moveType == (ChessMove) 0) { break; } else if (moveType == PGNTag) { err = ParsePGNTag(yy_text, gameInfo); if (err != 0) return err; - } + } } /* just one problem...if there is a result in the new tags, * DisplayMove() won't ever show it because ClearGameInfo() set