X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=backend.c;h=c14f438bf1f5ee6157ce72037bf5ecf9ed02fe4e;hb=7223300f42e9b2f70f963c654317b5bdb36e29e0;hp=42d9d197616c0566c7c073f9d9d22ee9984ffe52;hpb=485413c12eae2b04aa319089a276a20155aabcb0;p=xboard.git diff --git a/backend.c b/backend.c index 42d9d19..c14f438 100644 --- a/backend.c +++ b/backend.c @@ -5,7 +5,7 @@ * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc. * * Enhancements Copyright 2005 Alessandro Scotti * @@ -225,6 +225,7 @@ void DisplayTwoMachinesTitle P(()); static void ExcludeClick P((int index)); void ToggleSecond P((void)); void PauseEngine P((ChessProgramState *cps)); +static int NonStandardBoardSize P((void)); #ifdef WIN32 extern void ConsoleCreate(); @@ -328,7 +329,7 @@ safeStrCpy (char *dst, const char *src, size_t count) { dst[ count-1 ] = '\0'; // make sure incomplete copy still null-terminated if(appData.debugMode) - fprintf(debugFP, "safeStrCpy: copying %s into %s didn't work, not enough space %d\n",src,dst, (int)count); + fprintf(debugFP, "safeStrCpy: copying %s into %s didn't work, not enough space %d\n",src,dst, (int)count); } return dst; @@ -780,9 +781,10 @@ InitEngine (ChessProgramState *cps, int n) cps->sendName = appData.icsActive; cps->sdKludge = FALSE; cps->stKludge = FALSE; + if(cps->tidy == NULL) cps->tidy = (char*) malloc(MSG_SIZ); TidyProgramName(cps->program, cps->host, cps->tidy); cps->matchWins = 0; - safeStrCpy(cps->variants, appData.variant, MSG_SIZ); + ASSIGN(cps->variants, appData.variant); cps->analysisSupport = 2; /* detect */ cps->analyzing = FALSE; cps->initDone = FALSE; @@ -807,7 +809,7 @@ InitEngine (ChessProgramState *cps, int n) cps->supportsNPS = UNKNOWN; cps->memSize = FALSE; cps->maxCores = FALSE; - cps->egtFormats[0] = NULLCHAR; + ASSIGN(cps->egtFormats, ""); /* [HGM] options */ cps->optionSettings = appData.engOptions[n]; @@ -1344,7 +1346,11 @@ void InitBackEnd2 () { if (appData.debugMode) { - fprintf(debugFP, "%s\n", programVersion); +# ifdef __GIT_VERSION + fprintf(debugFP, "Version: %s (%s)\n", programVersion, __GIT_VERSION); +# else + fprintf(debugFP, "Version: %s\n", programVersion); +# endif } ASSIGN(currentDebugFile, appData.nameOfDebugFile); // [HGM] debug split: remember initial name in use @@ -2194,7 +2200,7 @@ StringToVariant (char *e) } } if (appData.debugMode) { - fprintf(debugFP, _("recognized '%s' (%d) as variant %s\n"), + fprintf(debugFP, "recognized '%s' (%d) as variant %s\n", e, wnum, VariantName(v)); } return v; @@ -3553,7 +3559,7 @@ read_from_ics (InputSourceRef isr, VOIDSTAR closure, char *data, int count, int gameInfo.whiteRating = string_to_rating(star_match[1]); gameInfo.blackRating = string_to_rating(star_match[3]); if (appData.debugMode) - fprintf(debugFP, _("Ratings from header: W %d, B %d\n"), + fprintf(debugFP, "Ratings from header: W %d, B %d\n", gameInfo.whiteRating, gameInfo.blackRating); } continue; @@ -4211,7 +4217,7 @@ ParseBoard12 (char *string) newGame = FALSE; if (appData.debugMode) - fprintf(debugFP, _("Parsing board: %s\n"), string); + fprintf(debugFP, "Parsing board: %s\n", string); move_str[0] = NULLCHAR; elapsed_time[0] = NULLCHAR; @@ -4320,7 +4326,7 @@ ParseBoard12 (char *string) partnerUp = 0; flipView = !flipView; } // [HGM] dual snprintf(partnerStatus, MSG_SIZ,"W: %d:%02d B: %d:%02d (%d-%d) %c", white_time*fac/60000, (white_time*fac%60000)/1000, (black_time*fac/60000), (black_time*fac%60000)/1000, white_stren, black_stren, to_play); - DisplayMessage(partnerStatus, ""); + if(!twoBoards) DisplayMessage(partnerStatus, ""); partnerBoardValid = TRUE; return; } @@ -4680,11 +4686,10 @@ ParseBoard12 (char *string) to canonical algebraic form. */ if (moveNum > 0) { if (appData.debugMode) { - if (appData.debugMode) { int f = forwardMostMove; - fprintf(debugFP, "parseboard %d, castling = %d %d %d %d %d %d\n", f, - boards[f][CASTLING][0],boards[f][CASTLING][1],boards[f][CASTLING][2], - boards[f][CASTLING][3],boards[f][CASTLING][4],boards[f][CASTLING][5]); - } + int f = forwardMostMove; + fprintf(debugFP, "parseboard %d, castling = %d %d %d %d %d %d\n", f, + boards[f][CASTLING][0],boards[f][CASTLING][1],boards[f][CASTLING][2], + boards[f][CASTLING][3],boards[f][CASTLING][4],boards[f][CASTLING][5]); fprintf(debugFP, "accepted move %s from ICS, parse it.\n", move_str); fprintf(debugFP, "moveNum = %d\n", moveNum); fprintf(debugFP, "board = %d-%d x %d\n", BOARD_LEFT, BOARD_RGHT, BOARD_HEIGHT); @@ -7202,7 +7207,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) } promoDefaultAltered = FALSE; MarkTargetSquares(1); - if(!second || appData.oneClick && !OnlyMove(&x, &y, TRUE)) { + if(!(second && appData.oneClick && OnlyMove(&x, &y, TRUE))) { if (appData.highlightDragging) { SetHighlights(x, y, -1, -1); } else { @@ -7252,6 +7257,7 @@ LeftClick (ClickType clickType, int xPix, int yPix) second = sweepSelecting = 0; fromX = fromY = -1; gatingPiece = EmptySquare; + MarkTargetSquares(1); ClearHighlights(); gotPremove = 0; ClearPremoveHighlights(); @@ -7756,6 +7762,7 @@ Adjudicate (ChessProgramState *cps) case MT_NONE: default: break; + case MT_STEALMATE: case MT_STALEMATE: case MT_STAINMATE: reason = "Xboard adjudication: Stalemate"; @@ -8008,6 +8015,7 @@ SendMoveToBookUser (int moveNr, ChessProgramState *cps, int initial) SendToProgram("force\n", cps); cps->bookSuspend = TRUE; // flag indicating it has to be restarted } + if(bookHit) setboardSpoiledMachineBlack = FALSE; // suppress 'go' in SendMoveToProgram if(!initial) SendMoveToProgram(moveNr, cps); // with hit on initial position there is no move // now arrange restart after book miss if(bookHit) { @@ -8424,12 +8432,14 @@ if(appData.debugMode) fprintf(debugFP, "nodes = %d, %lld\n", (int) programStats. return; // [HGM] This return was missing, causing option features to be recognized as non-compliant commands! } - if ((!appData.testLegality || gameInfo.variant == VariantFairy) && - !strncmp(message, "setup ", 6)) { // [HGM] allow first engine to define opening position + if (!strncmp(message, "setup ", 6) && + (!appData.testLegality || gameInfo.variant == VariantFairy || NonStandardBoardSize()) + ) { // [HGM] allow first engine to define opening position int dummy, s=6; char buf[MSG_SIZ]; if(appData.icsActive || forwardMostMove != 0 || cps != &first) return; if(sscanf(message, "setup (%s", buf) == 1) s = 8 + strlen(buf), buf[s-9] = NULLCHAR, SetCharTable(pieceToChar, buf); if(startedFromSetupPosition) return; + if(sscanf(message+s, "%dx%d+%d", &dummy, &dummy, &dummy) == 3) while(message[s] && message[s++] != ' '); // for compatibility with Alien Edition ParseFEN(boards[0], &dummy, message+s); DrawPosition(TRUE, boards[0]); startedFromSetupPosition = TRUE; @@ -9846,11 +9856,38 @@ SendEgtPath (ChessProgramState *cps) } } +static int +NonStandardBoardSize () +{ + /* [HGM] Awkward testing. Should really be a table */ + int overruled = gameInfo.boardWidth != 8 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 0; + if( gameInfo.variant == VariantXiangqi ) + overruled = gameInfo.boardWidth != 9 || gameInfo.boardHeight != 10 || gameInfo.holdingsSize != 0; + if( gameInfo.variant == VariantShogi ) + overruled = gameInfo.boardWidth != 9 || gameInfo.boardHeight != 9 || gameInfo.holdingsSize != 7; + if( gameInfo.variant == VariantBughouse || gameInfo.variant == VariantCrazyhouse ) + overruled = gameInfo.boardWidth != 8 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 5; + if( gameInfo.variant == VariantCapablanca || gameInfo.variant == VariantCapaRandom || + gameInfo.variant == VariantGothic || gameInfo.variant == VariantFalcon || gameInfo.variant == VariantJanus ) + overruled = gameInfo.boardWidth != 10 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 0; + if( gameInfo.variant == VariantCourier ) + overruled = gameInfo.boardWidth != 12 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 0; + if( gameInfo.variant == VariantSuper ) + overruled = gameInfo.boardWidth != 8 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 8; + if( gameInfo.variant == VariantGreat ) + overruled = gameInfo.boardWidth != 10 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 8; + if( gameInfo.variant == VariantSChess ) + overruled = gameInfo.boardWidth != 8 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 7; + if( gameInfo.variant == VariantGrand ) + overruled = gameInfo.boardWidth != 10 || gameInfo.boardHeight != 10 || gameInfo.holdingsSize != 7; + return overruled; +} + void InitChessProgram (ChessProgramState *cps, int setup) /* setup needed to setup FRC opening position */ { - char buf[MSG_SIZ], b[MSG_SIZ]; int overruled; + char buf[MSG_SIZ], b[MSG_SIZ]; if (appData.noChessProgram) return; hintRequested = FALSE; bookRequested = FALSE; @@ -9882,29 +9919,7 @@ InitChessProgram (ChessProgramState *cps, int setup) return; } - /* [HGM] make prefix for non-standard board size. Awkward testing... */ - overruled = gameInfo.boardWidth != 8 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 0; - if( gameInfo.variant == VariantXiangqi ) - overruled = gameInfo.boardWidth != 9 || gameInfo.boardHeight != 10 || gameInfo.holdingsSize != 0; - if( gameInfo.variant == VariantShogi ) - overruled = gameInfo.boardWidth != 9 || gameInfo.boardHeight != 9 || gameInfo.holdingsSize != 7; - if( gameInfo.variant == VariantBughouse || gameInfo.variant == VariantCrazyhouse ) - overruled = gameInfo.boardWidth != 8 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 5; - if( gameInfo.variant == VariantCapablanca || gameInfo.variant == VariantCapaRandom || - gameInfo.variant == VariantGothic || gameInfo.variant == VariantFalcon || gameInfo.variant == VariantJanus ) - overruled = gameInfo.boardWidth != 10 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 0; - if( gameInfo.variant == VariantCourier ) - overruled = gameInfo.boardWidth != 12 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 0; - if( gameInfo.variant == VariantSuper ) - overruled = gameInfo.boardWidth != 8 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 8; - if( gameInfo.variant == VariantGreat ) - overruled = gameInfo.boardWidth != 10 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 8; - if( gameInfo.variant == VariantSChess ) - overruled = gameInfo.boardWidth != 8 || gameInfo.boardHeight != 8 || gameInfo.holdingsSize != 7; - if( gameInfo.variant == VariantGrand ) - overruled = gameInfo.boardWidth != 10 || gameInfo.boardHeight != 10 || gameInfo.holdingsSize != 7; - - if(overruled) { + if(NonStandardBoardSize()) { /* [HGM] make prefix for non-standard board size. */ snprintf(b, MSG_SIZ, "%dx%d+%d_%s", gameInfo.boardWidth, gameInfo.boardHeight, gameInfo.holdingsSize, VariantName(gameInfo.variant)); // cook up sized variant name /* [HGM] varsize: try first if this defiant size variant is specifically known */ @@ -10121,7 +10136,7 @@ WriteTourneyFile (char *results, FILE *f) fprintf(f, "-loadPositionIndex %d\n", appData.loadPositionIndex); fprintf(f, "-rewindIndex %d\n", appData.rewindIndex); fprintf(f, "-usePolyglotBook %s\n", appData.usePolyglotBook ? "true" : "false"); - fprintf(f, "-polyglotBook %s\n", appData.polyglotBook); + fprintf(f, "-polyglotBook \"%s\"\n", appData.polyglotBook); fprintf(f, "-bookDepth %d\n", appData.bookDepth); fprintf(f, "-bookVariation %d\n", appData.bookStrength); fprintf(f, "-discourageOwnBooks %s\n", appData.defNoBook ? "true" : "false"); @@ -11172,17 +11187,23 @@ AutoPlayOneMove () if (gameMode != PlayFromGameFile && gameMode != AnalyzeFile) return FALSE; - if (gameMode == AnalyzeFile && currentMove > backwardMostMove) { + if (gameMode == AnalyzeFile && currentMove > backwardMostMove && programStats.depth) { pvInfoList[currentMove].depth = programStats.depth; pvInfoList[currentMove].score = programStats.score; pvInfoList[currentMove].time = 0; if(currentMove < forwardMostMove) AppendComment(currentMove+1, lastPV[0], 2); + else { // append analysis of final position as comment + char buf[MSG_SIZ]; + snprintf(buf, MSG_SIZ, "{final score %+4.2f/%d}", programStats.score/100., programStats.depth); + AppendComment(currentMove, buf, 3); // the 3 prevents stripping of the score/depth! + } + programStats.depth = 0; } if (currentMove >= forwardMostMove) { if(gameMode == AnalyzeFile) { if(appData.loadGameIndex == -1) { - GameEnds(EndOfFile, NULL, GE_FILE); + GameEnds(gameInfo.result, gameInfo.resultDetails ? gameInfo.resultDetails : "", GE_FILE); ScheduleDelayedEvent(AnalyzeNextGame, 10); } else { ExitAnalyzeMode(); SendToProgram("force\n", &first); @@ -11701,22 +11722,40 @@ void PackMove (int fromX, int fromY, int toX, int toY, ChessSquare promoPiece) { int sq = fromX + (fromY<<4); - int piece = quickBoard[sq]; + int piece = quickBoard[sq], rook; quickBoard[sq] = 0; moveDatabase[movePtr].to = pieceList[piece] = sq = toX + (toY<<4); - if(piece == pieceList[1] && fromY == toY && (toX > fromX+1 || toX < fromX-1) && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1) { + if(piece == pieceList[1] && fromY == toY) { + if((toX > fromX+1 || toX < fromX-1) && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1) { int from = toX>fromX ? BOARD_RGHT-1 : BOARD_LEFT; moveDatabase[movePtr++].piece = Q_WCASTL; quickBoard[sq] = piece; piece = quickBoard[from]; quickBoard[from] = 0; moveDatabase[movePtr].to = pieceList[piece] = sq = toX>fromX ? sq-1 : sq+1; + } else if((rook = quickBoard[sq]) && pieceType[rook] == WhiteRook) { // FRC castling + quickBoard[sq] = 0; // remove Rook + moveDatabase[movePtr].to = sq = (toX>fromX ? BOARD_RGHT-2 : BOARD_LEFT+2); // King to-square + moveDatabase[movePtr++].piece = Q_WCASTL; + quickBoard[sq] = pieceList[1]; // put King + piece = rook; + moveDatabase[movePtr].to = pieceList[rook] = sq = toX>fromX ? sq-1 : sq+1; + } } else - if(piece == pieceList[2] && fromY == toY && (toX > fromX+1 || toX < fromX-1) && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1) { + if(piece == pieceList[2] && fromY == toY) { + if((toX > fromX+1 || toX < fromX-1) && fromX != BOARD_LEFT && fromX != BOARD_RGHT-1) { int from = (toX>fromX ? BOARD_RGHT-1 : BOARD_LEFT) + (BOARD_HEIGHT-1 <<4); moveDatabase[movePtr++].piece = Q_BCASTL; quickBoard[sq] = piece; piece = quickBoard[from]; quickBoard[from] = 0; moveDatabase[movePtr].to = pieceList[piece] = sq = toX>fromX ? sq-1 : sq+1; + } else if((rook = quickBoard[sq]) && pieceType[rook] == BlackRook) { // FRC castling + quickBoard[sq] = 0; // remove Rook + moveDatabase[movePtr].to = sq = (toX>fromX ? BOARD_RGHT-2 : BOARD_LEFT+2); + moveDatabase[movePtr++].piece = Q_BCASTL; + quickBoard[sq] = pieceList[2]; // put King + piece = rook; + moveDatabase[movePtr].to = pieceList[rook] = sq = toX>fromX ? sq-1 : sq+1; + } } else if(epOK && (pieceType[piece] == WhitePawn || pieceType[piece] == BlackPawn) && fromX != toX && quickBoard[sq] == 0) { quickBoard[(fromY<<4)+toX] = 0; @@ -12032,7 +12071,7 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) gn = 1; } else { - if(gameMode == AnalyzeFile && appData.loadGameIndex == -1) + if(oldGameMode == AnalyzeFile && appData.loadGameIndex == -1) appData.loadGameIndex = 0; // [HGM] suppress error message if we reach file end after auto-stepping analysis else DisplayError(_("Game number out of range"), 0); @@ -12428,10 +12467,12 @@ LoadGame (FILE *f, int gameNumber, char *title, int useList) HistorySet(parseList, backwardMostMove, forwardMostMove, currentMove-1); - if (oldGameMode == AnalyzeFile || - oldGameMode == AnalyzeMode) { + if (oldGameMode == AnalyzeFile) { appData.loadGameIndex = -1; // [HGM] order auto-stepping through games AnalyzeFileEvent(); + } else + if (oldGameMode == AnalyzeMode) { + AnalyzeFileEvent(); } if(creatingBook) return TRUE; @@ -13649,7 +13690,7 @@ AnalyzeModeEvent () /* secure check */ if (appData.icsEngineAnalyze) { if (appData.debugMode) - fprintf(debugFP, _("Found unexpected active ICS engine analyze \n")); + fprintf(debugFP, "Found unexpected active ICS engine analyze \n"); ExitAnalyzeMode(); ModeHighlight(); } @@ -13663,7 +13704,7 @@ AnalyzeModeEvent () } appData.icsEngineAnalyze = TRUE; if (appData.debugMode) - fprintf(debugFP, _("ICS engine analyze starting... \n")); + fprintf(debugFP, "ICS engine analyze starting... \n"); } if (gameMode == AnalyzeMode) { ToggleSecond(); return 0; } @@ -15204,7 +15245,7 @@ void CreateBookEvent () { ListGame * lg = (ListGame *) gameList.head; - FILE *f; + FILE *f, *g; int nItem; static int secondTime = FALSE; @@ -15213,8 +15254,8 @@ CreateBookEvent () return; } - if(!secondTime && (f = fopen(appData.polyglotBook, "r"))) { - fclose(f); + if(!secondTime && (g = fopen(appData.polyglotBook, "r"))) { + fclose(g); secondTime++; DisplayNote(_("Book file exists! Try again for overwrite.")); return; @@ -15512,7 +15553,8 @@ AppendComment (int index, char *text, Boolean addBraces) int oldlen, len; char *old; -if(appData.debugMode) fprintf(debugFP, "Append: in='%s' %d\n", text, addBraces); fflush(debugFP); +if(appData.debugMode) fprintf(debugFP, "Append: in='%s' %d\n", text, addBraces); + if(addBraces == 3) addBraces = 0; else // force appending literally text = GetInfoFromComment( index, text ); /* [HGM] PV time: strip PV info from comment */ CrushCRs(text); @@ -15579,8 +15621,11 @@ GetInfoFromComment (int index, char * text) int time = -1, sec = 0, deci; char * s_eval = FindStr( text, "[%eval " ); char * s_emt = FindStr( text, "[%emt " ); - +#if 0 if( s_eval != NULL || s_emt != NULL ) { +#else + if(0) { // [HGM] this code is not finished, and could actually be detrimental +#endif /* New style */ char delim; @@ -15610,6 +15655,7 @@ GetInfoFromComment (int index, char * text) } p = text; + if(!strncmp(p+1, "final score ", 12)) p += 12, index++; else if(p[1] == '(') { // comment starts with PV p = strchr(p, ')'); // locate end of PV if(p == NULL || sep < p+5) return text; @@ -15633,7 +15679,7 @@ GetInfoFromComment (int index, char * text) if(sec >= 0) time = 600*time + 10*sec; else if(deci >= 0) time = 10*time + deci; else time *= 10; // deci-sec - score = score >= 0 ? score*100 + score_lo : score*100 - score_lo; + score = score > 0 || !score & p[1] != '-' ? score*100 + score_lo : score*100 - score_lo; /* [HGM] PV time: now locate end of PV info */ while( *++sep >= '0' && *sep <= '9'); // strip depth @@ -15944,14 +15990,15 @@ IntFeature (char **p, char *name, int *loc, ChessProgramState *cps) } int -StringFeature (char **p, char *name, char loc[], ChessProgramState *cps) +StringFeature (char **p, char *name, char **loc, ChessProgramState *cps) { char buf[MSG_SIZ]; int len = strlen(name); if (strncmp((*p), name, len) == 0 && (*p)[len] == '=' && (*p)[len+1] == '\"') { (*p) += len + 2; - sscanf(*p, "%[^\"]", loc); + ASSIGN(*loc, *p); // kludge alert: assign rest of line just to be sure allocation is large enough so that sscanf below always fits + sscanf(*p, "%[^\"]", *loc); while (**p && **p != '\"') (*p)++; if (**p == '\"') (*p)++; snprintf(buf, MSG_SIZ, "accepted %s\n", name); @@ -16072,7 +16119,7 @@ void ParseFeatures (char *args, ChessProgramState *cps) { char *p = args; - char *q; + char *q = NULL; int val; char buf[MSG_SIZ]; @@ -16092,7 +16139,7 @@ ParseFeatures (char *args, ChessProgramState *cps) continue; } if (BoolFeature(&p, "analyze", &cps->analysisSupport, cps)) continue; - if (StringFeature(&p, "myname", cps->tidy, cps)) { + if (StringFeature(&p, "myname", &cps->tidy, cps)) { if (gameMode == TwoMachinesPlay) { DisplayTwoMachinesTitle(); } else { @@ -16100,7 +16147,7 @@ ParseFeatures (char *args, ChessProgramState *cps) } continue; } - if (StringFeature(&p, "variants", cps->variants, cps)) continue; + if (StringFeature(&p, "variants", &cps->variants, cps)) continue; if (BoolFeature(&p, "san", &cps->useSAN, cps)) continue; if (BoolFeature(&p, "ping", &cps->usePing, cps)) continue; if (BoolFeature(&p, "playother", &cps->usePlayother, cps)) continue; @@ -16125,12 +16172,11 @@ ParseFeatures (char *args, ChessProgramState *cps) if (IntFeature(&p, "level", &cps->maxNrOfSessions, cps)) continue; if (BoolFeature(&p, "memory", &cps->memSize, cps)) continue; if (BoolFeature(&p, "smp", &cps->maxCores, cps)) continue; - if (StringFeature(&p, "egt", cps->egtFormats, cps)) continue; - if (StringFeature(&p, "option", buf, cps)) { - if(cps->reload) continue; // we are reloading because of xreuse + if (StringFeature(&p, "egt", &cps->egtFormats, cps)) continue; + if (StringFeature(&p, "option", &q, cps)) { // read to freshly allocated temp buffer first + if(cps->reload) { FREE(q); q = NULL; continue; } // we are reloading because of xreuse FREE(cps->option[cps->nrOptions].name); - cps->option[cps->nrOptions].name = malloc(MSG_SIZ); - safeStrCpy(cps->option[cps->nrOptions].name, buf, MSG_SIZ); + cps->option[cps->nrOptions].name = q; q = NULL; if(!ParseOption(&(cps->option[cps->nrOptions++]), cps)) { // [HGM] options: add option feature snprintf(buf, MSG_SIZ, "rejected option %s\n", cps->option[--cps->nrOptions].name); SendToProgram(buf, cps);