} else if ((i = 4, p = StrCaseStr(e, "wild")) ||
(i = 1, p = StrCaseStr(e, "w"))) {
p += i;
- while (*p && (isspace(*p) || *p == '(')) p++;
+ while (*p && (isspace(*p) || *p == '(' || *p == '/')) p++;
if (isdigit(*p)) {
wnum = atoi(p);
} else {
}
/* Improved generic start/end-of-game messages */
- if (looking_at(buf, &i, "{Game * (* vs. *) *}*")) {
+ if ((tkind=0, looking_at(buf, &i, "{Game * (* vs. *) *}*")) ||
+ (tkind=1, looking_at(buf, &i, "{Game * (*(*) vs. *(*)) *}*"))){
+ /* If tkind == 0: */
/* star_match[0] is the game number */
/* [1] is the white player's name */
/* [2] is the black player's name */
/* [3] begins with "Creating" or "Continuing" */
/* [4] is " *" or empty (don't care). */
int gamenum = atoi(star_match[0]);
- char *why = star_match[3];
- char *endtoken = star_match[4];
+ char *whitename, *blackname, *why, *endtoken;
ChessMove endtype = (ChessMove) 0;
+ if (tkind == 0) {
+ whitename = star_match[1];
+ blackname = star_match[2];
+ why = star_match[3];
+ endtoken = star_match[4];
+ } else {
+ whitename = star_match[1];
+ blackname = star_match[3];
+ why = star_match[5];
+ endtoken = star_match[6];
+ }
+
/* Game start messages */
if (strncmp(why, "Creating ", 9) == 0 ||
strncmp(why, "Continuing ", 11) == 0) {
strcpy(gs_kind, strchr(why, ' ') + 1);
#if ZIPPY
if (appData.zippyPlay) {
- ZippyGameStart(star_match[1], star_match[2]);
+ ZippyGameStart(whitename, blackname);
}
#endif /*ZIPPY*/
continue;
/* Machine move could not be parsed; ignore it. */
sprintf(buf1, "Illegal move \"%s\" from %s machine",
machineMove, cps->which);
- /*!!if (appData.debugMode)*/ DisplayError(buf1, 0);
+ DisplayError(buf1, 0);
+ if (gameMode == TwoMachinesPlay) {
+ GameEnds(machineWhite ? BlackWins : WhiteWins,
+ "Forfeit due to illegal move", GE_XBOARD);
+ }
return;
}
DisplayError(buf2, 0);
return;
}
- if (StrStr(message, "st")) {
+ if (StrStr(message, "(no matching move)st")) {
+ /* Special kludge for GNU Chess 4 only */
cps->stKludge = TRUE;
SendTimeControl(cps, movesPerSession, timeControl,
timeIncrement, appData.searchDepth,
searchTime);
return;
}
- if (StrStr(message, "sd")) {
+ if (StrStr(message, "(no matching move)sd")) {
+ /* Special kludge for GNU Chess 4 only */
cps->sdKludge = TRUE;
SendTimeControl(cps, movesPerSession, timeControl,
timeIncrement, appData.searchDepth,
if (gameMode == BeginningOfGame || gameMode == EndOfGame ||
gameMode == IcsIdle) return;
if (forwardMostMove <= backwardMostMove) return;
+#if 0
+ /* Following removed: it caused a bug where a real illegal move
+ message in analyze mored would be ignored. */
if (cps == &first && programStats.ok_to_send == 0) {
/* Bogus message from Crafty responding to "." This filtering
can miss some of the bad messages, but fortunately the bug
is fixed in current Crafty versions, so it doesn't matter. */
return;
}
+#endif
if (pausing) PauseEvent();
if (gameMode == PlayFromGameFile) {
/* Stop reading this game file */
}
return;
case ElapsedTime:
- if (boardIndex > 0) {
+ if (boardIndex > (blackPlaysFirst ? 1 : 0)) {
strcat(parseList[boardIndex-1], " ");
strcat(parseList[boardIndex-1], yy_text);
}
* A game that starts with one of the latter two patterns
* will also have a move number 1, possibly
* following a position diagram.
+ * 5-4-02: Let's try being more lenient and allowing a game to
+ * start with an unnumbered move. Does that break anything?
*/
cm = lastLoadGameStart = (ChessMove) 0;
- yyskipmoves = TRUE;
while (gn > 0) {
yyboardindex = forwardMostMove;
cm = (ChessMove) yylex();
- yyskipmoves = FALSE;
switch (cm) {
case (ChessMove) 0:
if (cmailMsgLoaded) {
Reset(TRUE, TRUE);
DisplayError("Game not found in file", 0);
}
- yyskipmoves = FALSE;
return FALSE;
case GNUChessGame:
}
break;
+ case NormalMove:
+ /* Only a NormalMove can be at the start of a game
+ * without a position diagram. */
+ if (lastLoadGameStart == (ChessMove) 0) {
+ gn--;
+ lastLoadGameStart = MoveNumberOne;
+ }
+ break;
+
default:
break;
}
}
- yyskipmoves = FALSE;
if (appData.debugMode)
fprintf(debugFP, "Parsed game start '%s' (%d)\n", yy_text, (int) cm);
cm = (ChessMove) yylex();
}
- if (cm == (ChessMove) 0 || cm == WhiteWins || cm == BlackWins ||
+ if ((cm == (ChessMove) 0 && lastLoadGameStart != (ChessMove) 0) ||
+ cm == WhiteWins || cm == BlackWins ||
cm == GameIsDrawn || cm == GameUnfinished) {
DisplayMessage("", "No moves in game");
if (cmailMsgLoaded) {
while (pn > 0) {
/* skip postions before number pn */
if (fgets(line, MSG_SIZ, f) == NULL) {
+ Reset(TRUE, TRUE);
DisplayError("Position not found in file", 0);
return FALSE;
}
ReloadCmailMsgEvent(unregister)
int unregister;
{
+#if !WIN32
static char *inFilename = NULL;
static char *outFilename;
int i;
/* Load first game in the file or popup game menu */
LoadGameFromFile(inFilename, 0, appData.cmailGameName, TRUE);
+#endif // !WIN32
return;
}
void
MailMoveEvent()
{
+#if !WIN32
static char *partCommandString = "cmail -xv%s -remail -game %s 2>&1";
FILE *commandOutput;
char buffer[MSG_SIZ], msg[MSG_SIZ], string[MSG_SIZ];
|| (nCmailMovesRegistered + nCmailResults == nCmailGames)) {
sprintf(string, partCommandString,
appData.debugMode ? " -v" : "", appData.cmailGameName);
- commandOutput = popen(string, "r");
+ commandOutput = popen(string, "rb");
if (commandOutput == NULL) {
DisplayError("Failed to invoke cmail", 0);
}
return;
+#endif // !WIN32
}
char *
CmailMsg()
{
+#if WIN32
+ return NULL;
+#else
int prependComma = 0;
char number[5];
char string[MSG_SIZ]; /* Space for game-list */
}
}
}
-
return cmailMsg;
+#endif // WIN32
}
void
}
void
+CrushCRs(text)
+ char *text;
+{
+ char *p = text;
+ char *q = text;
+ char ch;
+
+ do {
+ ch = *p++;
+ if (ch == '\r') continue;
+ *q++ = ch;
+ } while (ch != '\0');
+}
+
+void
AppendComment(index, text)
int index;
char *text;
int oldlen, len;
char *old;
+ CrushCRs(text);
while (*text == '\n') text++;
len = strlen(text);
while (len > 0 && text[len - 1] == '\n') len--;