/*
* parser.c --
*
- * Copyright 2011, 2012, 2013 Free Software Foundation, Inc.
+ * Copyright 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
* ------------------------------------------------------------------------
*
* GNU XBoard is free software: you can redistribute it and/or modify
return *p != start;
}
-inline int
+static inline int
Match (char *pattern, char **ptr)
{
char *p = pattern, *s = *ptr;
return 0; // no match, no ptr update
}
-inline int
+static inline int
Word (char *pattern, char **p)
{
if(Match(pattern, p)) return 1;
if(**p == '=' || (gameInfo.variant == VariantSChess) && **p == '/') (*p)++; // optional = (or / for Seirawan gating)
if(**p == '(' && (*p)[2] == ')' && isalpha( (*p)[1] )) { (*p) += 3; return ToLower((*p)[-2]); }
if(isalpha(**p) && **p != 'x') return ToLower(*(*p)++); // reserve 'x' for multi-leg captures?
- if(*p != start) return '='; // must be the optional =
+ if(*p != start) return **p == '+' ? *(*p)++ : '='; // must be the optional = (or =+)
return NULLCHAR; // no suffix detected
}
if(fromString) return 0; // we are parsing string, so the end is really the end
*p = inPtr = inputBuf;
if(!ReadLine()) return 0; // EOF
+ } else if(inPtr > inputBuf + PARSEBUFSIZE/2) { // buffer fills up with already parsed stuff
+ char *q = *p, *r = inputBuf;
+ while(*r++ = *q++);
+ *p = inputBuf; inPtr = r - 1;
}
parseStart = oldp = *p; // remember where we begin
if(piece) {
cl.pieceIn = CharToPiece(wom ? piece : ToLower(piece));
if(cl.pieceIn == EmptySquare) return ImpossibleMove; // non-existent piece
- if(promoted) cl.pieceIn = (ChessSquare) (PROMOTED 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;
toY = cl.rtIn = (currentMoveString[3] = Number(p) + '0') - ONE;
}
if(type[0] != NOTHING && type[1] != NOTHING && type[3] != NOTHING) { // fully specified.
+ 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
- ChessSquare realPiece = boards[yyboardindex][fromY][fromX];
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
+ currentMoveString[4] = cl.promoCharIn = *(*p)++; // append promochar after all
}
result = LegalityTest(boards[yyboardindex], PosFlags(yyboardindex), fromY, fromX, toY, toX, cl.promoCharIn);
if (currentMoveString[4] == NULLCHAR) { // suppy missing mandatory promotion character