Fix some resource leaks
[xboard.git] / backend.c
index 5224018..460a4af 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -5,7 +5,7 @@
  * Massachusetts.
  *
  * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,
- * 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ * 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
  *
  * Enhancements Copyright 2005 Alessandro Scotti
  *
@@ -2861,7 +2861,7 @@ read_from_ics(isr, closure, data, count, error)
 
                if(channel >= 0) // channel broadcast; look if there is a chatbox for this channel
                for(p=0; p<MAX_CHAT; p++) {
-                   if(channel == atoi(chatPartner[p])) {
+                   if(chatPartner[p][0] >= '0' && chatPartner[p][0] <= '9' && channel == atoi(chatPartner[p])) {
                    talker[0] = '['; strcat(talker, "] ");
                    Colorize(channel == 1 ? ColorChannel1 : ColorChannel, FALSE);
                    chattingPartner = p; break;
@@ -5985,6 +5985,7 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
       case BeginningOfGame:
       case AnalyzeMode:
       case Training:
+       if(fromY == DROP_RANK) break; // [HGM] drop moves (entered through move type-in) are automatically assigned to side-to-move
        if ((int) boards[currentMove][fromY][fromX] >= (int) BlackPawn &&
             (int) boards[currentMove][fromY][fromX] < (int) EmptySquare) {
            /* User is moving for Black */
@@ -6079,7 +6080,7 @@ UserMoveEvent(fromX, fromY, toX, toY, promoChar)
     pup = boards[currentMove][toY][toX];
 
     /* [HGM] If move started in holdings, it means a drop. Convert to standard form */
-    if( fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) { 
+    if( (fromX == BOARD_LEFT-2 || fromX == BOARD_RGHT+1) && fromY != DROP_RANK ) {
          if( pup != EmptySquare ) return;
          moveType = WhiteOnMove(currentMove) ? WhiteDrop : BlackDrop;
           if(appData.debugMode) fprintf(debugFP, "Drop move %d, curr=%d, x=%d,y=%d, p=%d\n", 
@@ -6187,7 +6188,10 @@ FinishMove(moveType, fromX, fromY, toX, toY, promoChar)
 
   MakeMove(fromX, fromY, toX, toY, promoChar); /*updates forwardMostMove*/
 
-  if(Adjudicate(NULL)) return 1; // [HGM] adjudicate: take care of automtic game end
+  if(Adjudicate(NULL)) { // [HGM] adjudicate: take care of automatic game end
+    ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
+    return 1;
+  }
 
   if (gameMode == BeginningOfGame) {
     if (appData.noChessProgram) {
@@ -6242,6 +6246,7 @@ FinishMove(moveType, fromX, fromY, toX, toY, promoChar)
 
   switch (gameMode) {
   case EditGame:
+    if(appData.testLegality)
     switch (MateTest(boards[currentMove], PosFlags(currentMove)) ) {
     case MT_NONE:
     case MT_CHECK:
@@ -6810,7 +6815,6 @@ Adjudicate(ChessProgramState *cps)
                     if(canAdjudicate && appData.checkMates) {
                         if(engineOpponent)
                           SendMoveToProgram(forwardMostMove-1, engineOpponent); // make sure opponent gets move
-                         ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
                          GameEnds( WhiteOnMove(forwardMostMove) ? BlackWins : WhiteWins,
                                                        "Xboard adjudication: King destroyed", GE_XBOARD );
                          return 1;
@@ -6824,7 +6828,6 @@ Adjudicate(ChessProgramState *cps)
                     if(canAdjudicate && appData.checkMates) {
                         if(engineOpponent)
                           SendMoveToProgram(forwardMostMove-1, engineOpponent); // make sure opponent gets to see move
-                         ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
                          GameEnds( WhiteOnMove(forwardMostMove) ? WhiteWins : BlackWins,
                                                        "Xboard adjudication: Bare king", GE_XBOARD );
                          return 1;
@@ -6837,7 +6840,6 @@ Adjudicate(ChessProgramState *cps)
                            /* but only adjudicate if adjudication enabled */
                            if(engineOpponent)
                              SendMoveToProgram(forwardMostMove-1, engineOpponent); // make sure opponent gets move
-                           ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
                            GameEnds( nrW > 1 ? WhiteWins : nrB > 1 ? BlackWins : GameIsDrawn,
                                                        "Xboard adjudication: Bare king", GE_XBOARD );
                            return 1;
@@ -6898,7 +6900,6 @@ Adjudicate(ChessProgramState *cps)
                 if(canAdjudicate && appData.checkMates && result) { // [HGM] mates: adjudicate finished games if requested
                    if(engineOpponent)
                      SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */
-                   ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
                    GameEnds( result, reason, GE_XBOARD );
                    return 1;
                }
@@ -6917,7 +6918,6 @@ Adjudicate(ChessProgramState *cps)
                           SendToProgram("force\n", engineOpponent); // suppress reply
                           SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see last move */
                         }
-                         ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
                          GameEnds( GameIsDrawn, "Xboard adjudication: Insufficient mating material", GE_XBOARD );
                          return 1;
                      }
@@ -6938,7 +6938,6 @@ Adjudicate(ChessProgramState *cps)
                            SendToProgram("force\n", engineOpponent); // suppress reply
                            SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */
                          }
-                          ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
                           GameEnds( GameIsDrawn, "Xboard adjudication: Trivial draw", GE_XBOARD );
                           return 1;
                      }
@@ -7021,7 +7020,6 @@ Adjudicate(ChessProgramState *cps)
                               SendToProgram("force\n", engineOpponent); // suppress reply
                               SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */
                             }
-                             ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
                              GameEnds( result, details, GE_XBOARD );
                              return 1;
                         }
@@ -7058,7 +7056,6 @@ Adjudicate(ChessProgramState *cps)
                           SendToProgram("force\n", engineOpponent); // suppress reply
                           SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */
                         }
-                         ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
                          GameEnds( GameIsDrawn, "Xboard adjudication: 50-move rule", GE_XBOARD );
                          return 1;
                 }
@@ -7081,7 +7078,6 @@ Adjudicate(ChessProgramState *cps)
                               SendToProgram("force\n", engineOpponent); // suppress reply
                               SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */
                             }
-                             ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
                              GameEnds( GameIsDrawn, p, GE_XBOARD );
                              return 1;
                          }
@@ -7092,7 +7088,6 @@ Adjudicate(ChessProgramState *cps)
                      SendToProgram("force\n", engineOpponent); // suppress reply
                      SendMoveToProgram(forwardMostMove-1, engineOpponent); /* make sure opponent gets to see move */
                    }
-                   ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
                    GameEnds( GameIsDrawn, "Xboard adjudication: long game", GE_XBOARD );
                    return 1;
                }
@@ -7328,11 +7323,6 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
        if (cps->sendTime == 2) cps->sendTime = 1;
        if (cps->offeredDraw) cps->offeredDraw--;
 
-       /* currentMoveString is set as a side-effect of ParseOneMove */
-       safeStrCpy(machineMove, currentMoveString, sizeof(machineMove)/sizeof(machineMove[0]));
-       strcat(machineMove, "\n");
-       safeStrCpy(moveList[forwardMostMove], machineMove, sizeof(moveList[forwardMostMove])/sizeof(moveList[forwardMostMove][0]));
-
         /* [AS] Save move info*/
         pvInfoList[ forwardMostMove ].score = programStats.score;
         pvInfoList[ forwardMostMove ].depth = programStats.depth;
@@ -7370,7 +7360,6 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
         }
 
        if(Adjudicate(cps)) {
-           DrawPosition(FALSE, boards[currentMove = forwardMostMove-1]);
            ShowMove(fromX, fromY, toX, toY); /*updates currentMove*/
            return; // [HGM] adjudicate: for all automatic game ends
        }
@@ -8422,7 +8411,8 @@ ApplyMove(fromX, fromY, toX, toY, promoChar, board)
       int i;
 
       if( board[fromY][fromX] == WhiteLance || board[fromY][fromX] == BlackLance ) {
-           if( gameInfo.variant == VariantFairy ) board[EP_STATUS] = EP_PAWN_MOVE; // Lance in fairy is Pawn-like
+           if( gameInfo.variant != VariantSuper && gameInfo.variant != VariantShogi )
+               board[EP_STATUS] = EP_PAWN_MOVE; // Lance is Pawn-like in most variants
       } else
       if( board[fromY][fromX] == WhitePawn ) {
            if(fromY != toY) // [HGM] Xiangqi sideway Pawn moves should not count as 50-move breakers
@@ -8905,7 +8895,7 @@ InitChessProgram(cps, setup)
       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 == 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;
@@ -9927,8 +9917,6 @@ LoadGameOneMove(readAhead)
        return FALSE;
     } else {
        /* currentMoveString is set as a side-effect of yylex */
-       strcat(currentMoveString, "\n");
-       safeStrCpy(moveList[forwardMostMove], currentMoveString, sizeof(moveList[forwardMostMove])/sizeof(moveList[forwardMostMove][0]));
 
        thinkOutput[0] = NULLCHAR;
        MakeMove(fromX, fromY, toX, toY, promoChar);
@@ -12620,6 +12608,30 @@ CallFlagEvent()
 }
 
 void
+ClockClick(int which)
+{      // [HGM] code moved to back-end from winboard.c
+       if(which) { // black clock
+         if (gameMode == EditPosition || gameMode == IcsExamining) {
+           SetBlackToPlayEvent();
+         } else if (gameMode == EditGame || shiftKey) {
+           AdjustClock(which, -1);
+         } else if (gameMode == IcsPlayingWhite ||
+                    gameMode == MachinePlaysBlack) {
+           CallFlagEvent();
+         }
+       } else { // white clock
+         if (gameMode == EditPosition || gameMode == IcsExamining) {
+           SetWhiteToPlayEvent();
+         } else if (gameMode == EditGame || shiftKey) {
+           AdjustClock(which, -1);
+         } else if (gameMode == IcsPlayingBlack ||
+                  gameMode == MachinePlaysWhite) {
+           CallFlagEvent();
+         }
+       }
+}
+
+void
 DrawEvent()
 {
     /* Offer draw or accept pending draw offer from opponent */