Merge branch 'v4.8.x'
[xboard.git] / parser.c
index 4924bbd..1d18403 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -22,6 +22,7 @@
 
 #include "config.h"
 #include <stdio.h>
+#include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
 #include "common.h"
@@ -380,6 +381,7 @@ char
 PromoSuffix (char **p)
 {
     char *start = *p;
+    if(**p == ' ') return NULLCHAR; // common case, test explicitly for speed
     if(**p == 'e' && (Match("ep", p) || Match("e.p.", p))) { *p = start; return NULLCHAR; } // non-compliant e.p. suffix is no promoChar!
     if(**p == '+' && IS_SHOGI(gameInfo.variant)) { (*p)++; return '+'; }
     if(**p == '=' || (gameInfo.variant == VariantSChess) && **p == '/') (*p)++; // optional = (or / for Seirawan gating)
@@ -494,7 +496,7 @@ NextUnit (char **p)
            if(piece) {
                cl.pieceIn = CharToPiece(wom ? piece : piece + 'a' - 'A');
                if(cl.pieceIn == EmptySquare) return ImpossibleMove; // non-existent piece
-               if(promoted) cl.pieceIn = (ChessSquare) (CHUPROMOTED cl.pieceIn);
+               if(promoted) cl.pieceIn = (ChessSquare) (CHUPROMOTED(cl.pieceIn));
            } else cl.pieceIn = EmptySquare;
            if(separator == '@' || separator == '*') { // drop move. We only get here without from-square or promoted piece
                fromY = DROP_RANK; fromX = cl.pieceIn;
@@ -526,11 +528,11 @@ NextUnit (char **p)
                    ChessSquare realPiece = boards[yyboardindex][fromY][fromX];
                    // Note that Disambiguate does not work for illegal moves, but flags them as impossible
                    if(piece) { // check if correct piece indicated
-                       if(PieceToChar(realPiece) == '~') realPiece = (ChessSquare) (DEMOTED realPiece);
+                       if(PieceToChar(realPiece) == '~') realPiece = (ChessSquare) (DEMOTED(realPiece));
                        if(!(appData.icsActive && PieceToChar(realPiece) == '+') && // trust ICS if it moves promoted pieces
                           piece && realPiece != cl.pieceIn) return ImpossibleMove;
                    } else if(!separator && **p == '+') { // could be a protocol move, where bare '+' suffix means shogi-style promotion
-                       if(realPiece < (wom ?  WhiteCannon : BlackCannon) && PieceToChar(PROMOTED realPiece) == '+') // seems to be that
+                       if(realPiece < (wom ?  WhiteCannon : BlackCannon) && PieceToChar(PROMOTED(realPiece)) == '+') // seems to be that
                           currentMoveString[4] = cl.promoCharIn = *(*p)++; // append promochar after all
                    }
                    result = LegalityTest(boards[yyboardindex], PosFlags(yyboardindex), fromY, fromX, toY, toX, cl.promoCharIn);
@@ -619,12 +621,12 @@ badMove:// we failed to find algebraic move
                if (yyskipmoves) return (int) AmbiguousMove; /* not disambiguated */
 
                if (wom) {
-                   rf = 0;
-                   rt = 0;
+                   rf = castlingRank[0];
+                   rt = castlingRank[0];
                    king = WhiteKing;
                } else {
-                   rf = BOARD_HEIGHT-1;
-                   rt = BOARD_HEIGHT-1;
+                   rf = castlingRank[3];
+                   rt = castlingRank[3];
                    king = BlackKing;
                }
                ff = (BOARD_WIDTH-1)>>1; // this would be d-file
@@ -632,8 +634,12 @@ badMove:// we failed to find algebraic move
                    /* ICS wild castling */
                    ft = castlingType == 1 ? BOARD_LEFT+1 : (gameInfo.variant == VariantJanus ? BOARD_RGHT-2 : BOARD_RGHT-3);
                } else {
+                   char *q;
                    ff = BOARD_WIDTH>>1; // e-file
                    ft = castlingType == 1 ? BOARD_RGHT-2 : BOARD_LEFT+2;
+                   if(pieceDesc[king] && (q = strchr(pieceDesc[king], 'O'))) { // redefined to non-default King stride
+                       ft = (castlingType == 1 ? ff + atoi(q+1) : ff - atoi(q+1));
+                   }
                }
                if(PosFlags(0) & F_FRC_TYPE_CASTLING) {
                    if (wom) {