Redo Game List Options with generic popup
[xboard.git] / args.h
diff --git a/args.h b/args.h
index 0b021ac..a08d49b 100644 (file)
--- a/args.h
+++ b/args.h
@@ -2,10 +2,10 @@
  * args.c -- Option parsing and saving for X and Windows versions of XBoard
  *
  * Copyright 1991 by Digital Equipment Corporation, Maynard,
- * Massachusetts. 
+ * Massachusetts.
  *
  * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,
- * 2007, 2008, 2009 Free Software Foundation, Inc.
+ * 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
  *
  * Enhancements Copyright 2005 Alessandro Scotti
  *
  * along with this program. If not, see http://www.gnu.org/licenses/.  *
  *
  *------------------------------------------------------------------------
- ** See the file ChangeLog for a revision history.  
+ ** See the file ChangeLog for a revision history.
 */
 
 // Note: this file is not a normal header, but contains executable code
 // for #inclusion in winboard.c and xboard.c, rather than separate compilation,
-// so that it can make use of the proper context of #defined symbols and 
+// so that it can make use of the proper context of #defined symbols and
 // declarations in those files.
 
 typedef enum {
-  ArgString, ArgInt, ArgFloat, ArgBoolean, ArgTrue, ArgFalse, ArgNone, 
+  ArgString, ArgInt, ArgFloat, ArgBoolean, ArgTrue, ArgFalse, ArgNone,
   ArgColor, ArgAttribs, ArgFilename, ArgBoardSize, ArgFont, ArgCommSettings,
-  ArgSettingsFilename,
+  ArgSettingsFilename, ArgTwo,
   ArgX, ArgY, ArgZ // [HGM] placement: for window-placement options stored relative to main window
 } ArgType;
 
@@ -102,6 +102,8 @@ typedef struct {
 IcsTextMenuEntry icsTextMenuEntry[ICS_TEXT_MENU_SIZE];
 
 int junk;
+Boolean singleList;
+char *homeDir;
 
 void EnsureOnScreen(int *x, int *y, int minX, int minY);
 char StringGet(void *getClosure);
@@ -121,15 +123,13 @@ void SaveColor(FILE *f, ArgDescriptor *ad);
 void SaveBoardSize(FILE *f, char *name, void *addr);
 void PrintCommPortSettings(FILE *f, char *name);
 void GetWindowCoords();
-int  MySearchPath(char *installDir, char *name, char *fullname);
-int  MyGetFullPathName(char *name, char *fullname);
 int  MainWindowUp();
 void PopUpStartupDialog();
 typedef char GetFunc(void *getClosure);
 void ParseArgs(GetFunc get, void *cl);
 
 // [HGM] this is an exact duplicate of something in winboard.c. Move to backend.c?
-char *defaultTextAttribs[] = 
+char *defaultTextAttribs[] =
 {
   COLOR_SHOUT, COLOR_SSHOUT, COLOR_CHANNEL1, COLOR_CHANNEL, COLOR_KIBITZ,
   COLOR_TELL, COLOR_CHALLENGE, COLOR_REQUEST, COLOR_SEEK, COLOR_NORMAL,
@@ -156,8 +156,8 @@ ArgDescriptor argDescriptors[] = {
   { "phc", ArgColor, (void *) 5, FALSE, INVALID },
   { "movesPerSession", ArgInt, (void *) &appData.movesPerSession, TRUE, (ArgIniType) MOVES_PER_SESSION },
   { "mps", ArgInt, (void *) &appData.movesPerSession, FALSE, INVALID },
-  { "initString", ArgString, (void *) &appData.initString, FALSE, INVALID },
-  { "firstInitString", ArgString, (void *) &appData.initString, FALSE, (ArgIniType) INIT_STRING },
+  { "initString", ArgString, (void *) &appData.firstInitString, FALSE, INVALID },
+  { "firstInitString", ArgString, (void *) &appData.firstInitString, FALSE, (ArgIniType) INIT_STRING },
   { "secondInitString", ArgString, (void *) &appData.secondInitString, FALSE, (ArgIniType) INIT_STRING },
   { "firstComputerString", ArgString, (void *) &appData.firstComputerString,
     FALSE, (ArgIniType) COMPUTER_STRING },
@@ -185,6 +185,7 @@ ArgDescriptor argDescriptors[] = {
   { "fd", ArgFilename, (void *) &appData.firstDirectory, FALSE, INVALID },
   { "secondDirectory", ArgFilename, (void *) &appData.secondDirectory, FALSE, (ArgIniType) SECOND_DIRECTORY },
   { "sd", ArgFilename, (void *) &appData.secondDirectory, FALSE, INVALID },
+  { "variations", ArgBoolean, (void *) &appData.variations, TRUE, (ArgIniType) FALSE },
 
   /* some options only used by the XBoard front end, and ignored in WinBoard         */
   /* Their saving is controlled by XBOARD, which in WinBoard is defined as FALSE */
@@ -205,19 +206,23 @@ ArgDescriptor argDescriptors[] = {
   { "pixmap", ArgFilename, (void *) &appData.pixmapDirectory, FALSE, INVALID },
   { "bitmapDirectory", ArgFilename, (void *) &appData.bitmapDirectory, XBOARD, (ArgIniType) "" },
   { "bm", ArgFilename, (void *) &appData.bitmapDirectory, FALSE, INVALID },
+  { "soundDirectory", ArgFilename, (void *) &appData.soundDirectory, XBOARD, (ArgIniType) "" },
   { "msLoginDelay", ArgInt, (void *) &appData.msLoginDelay, XBOARD, (ArgIniType) MS_LOGIN_DELAY },
   { "pasteSelection", ArgBoolean, (void *) &appData.pasteSelection, XBOARD, (ArgIniType) FALSE },
 
+  { "dropMenu", ArgBoolean, (void *) &appData.dropMenu, TRUE, (ArgIniType) FALSE },
+  { "pieceMenu", ArgBoolean, (void *) &appData.pieceMenu, TRUE, (ArgIniType) TRUE },
+  { "sweepPromotions", ArgBoolean, (void *) &appData.sweepSelect, TRUE, (ArgIniType) FALSE },
   { "remoteShell", ArgFilename, (void *) &appData.remoteShell, FALSE, (ArgIniType) REMOTE_SHELL },
   { "rsh", ArgFilename, (void *) &appData.remoteShell, FALSE, INVALID },
-  { "remoteUser", ArgString, (void *) &appData.remoteUser, FALSE, INVALID },
+  { "remoteUser", ArgString, (void *) &appData.remoteUser, FALSE, (ArgIniType) "" },
   { "ruser", ArgString, (void *) &appData.remoteUser, FALSE, INVALID },
   { "timeDelay", ArgFloat, (void *) &appData.timeDelay, TRUE, INVALID },
   { "td", ArgFloat, (void *) &appData.timeDelay, FALSE, INVALID },
   { "timeControl", ArgString, (void *) &appData.timeControl, TRUE, (ArgIniType) TIME_CONTROL },
   { "tc", ArgString, (void *) &appData.timeControl, FALSE, INVALID },
-  { "timeIncrement", ArgInt, (void *) &appData.timeIncrement, TRUE, (ArgIniType) TIME_INCREMENT },
-  { "inc", ArgInt, (void *) &appData.timeIncrement, FALSE, INVALID },
+  { "timeIncrement", ArgFloat, (void *) &appData.timeIncrement, TRUE, INVALID },
+  { "inc", ArgFloat, (void *) &appData.timeIncrement, FALSE, INVALID },
   { "internetChessServerMode", ArgBoolean, (void *) &appData.icsActive, FALSE, INVALID },
   { "ics", ArgTrue, (void *) &appData.icsActive, FALSE, (ArgIniType) FALSE },
   { "xics", ArgFalse, (void *) &appData.icsActive, FALSE, INVALID },
@@ -237,9 +242,12 @@ ArgDescriptor argDescriptors[] = {
   { "xtelnet", ArgFalse, (void *) &appData.useTelnet, FALSE, INVALID },
   { "-telnet", ArgFalse, (void *) &appData.useTelnet, FALSE, INVALID },
   { "telnetProgram", ArgFilename, (void *) &appData.telnetProgram, FALSE, (ArgIniType) TELNET_PROGRAM },
-  { "internetChessserverHelper", ArgFilename, (void *) &appData.icsHelper, 
+  { "internetChessserverHelper", ArgFilename, (void *) &appData.icsHelper,
        FALSE, INVALID }, // for XB
   { "icshelper", ArgFilename, (void *) &appData.icsHelper, FALSE, (ArgIniType) "" },
+  { "seekGraph", ArgBoolean, (void *) &appData.seekGraph, TRUE, (ArgIniType) FALSE },
+  { "sg", ArgTrue, (void *) &appData.seekGraph, FALSE, INVALID },
+  { "autoRefresh", ArgBoolean, (void *) &appData.autoRefresh, TRUE, (ArgIniType) FALSE },
   { "gateway", ArgString, (void *) &appData.gateway, FALSE, (ArgIniType) "" },
   { "loadGameFile", ArgFilename, (void *) &appData.loadGameFile, FALSE, (ArgIniType) "" },
   { "lgf", ArgFilename, (void *) &appData.loadGameFile, FALSE, INVALID },
@@ -303,16 +311,17 @@ ArgDescriptor argDescriptors[] = {
   { "popup", ArgTrue, (void *) &appData.popupMoveErrors, FALSE, INVALID },
   { "xpopup", ArgFalse, (void *) &appData.popupMoveErrors, FALSE, INVALID },
   { "-popup", ArgFalse, (void *) &appData.popupMoveErrors, FALSE, INVALID },
-  { "popUpErrors", ArgBoolean, (void *) &appData.popupMoveErrors, 
+  { "popUpErrors", ArgBoolean, (void *) &appData.popupMoveErrors,
     FALSE, INVALID }, /* only so that old WinBoard.ini files from betas can be read */
   { "clockFont", ArgFont, (void *) CLOCK_FONT, TRUE, INVALID },
-  { "messageFont", ArgFont, (void *) MESSAGE_FONT, !XBOARD, INVALID },
-  { "font", ArgFont, (void *) MESSAGE_FONT, XBOARD, INVALID },
+  { "messageFont", ArgFont, (void *) MESSAGE_FONT, TRUE, INVALID },
+  { "font", ArgFont, (void *) MESSAGE_FONT, FALSE, INVALID }, /* only so that old .xboardrc files will parse. -font does not work from the command line because it is captured by the X libraries. */
   { "coordFont", ArgFont, (void *) COORD_FONT, TRUE, INVALID },
   { "tagsFont", ArgFont, (void *) EDITTAGS_FONT, TRUE, INVALID },
   { "commentFont", ArgFont, (void *) COMMENT_FONT, TRUE, INVALID },
   { "icsFont", ArgFont, (void *) CONSOLE_FONT, TRUE, INVALID },
   { "moveHistoryFont", ArgFont, (void *) MOVEHISTORY_FONT, TRUE, INVALID }, /* [AS] */
+  { "gameListFont", ArgFont, (void *) GAMELIST_FONT, TRUE, INVALID }, /* [HGM] */
   { "boardSize", ArgBoardSize, (void *) &boardSize,
     TRUE, (ArgIniType) -1 }, /* must come after all fonts */
   { "size", ArgBoardSize, (void *) &boardSize, FALSE, INVALID },
@@ -412,7 +421,7 @@ ArgDescriptor argDescriptors[] = {
   { "xhighlight", ArgFalse, (void *) &appData.highlightLastMove, FALSE, INVALID },
   { "-highlight", ArgFalse, (void *) &appData.highlightLastMove, FALSE, INVALID },
   { "highlightDragging", ArgBoolean,
-    (void *) &appData.highlightDragging, TRUE, INVALID },
+    (void *) &appData.highlightDragging, !XBOARD, (ArgIniType) TRUE },
   { "highdrag", ArgTrue, (void *) &appData.highlightDragging, FALSE, INVALID },
   { "xhighdrag", ArgFalse, (void *) &appData.highlightDragging, FALSE, INVALID },
   { "-highdrag", ArgFalse, (void *) &appData.highlightDragging, FALSE, INVALID },
@@ -449,6 +458,7 @@ ArgDescriptor argDescriptors[] = {
   { "soundIcsDraw", ArgFilename, (void *) &appData.soundIcsDraw, TRUE, (ArgIniType) "" },
   { "soundIcsUnfinished", ArgFilename, (void *) &appData.soundIcsUnfinished, TRUE, (ArgIniType) "" },
   { "soundIcsAlarm", ArgFilename, (void *) &appData.soundIcsAlarm, TRUE, (ArgIniType) "" },
+  { "disguisePromotedPieces", ArgBoolean, (void *) &appData.disguise, TRUE, (ArgIniType) TRUE },
   { "reuseFirst", ArgBoolean, (void *) &appData.reuseFirst, FALSE, (ArgIniType) TRUE },
   { "reuse", ArgTrue, (void *) &appData.reuseFirst, FALSE, INVALID },
   { "xreuse", ArgFalse, (void *) &appData.reuseFirst, FALSE, INVALID },
@@ -462,6 +472,8 @@ ArgDescriptor argDescriptors[] = {
   { "comPortSettings", ArgCommSettings, (void *) /*&dcb*/ 0, TRUE, INVALID },
   { "settingsFile", ArgSettingsFilename, (void *) &settingsFileName, FALSE, (ArgIniType) SETTINGS_FILE },
   { "ini", ArgSettingsFilename, (void *) &settingsFileName, FALSE, INVALID },
+  { "at", ArgSettingsFilename, (void *) NULL, FALSE, INVALID },
+  { "opt", ArgSettingsFilename, (void *) NULL, FALSE, INVALID },
   { "saveSettingsFile", ArgFilename, (void *) &settingsFileName, FALSE, INVALID },
   { "saveSettingsOnExit", ArgBoolean, (void *) &saveSettingsOnExit, TRUE, (ArgIniType) TRUE },
   { "chessProgram", ArgBoolean, (void *) &chessProgram, FALSE, (ArgIniType) FALSE },
@@ -470,10 +482,13 @@ ArgDescriptor argDescriptors[] = {
   { "-cp", ArgFalse, (void *) &chessProgram, FALSE, INVALID },
   { "icsMenu", ArgString, (void *) &icsTextMenuString, TRUE, (ArgIniType) ICS_TEXT_MENU_DEFAULT },
   { "icsNames", ArgString, (void *) &icsNames, TRUE, (ArgIniType) ICS_NAMES },
+  { "singleEngineList", ArgBoolean, (void *) &singleList, !XBOARD, (ArgIniType) FALSE },
+  { "recentEngines", ArgInt, (void *) &appData.recentEngines, TRUE, (ArgIniType) 6 },
+  { "recentEngineList", ArgString, (void *) &appData.recentEngineList, TRUE, (ArgIniType) "" },
   { "firstChessProgramNames", ArgString, (void *) &firstChessProgramNames,
     TRUE, (ArgIniType) FCP_NAMES },
   { "secondChessProgramNames", ArgString, (void *) &secondChessProgramNames,
-    TRUE, (ArgIniType) SCP_NAMES },
+    !XBOARD, (ArgIniType) SCP_NAMES },
   { "initialMode", ArgString, (void *) &appData.initialMode, FALSE, (ArgIniType) "" },
   { "mode", ArgString, (void *) &appData.initialMode, FALSE, INVALID },
   { "variant", ArgString, (void *) &appData.variant, FALSE, (ArgIniType) "normal" },
@@ -504,10 +519,11 @@ ArgDescriptor argDescriptors[] = {
   { "adjudicateLossThreshold", ArgInt, (void *) &appData.adjudicateLossThreshold, TRUE, (ArgIniType) 0 },
   { "delayBeforeQuit", ArgInt, (void *) &appData.delayBeforeQuit, TRUE, (ArgIniType) 0 },
   { "delayAfterQuit", ArgInt, (void *) &appData.delayAfterQuit, TRUE, (ArgIniType) 0 },
-  { "nameOfDebugFile", ArgFilename, (void *) &appData.nameOfDebugFile, FALSE, (ArgIniType) "winboard.debug" },
+  { "nameOfDebugFile", ArgFilename, (void *) &appData.nameOfDebugFile, FALSE, (ArgIniType) DEBUG_FILE },
   { "debugfile", ArgFilename, (void *) &appData.nameOfDebugFile, FALSE, INVALID },
   { "pgnEventHeader", ArgString, (void *) &appData.pgnEventHeader, TRUE, (ArgIniType) "Computer Chess Game" },
   { "defaultFrcPosition", ArgInt, (void *) &appData.defaultFrcPosition, TRUE, (ArgIniType) -1 },
+  { "shuffleOpenings", ArgTrue, (void *) &shuffleOpenings, FALSE, INVALID },
   { "gameListTags", ArgString, (void *) &appData.gameListTags, TRUE, (ArgIniType) GLT_DEFAULT_TAGS },
   { "saveOutOfBookInfo", ArgBoolean, (void *) &appData.saveOutOfBookInfo, TRUE, (ArgIniType) TRUE },
   { "showEvalInMoveHistory", ArgBoolean, (void *) &appData.showEvalInMoveHistory, TRUE, (ArgIniType) TRUE },
@@ -521,30 +537,64 @@ ArgDescriptor argDescriptors[] = {
   { "autoDisplayTags", ArgBoolean, (void *) &appData.autoDisplayTags, TRUE, (ArgIniType) TRUE },
   { "firstIsUCI", ArgBoolean, (void *) &appData.firstIsUCI, FALSE, (ArgIniType) FALSE },
   { "fUCI", ArgTrue, (void *) &appData.firstIsUCI, FALSE, INVALID },
+  { "firstUCI", ArgTrue, (void *) &appData.firstIsUCI, FALSE, INVALID },
   { "secondIsUCI", ArgBoolean, (void *) &appData.secondIsUCI, FALSE, (ArgIniType) FALSE },
   { "sUCI", ArgTrue, (void *) &appData.secondIsUCI, FALSE, INVALID },
+  { "fUCCI", ArgTwo, (void *) &appData.firstIsUCI, FALSE, INVALID },
+  { "sUCCI", ArgTwo, (void *) &appData.secondIsUCI, FALSE, INVALID },
+  { "fUSI", ArgTwo, (void *) &appData.firstIsUCI, FALSE, INVALID },
+  { "sUSI", ArgTwo, (void *) &appData.secondIsUCI, FALSE, INVALID },
+  { "secondUCI", ArgTrue, (void *) &appData.secondIsUCI, FALSE, INVALID },
   { "firstHasOwnBookUCI", ArgBoolean, (void *) &appData.firstHasOwnBookUCI, FALSE, (ArgIniType) TRUE },
   { "fNoOwnBookUCI", ArgFalse, (void *) &appData.firstHasOwnBookUCI, FALSE, INVALID },
   { "firstXBook", ArgFalse, (void *) &appData.firstHasOwnBookUCI, FALSE, INVALID },
   { "secondHasOwnBookUCI", ArgBoolean, (void *) &appData.secondHasOwnBookUCI, FALSE, (ArgIniType) TRUE },
   { "sNoOwnBookUCI", ArgFalse, (void *) &appData.secondHasOwnBookUCI, FALSE, INVALID },
   { "secondXBook", ArgFalse, (void *) &appData.secondHasOwnBookUCI, FALSE, INVALID },
-  { "adapterCommand", ArgFilename, (void *) &appData.adapterCommand, TRUE, (ArgIniType) "polyglot -noini -ec %%cp -ed %%d" },
+  { "adapterCommand", ArgFilename, (void *) &appData.adapterCommand, TRUE, (ArgIniType) "polyglot -noini -ec \"%fcp\" -ed \"%fd\"" },
+  { "uxiAdapter", ArgFilename, (void *) &appData.ucciAdapter, TRUE, (ArgIniType) "" },
   { "polyglotDir", ArgFilename, (void *) &appData.polyglotDir, TRUE, (ArgIniType) "" },
   { "usePolyglotBook", ArgBoolean, (void *) &appData.usePolyglotBook, TRUE, (ArgIniType) FALSE },
   { "polyglotBook", ArgFilename, (void *) &appData.polyglotBook, TRUE, (ArgIniType) "" },
-  { "defaultHashSize", ArgInt, (void *) &appData.defaultHashSize, TRUE, (ArgIniType) 64 }, 
+  { "bookDepth", ArgInt, (void *) &appData.bookDepth, TRUE, (ArgIniType) 12 },
+  { "bookVariation", ArgInt, (void *) &appData.bookStrength, TRUE, (ArgIniType) 50 },
+  { "discourageOwnBooks", ArgBoolean, (void *) &appData.defNoBook, TRUE, (ArgIniType) FALSE },
+  { "defaultHashSize", ArgInt, (void *) &appData.defaultHashSize, TRUE, (ArgIniType) 64 },
   { "defaultCacheSizeEGTB", ArgInt, (void *) &appData.defaultCacheSizeEGTB, TRUE, (ArgIniType) 4 },
   { "defaultPathEGTB", ArgFilename, (void *) &appData.defaultPathEGTB, TRUE, (ArgIniType) "c:\\egtb" },
+  { "language", ArgFilename, (void *) &appData.language, TRUE, (ArgIniType) "" },
+  { "userFileDirectory", ArgFilename, (void *) &homeDir, FALSE, (ArgIniType) installDir },
+  { "usePieceFont", ArgBoolean, (void *) &appData.useFont, TRUE, (ArgIniType) FALSE },
+  { "useBoardTexture", ArgBoolean, (void *) &appData.useBitmaps, TRUE, (ArgIniType) FALSE },
+
+  // [HGM] tournament options
+  { "tourneyFile", ArgFilename, (void *) &appData.tourneyFile, FALSE, (ArgIniType) "" },
+  { "tf", ArgFilename, (void *) &appData.tourneyFile, FALSE, INVALID },
+  { "participants", ArgString, (void *) &appData.participants, FALSE, (ArgIniType) "" },
+  { "tourneyType", ArgInt, (void *) &appData.tourneyType, FALSE, (ArgIniType) 0 },
+  { "tt", ArgInt, (void *) &appData.tourneyType, FALSE, INVALID },
+  { "tourneyCycles", ArgInt, (void *) &appData.tourneyCycles, FALSE, (ArgIniType) 1 },
+  { "cy", ArgInt, (void *) &appData.tourneyCycles, FALSE, INVALID },
+  { "results", ArgString, (void *) &appData.results, FALSE, (ArgIniType) "" },
+  { "syncAfterRound", ArgBoolean, (void *) &appData.roundSync, FALSE, (ArgIniType) FALSE },
+  { "syncAfterCycle", ArgBoolean, (void *) &appData.cycleSync, FALSE, (ArgIniType) TRUE },
+  { "seedBase", ArgInt, (void *) &appData.seedBase, FALSE, (ArgIniType) 1 },
+  { "pgnNumberTag", ArgBoolean, (void *) &appData.numberTag, TRUE, (ArgIniType) FALSE },
+  { "afterGame", ArgString, (void *) &appData.afterGame, FALSE, INVALID },
+  { "afterTourney", ArgString, (void *) &appData.afterTourney, FALSE, INVALID },
 
   /* [HGM] board-size, adjudication and misc. options */
-  { "boardWidth", ArgInt, (void *) &appData.NrFiles, TRUE, (ArgIniType) -1 },
-  { "boardHeight", ArgInt, (void *) &appData.NrRanks, TRUE, (ArgIniType) -1 },
-  { "holdingsSize", ArgInt, (void *) &appData.holdingsSize, TRUE, (ArgIniType) -1 },
+  { "oneClickMove", ArgBoolean, (void *) &appData.oneClick, TRUE, (ArgIniType) FALSE },
+  { "boardWidth", ArgInt, (void *) &appData.NrFiles, FALSE, (ArgIniType) -1 },
+  { "boardHeight", ArgInt, (void *) &appData.NrRanks, FALSE, (ArgIniType) -1 },
+  { "holdingsSize", ArgInt, (void *) &appData.holdingsSize, FALSE, (ArgIniType) -1 },
+  { "defaultMatchGames", ArgInt, (void *) &appData.defaultMatchGames, TRUE, (ArgIniType) 10 },
   { "matchPause", ArgInt, (void *) &appData.matchPause, TRUE, (ArgIniType) 10000 },
   { "pieceToCharTable", ArgString, (void *) &appData.pieceToCharTable, FALSE, INVALID },
-  { "flipBlack", ArgBoolean, (void *) &appData.upsideDown, TRUE, (ArgIniType) FALSE },
-  { "allWhite", ArgBoolean, (void *) &appData.allWhite, TRUE, (ArgIniType) FALSE },
+  { "pieceNickNames", ArgString, (void *) &appData.pieceNickNames, FALSE, INVALID },
+  { "colorNickNames", ArgString, (void *) &appData.colorNickNames, FALSE, INVALID },
+  { "flipBlack", ArgBoolean, (void *) &appData.upsideDown, FALSE, (ArgIniType) FALSE },
+  { "allWhite", ArgBoolean, (void *) &appData.allWhite, FALSE, (ArgIniType) FALSE },
   { "alphaRank", ArgBoolean, (void *) &appData.alphaRank, FALSE, (ArgIniType) FALSE },
   { "firstAlphaRank", ArgBoolean, (void *) &first.alphaRank, FALSE, (ArgIniType) FALSE },
   { "secondAlphaRank", ArgBoolean, (void *) &second.alphaRank, FALSE, (ArgIniType) FALSE },
@@ -554,6 +604,8 @@ ArgDescriptor argDescriptors[] = {
   { "trivialDraws", ArgBoolean, (void *) &appData.trivialDraws, TRUE, (ArgIniType) FALSE },
   { "ruleMoves", ArgInt, (void *) &appData.ruleMoves, TRUE, (ArgIniType) 51 },
   { "repeatsToDraw", ArgInt, (void *) &appData.drawRepeats, TRUE, (ArgIniType) 6 },
+  { "backgroundObserve", ArgBoolean, (void *) &appData.bgObserve, TRUE, (ArgIniType) FALSE },
+  { "dualBoard", ArgBoolean, (void *) &appData.dualBoard, TRUE, (ArgIniType) FALSE },
   { "autoKibitz", ArgTrue, (void *) &appData.autoKibitz, FALSE, INVALID },
   { "engineDebugOutput", ArgInt, (void *) &appData.engineComments, FALSE, (ArgIniType) 1 },
   { "userName", ArgString, (void *) &appData.userName, FALSE, INVALID },
@@ -562,18 +614,47 @@ ArgDescriptor argDescriptors[] = {
   { "smpCores", ArgInt, (void *) &appData.smpCores, TRUE, (ArgIniType) 1 },
   { "egtFormats", ArgString, (void *) &appData.egtFormats, TRUE, (ArgIniType) "" },
   { "niceEngines", ArgInt, (void *) &appData.niceEngines, TRUE, INVALID },
-  { "firstLogo", ArgFilename, (void *) &appData.firstLogo, FALSE, INVALID },
-  { "secondLogo", ArgFilename, (void *) &appData.secondLogo, FALSE, INVALID },
+  { "firstLogo", ArgFilename, (void *) &appData.firstLogo, FALSE, (ArgIniType) "" },
+  { "secondLogo", ArgFilename, (void *) &appData.secondLogo, FALSE, (ArgIniType) "" },
   { "autoLogo", ArgBoolean, (void *) &appData.autoLogo, TRUE, INVALID },
   { "firstOptions", ArgString, (void *) &appData.firstOptions, FALSE, (ArgIniType) "" },
   { "secondOptions", ArgString, (void *) &appData.secondOptions, FALSE, (ArgIniType) "" },
-  { "firstNeedsNoncompliantFEN", ArgString, (void *) &appData.fenOverride1, FALSE, (ArgIniType) "" },
-  { "secondNeedsNoncompliantFEN", ArgString, (void *) &appData.fenOverride2, FALSE, (ArgIniType) "" },
+  { "firstFeatures", ArgString, (void *) &appData.features[0], FALSE, (ArgIniType) "" },
+  { "secondFeatures", ArgString, (void *) &appData.features[1], FALSE, (ArgIniType) "" },
+  { "featureDefaults", ArgString, (void *) &appData.featureDefaults, TRUE, (ArgIniType) "" },
+  { "firstNeedsNoncompliantFEN", ArgString, (void *) &appData.fenOverride1, FALSE, (ArgIniType) NULL },
+  { "secondNeedsNoncompliantFEN", ArgString, (void *) &appData.fenOverride2, FALSE, (ArgIniType) NULL },
   { "keepAlive", ArgInt, (void *) &appData.keepAlive, FALSE, INVALID },
   { "icstype", ArgInt, (void *) &ics_type, FALSE, INVALID },
   { "forceIllegalMoves", ArgTrue, (void *) &appData.forceIllegal, FALSE, INVALID },
-
-#ifdef ZIPPY
+  { "showTargetSquares", ArgBoolean, (void *) &appData.markers, TRUE, (ArgIniType) FALSE },
+  { "firstPgnName", ArgString, (void *) &appData.pgnName[0], FALSE, (ArgIniType) "" },
+  { "fn", ArgString, (void *) &appData.pgnName[0], FALSE, INVALID },
+  { "secondPgnName", ArgString, (void *) &appData.pgnName[1], FALSE, (ArgIniType) "" },
+  { "sn", ArgString, (void *) &appData.pgnName[1], FALSE, INVALID },
+  { "absoluteAnalysisScores", ArgBoolean, (void *) &appData.whitePOV, TRUE, FALSE },
+  { "scoreWhite", ArgBoolean, (void *) &appData.scoreWhite, TRUE, FALSE },
+  { "evalZoom", ArgInt, (void *) &appData.zoom, TRUE, (ArgIniType) 1 },
+  { "evalThreshold", ArgInt, (void *) &appData.evalThreshold, TRUE, (ArgIniType) 25 },
+  { "fSAN", ArgTrue, (void *) &appData.pvSAN[0], FALSE, FALSE },
+  { "sSAN", ArgTrue, (void *) &appData.pvSAN[1], FALSE, FALSE },
+  { "pairingEngine", ArgFilename, (void *) &appData.pairingEngine, TRUE, "" },
+  { "defaultTourneyName", ArgFilename, (void *) &appData.defName, TRUE, "" },
+  { "eloThresholdAny", ArgInt, (void *) &appData.eloThreshold1, FALSE, (ArgIniType) 0 },
+  { "eloThresholdBoth", ArgInt, (void *) &appData.eloThreshold2, FALSE, (ArgIniType) 0 },
+  { "dateThreshold", ArgInt, (void *) &appData.dateThreshold, FALSE, (ArgIniType) 0 },
+  { "searchMode", ArgInt, (void *) &appData.searchMode, FALSE, (ArgIniType) 1 },
+  { "stretch", ArgInt, (void *) &appData.stretch, FALSE, (ArgIniType) 1 },
+  { "ignoreColors", ArgBoolean, (void *) &appData.ignoreColors, FALSE, FALSE },
+  { "findMirrorImage", ArgBoolean, (void *) &appData.findMirror, FALSE, FALSE },
+  { "viewer", ArgTrue, (void *) &appData.viewer, FALSE, FALSE },
+  { "viewerOptions", ArgString, (void *) &appData.viewerOptions, TRUE, (ArgIniType) "-ncp -engineOutputUp false -saveSettingsOnExit false" },
+  { "autoCopyPV", ArgBoolean, (void *) &appData.autoCopyPV, TRUE, FALSE },
+  { "topLevel", ArgBoolean, (void *) &appData.topLevel, XBOARD, (ArgIniType) TOPLEVEL },
+  { "dialogColor", ArgString, (void *) &appData.dialogColor, XBOARD, (ArgIniType) "" },
+  { "buttonColor", ArgString, (void *) &appData.buttonColor, XBOARD, (ArgIniType) "" },
+
+#if ZIPPY
   { "zippyTalk", ArgBoolean, (void *) &appData.zippyTalk, FALSE, (ArgIniType) ZIPPY_TALK },
   { "zt", ArgTrue, (void *) &appData.zippyTalk, FALSE, INVALID },
   { "xzt", ArgFalse, (void *) &appData.zippyTalk, FALSE, INVALID },
@@ -617,7 +698,9 @@ ArgDescriptor argDescriptors[] = {
   { "zippyReplyTimeout", ArgInt, (void *)&junk, FALSE, INVALID },
 #endif
   /* [HGM] options for broadcasting and time odds */
+  { "chatBoxes", ArgString, (void *) &appData.chatBoxes, !XBOARD, (ArgIniType) NULL },
   { "serverMoves", ArgString, (void *) &appData.serverMovesName, FALSE, (ArgIniType) NULL },
+  { "serverFile", ArgString, (void *) &appData.serverFileName, FALSE, (ArgIniType) NULL },
   { "suppressLoadMoves", ArgBoolean, (void *) &appData.suppressLoadMoves, FALSE, (ArgIniType) FALSE },
   { "serverPause", ArgInt, (void *) &appData.serverPause, FALSE, (ArgIniType) 15 },
   { "firstTimeOdds", ArgInt, (void *) &appData.firstTimeOdds, FALSE, (ArgIniType) 1 },
@@ -631,9 +714,10 @@ ArgDescriptor argDescriptors[] = {
   { "keepLineBreaksICS", ArgBoolean, (void *) &appData.noJoin, TRUE, INVALID },
   { "wrapContinuationSequence", ArgString, (void *) &appData.wrapContSeq, FALSE, INVALID },
   { "useInternalWrap", ArgTrue, (void *) &appData.useInternalWrap, FALSE, INVALID }, /* noJoin usurps this if set */
+  { "openCommand", ArgString, (void *) &appData.sysOpen, FALSE, "xdg-open" },
 
   // [HGM] placement: put all window layouts last in ini file, but man X,Y before all others
-  { "minX", ArgZ, (void *) &minX, FALSE, INVALID }, // [HGM] placement: to make suer auxialary windows can be placed
+  { "minX", ArgZ, (void *) &minX, FALSE, INVALID }, // [HGM] placement: to make sure auxiliary windows can be placed
   { "minY", ArgZ, (void *) &minY, FALSE, INVALID },
   { "winWidth",  ArgInt, (void *) &wpMain.width,  TRUE, INVALID }, // [HGM] placement: dummies to remember right & bottom
   { "winHeight", ArgInt, (void *) &wpMain.height, TRUE, INVALID }, //       for attaching auxiliary windows to them
@@ -688,15 +772,28 @@ ArgDescriptor argDescriptorIndirection =
 { "", ArgSettingsFilename, (void *) NULL, FALSE };
 
 void
-ExitArgError(char *msg, char *badArg)
+ExitArgError(char *msg, char *badArg, Boolean quit)
 {
   char buf[MSG_SIZ];
+  int len;
+
+  len = snprintf(buf, MSG_SIZ, msg, badArg);
+  if( (len >= MSG_SIZ) && appData.debugMode )
+    fprintf(debugFP, "ExitArgError: buffer truncated. Input: msg=%s badArg=%s\n", msg, badArg);
 
-  sprintf(buf, "%s %s", msg, badArg);
+  if(!quit) { printf(_("%s in settings file\n"), buf); return; } // DisplayError does not work yet at this stage...
   DisplayFatalError(buf, 0, 2);
   exit(2);
 }
 
+int
+ValidateInt(char *s)
+{
+  char *p = s;
+  if(*p == '-' || *p == '+') p++;
+  while(*p) if(!isdigit(*p++)) ExitArgError(_("Bad integer value %s"), s, TRUE);
+  return atoi(s);
+}
 
 char
 StringGet(void *getClosure)
@@ -725,18 +822,24 @@ Boolean
 ParseSettingsFile(char *name, char **addr)
 {
   FILE *f;
-  int ok; char buf[MSG_SIZ], fullname[MSG_SIZ];
+  int ok,len;
+  char buf[MSG_SIZ], fullname[MSG_SIZ];
+
 
   ok = MySearchPath(installDir, name, fullname);
-  if(!ok && strchr(name, '.') == NULL) { // [HGM] append default file-name extension '.ini' when needed
-    sprintf(buf, "%s.ini", name);
-    ok = MySearchPath(installDir, buf, fullname);
-  }
+  if(!ok && strchr(name, '.') == NULL)
+    { // append default file-name extension '.ini' when needed
+      len = snprintf(buf,MSG_SIZ, "%s.ini", name);
+      if( (len >= MSG_SIZ) && appData.debugMode )
+       fprintf(debugFP, "ParseSettingsFile: buffer truncated. Input: name=%s \n",name);
+
+      ok = MySearchPath(installDir, buf, fullname);
+    }
   if (ok) {
     f = fopen(fullname, "r");
     if (f != NULL) {
       if (addr != NULL) {
-           *addr = strdup(fullname);
+           ASSIGN(*addr, fullname);
       }
       ParseArgs(FileGet, f);
       fclose(f);
@@ -776,13 +879,13 @@ ParseArgs(GetFunc get, void *cl)
        ch = get(cl);
       }
       *q = NULLCHAR;
-
       for (ad = argDescriptors; ad->argName != NULL; ad++)
        if (strcmp(ad->argName, argName + 1) == 0) break;
-
-      if (ad->argName == NULL)
-       ExitArgError("Unrecognized argument", argName);
-
+      if (ad->argName == NULL) {
+       ExitArgError(_("Unrecognized argument %s"), argName, get != &FileGet); // [HGM] make unknown argument non-fatal
+       while (ch != '\n' && ch != NULLCHAR) ch = get(cl); // but skip rest of line it is on
+       continue; // so that when it is in a settings file, it is the only setting that will be purged from it
+      }
     } else if (ch == '@') {
       /* Indirection file */
       ad = &argDescriptorIndirection;
@@ -790,9 +893,13 @@ ParseArgs(GetFunc get, void *cl)
     } else {
       /* Positional argument */
       ad = &argDescriptors[posarg++];
-      strcpy(argName, ad->argName);
+      strncpy(argName, ad->argName,sizeof(argName)/sizeof(argName[0]));
     }
 
+    if (ad->argType == ArgTwo) { // [HGM] kludgey arg type, not suitable for saving
+      *(Boolean *) ad->argLoc = 2;
+      continue;
+    }
     if (ad->argType == ArgTrue) {
       *(Boolean *) ad->argLoc = TRUE;
       continue;
@@ -804,7 +911,7 @@ ParseArgs(GetFunc get, void *cl)
 
     while (ch == ' ' || ch == '=' || ch == ':' || ch == '\t') ch = get(cl);
     if (ch == NULLCHAR || ch == '\n') {
-      ExitArgError("No value provided for argument", argName);
+      ExitArgError(_("No value provided for argument %s"), argName, TRUE);
     }
     q = argValue;
     if (ch == '{') {
@@ -817,7 +924,7 @@ ParseArgs(GetFunc get, void *cl)
        case NULLCHAR:
          start = NULLCHAR;
          break;
-         
+
        case '}':
          ch = get(cl);
          start = NULLCHAR;
@@ -828,7 +935,7 @@ ParseArgs(GetFunc get, void *cl)
          ch = get(cl);
          break;
        }
-      }          
+      }
     } else if (ch == '\'' || ch == '"') {
       // Quoting with ' ' or " ", with \ as escape character.
       // Inconvenient for long strings that may contain Windows filenames.
@@ -864,7 +971,7 @@ ParseArgs(GetFunc get, void *cl)
          ch = get(cl);
          switch (ch) {
          case NULLCHAR:
-           ExitArgError("Incomplete \\ escape in value for", argName);
+           ExitArgError(_("Incomplete \\ escape in value for %s"), argName, TRUE);
            break;
          case 'n':
            *q++ = '\n';
@@ -917,20 +1024,20 @@ ParseArgs(GetFunc get, void *cl)
 
     switch (ad->argType) {
     case ArgInt:
-      *(int *) ad->argLoc = atoi(argValue);
+      *(int *) ad->argLoc = ValidateInt(argValue);
       break;
 
     case ArgX:
-      *(int *) ad->argLoc = atoi(argValue) + wpMain.x; // [HGM] placement: translate stored relative to absolute 
+      *(int *) ad->argLoc = ValidateInt(argValue) + wpMain.x; // [HGM] placement: translate stored relative to absolute
       break;
 
     case ArgY:
-      *(int *) ad->argLoc = atoi(argValue) + wpMain.y; // (this is really kludgey, it should be done where used...)
+      *(int *) ad->argLoc = ValidateInt(argValue) + wpMain.y; // (this is really kludgey, it should be done where used...)
       break;
 
     case ArgZ:
-      *(int *) ad->argLoc = atoi(argValue);
-      EnsureOnScreen(&wpMain.x, &wpMain.y, minX, minY); 
+      *(int *) ad->argLoc = ValidateInt(argValue);
+      EnsureOnScreen(&wpMain.x, &wpMain.y, minX, minY);
       break;
 
     case ArgFloat:
@@ -939,7 +1046,7 @@ ParseArgs(GetFunc get, void *cl)
 
     case ArgString:
     case ArgFilename:
-      *(char **) ad->argLoc = strdup(argValue);
+      ASSIGN(*(char **) ad->argLoc, argValue);
       break;
 
     case ArgSettingsFilename:
@@ -948,7 +1055,7 @@ ParseArgs(GetFunc get, void *cl)
        } else {
          if (ad->argLoc != NULL) {
          } else {
-           ExitArgError("Failed to open indirection file", argValue);
+           ExitArgError(_("Failed to open indirection file %s"), argValue, TRUE);
          }
        }
       }
@@ -965,13 +1072,13 @@ ParseArgs(GetFunc get, void *cl)
        *(Boolean *) ad->argLoc = FALSE;
        break;
       default:
-       ExitArgError("Unrecognized boolean argument value", argValue);
+       ExitArgError(_("Unrecognized boolean argument value %s"), argValue, TRUE);
        break;
       }
       break;
 
     case ArgColor:
-      ParseColor((int)ad->argLoc, argValue);
+      ParseColor((int)(intptr_t)ad->argLoc, argValue);
       break;
 
     case ArgAttribs: {
@@ -979,13 +1086,13 @@ ParseArgs(GetFunc get, void *cl)
        ParseTextAttribs(cc, argValue); // [HGM] wrapper for platform independency
       }
       break;
-      
+
     case ArgBoardSize:
       ParseBoardSize(ad->argLoc, argValue);
       break;
 
     case ArgFont:
-      ParseFont(argValue, (int)ad->argLoc);
+      ParseFont(argValue, (int)(intptr_t)ad->argLoc);
       break;
 
     case ArgCommSettings:
@@ -993,14 +1100,27 @@ ParseArgs(GetFunc get, void *cl)
       break;
 
     case ArgNone:
-      ExitArgError("Unrecognized argument", argValue);
+      ExitArgError(_("Unrecognized argument %s"), argValue, TRUE);
       break;
+    case ArgTwo:
     case ArgTrue:
     case ArgFalse: ;
     }
   }
 }
 
+void
+ParseArgsFromString(char *p)
+{
+    ParseArgs(StringGet, &p);
+}
+
+void
+ParseArgsFromFile(FILE *f)
+{
+    ParseArgs(FileGet, f);
+}
+
 void
 ParseIcsTextMenu(char *icsTextMenuString)
 {
@@ -1058,7 +1178,7 @@ ParseIcsTextMenu(char *icsTextMenuString)
       p = t + 1;
     }
     e++;
-  } 
+  }
 }
 
 void
@@ -1079,26 +1199,28 @@ SetDefaultsFromList()
     if(argDescriptors[i].defaultValue != INVALID)
       switch(argDescriptors[i].argType) {
         case ArgBoolean:
+        case ArgTwo:
         case ArgTrue:
         case ArgFalse:
-          *(Boolean *) argDescriptors[i].argLoc = (int)argDescriptors[i].defaultValue;
+          *(Boolean *) argDescriptors[i].argLoc = (int)(intptr_t)argDescriptors[i].defaultValue;
           break;
         case ArgInt:
         case ArgX:
         case ArgY:
         case ArgZ:
-          *(int *) argDescriptors[i].argLoc = (int)argDescriptors[i].defaultValue;
+          *(int *) argDescriptors[i].argLoc = (int)(intptr_t)argDescriptors[i].defaultValue;
           break;
         case ArgString:
         case ArgFilename:
         case ArgSettingsFilename:
-          *(char **) argDescriptors[i].argLoc = (char *)argDescriptors[i].defaultValue;
+          if((char *)argDescriptors[i].defaultValue)
+          *(char **) argDescriptors[i].argLoc = strdup((char *)argDescriptors[i].defaultValue);
           break;
         case ArgBoardSize:
-          *(int *) argDescriptors[i].argLoc = (int)argDescriptors[i].defaultValue;
+          *(int *) argDescriptors[i].argLoc = (int)(intptr_t)argDescriptors[i].defaultValue;
           break;
         case ArgColor:
-          ParseColor((int)argDescriptors[i].argLoc, (char*)argDescriptors[i].defaultValue);
+          ParseColor((int)(intptr_t)argDescriptors[i].argLoc, (char*)argDescriptors[i].defaultValue);
           break;
         case ArgFloat: // floats cannot be casted to int without precision loss
         default: ; // some arg types cannot be initialized through table
@@ -1122,6 +1244,7 @@ InitAppData(char *lpCmdLine)
 
   // float: casting to int is not harmless, so default cannot be contained in table
   appData.timeDelay = TIME_DELAY;
+  appData.timeIncrement = TIME_INCREMENT;
 
   // some complex, platform-dependent stuff that could not be handled from table
   SetDefaultTextAttribs();
@@ -1134,6 +1257,8 @@ InitAppData(char *lpCmdLine)
   /* Parse command line */
   ParseArgs(StringGet, &lpCmdLine);
 
+  if(appData.viewer && appData.viewerOptions[0]) ParseArgsFromString(appData.viewerOptions);
+
   /* [HGM] make sure board size is acceptable */
   if(appData.NrFiles > BOARD_FILES ||
      appData.NrRanks > BOARD_RANKS   )
@@ -1149,22 +1274,34 @@ InitAppData(char *lpCmdLine)
       char *p = StrStr(appData.firstChessProgram, "WBopt");
       static char *f = "first";
       char buf[MSG_SIZ], *q = buf;
-      if(p != NULL) { // engine command line contains WinBoard options
-          sprintf(buf, p+6, f, f, f, f, f, f, f, f, f, f); // replace %s in them by "first"
+      int len;
+
+      if(p != NULL)
+       { // engine command line contains WinBoard options
+          len = snprintf(buf, MSG_SIZ, p+6, f, f, f, f, f, f, f, f, f, f); // replace %s in them by "first"
+         if( (len >= MSG_SIZ) && appData.debugMode )
+           fprintf(debugFP, "InitAppData: buffer truncated.\n");
+
           ParseArgs(StringGet, &q);
           p[-1] = 0; // cut them offengine command line
-      }
+       }
   }
   // now do same for second chess program
   if(appData.secondChessProgram != NULL) {
       char *p = StrStr(appData.secondChessProgram, "WBopt");
       static char *s = "second";
       char buf[MSG_SIZ], *q = buf;
-      if(p != NULL) { // engine command line contains WinBoard options
-          sprintf(buf, p+6, s, s, s, s, s, s, s, s, s, s); // replace %s in them by "first"
+      int len;
+
+      if(p != NULL)
+       { // engine command line contains WinBoard options
+          len = snprintf(buf,MSG_SIZ, p+6, s, s, s, s, s, s, s, s, s, s); // replace %s in them by "first"
+         if( (len >= MSG_SIZ) && appData.debugMode )
+           fprintf(debugFP, "InitAppData: buffer truncated.\n");
+
           ParseArgs(StringGet, &q);
           p[-1] = 0; // cut them offengine command line
-      }
+       }
   }
 
   /* Propagate options that affect others */
@@ -1177,7 +1314,7 @@ InitAppData(char *lpCmdLine)
   if ((!appData.noChessProgram && !chessProgram && !appData.icsActive) ||
       (appData.icsActive && *appData.icsHost == NULLCHAR) ||
       (chessProgram && (*appData.firstChessProgram == NULLCHAR ||
-                        *appData.secondChessProgram == NULLCHAR))) 
+                        *appData.secondChessProgram == NULLCHAR)))
                PopUpStartupDialog();
 
   /* Make sure save files land in the right (?) directory */
@@ -1299,7 +1436,7 @@ SaveSettings(char* name)
       fprintf(f, OPTCHAR "%s" SEPCHAR "%g\n", ad->argName, *(float *)ad->argLoc);
       break;
     case ArgBoolean:
-      fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, 
+      fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName,
        (*(Boolean *)ad->argLoc) ? "true" : "false");
       break;
     case ArgTrue:
@@ -1330,6 +1467,7 @@ SaveSettings(char* name)
       break;
     case ArgCommSettings:
       PrintCommPortSettings(f, ad->argName);
+    case ArgTwo:
     case ArgNone:
     case ArgSettingsFilename: ;
     }
@@ -1342,6 +1480,7 @@ GetArgValue(char *name)
 { // retrieve (as text) current value of string or int argument given by name
   // (this is used for maing the values available in the adapter command)
   ArgDescriptor *ad;
+  int len;
 
   for (ad = argDescriptors; ad->argName != NULL; ad++)
     if (strcmp(ad->argName, name) == 0) break;
@@ -1351,13 +1490,20 @@ GetArgValue(char *name)
   switch(ad->argType) {
     case ArgString:
     case ArgFilename:
-      strcpy(name, *(char**) ad->argLoc);
+      strncpy(name, *(char**) ad->argLoc, MSG_SIZ);
+
       return TRUE;
     case ArgInt:
-      sprintf(name, "%d", *(int*) ad->argLoc);
+      len = snprintf(name, MSG_SIZ, "%d", *(int*) ad->argLoc);
+      if( (len >= MSG_SIZ) && appData.debugMode )
+       fprintf(debugFP, "GetArgValue: buffer truncated.\n");
+
       return TRUE;
     case ArgBoolean:
-      sprintf(name, "%s", *(Boolean*) ad->argLoc ? "true" : "false");
+      len = snprintf(name, MSG_SIZ, "%s", *(Boolean*) ad->argLoc ? "true" : "false");
+      if( (len >= MSG_SIZ) && appData.debugMode )
+       fprintf(debugFP, "GetArgValue: buffer truncated.\n");
+
       return TRUE;
     default: ;
   }