A better and more flexible way of invoking Polyglot
authorH.G. Muller <h.g.muller@hccnet.nl>
Sun, 6 Dec 2009 19:56:40 +0000 (11:56 -0800)
committerArun Persaud <arun@nubati.net>
Sun, 6 Dec 2009 19:56:40 +0000 (11:56 -0800)
rewrote uci.c. No more use of temporary files, all data passed through the engine command line. Adds a new command-line option -adapterCommand for this.

args.h
backend.h
common.h
uci.c

diff --git a/args.h b/args.h
index a916780..0b021ac 100644 (file)
--- a/args.h
+++ b/args.h
@@ -529,6 +529,7 @@ ArgDescriptor argDescriptors[] = {
   { "secondHasOwnBookUCI", ArgBoolean, (void *) &appData.secondHasOwnBookUCI, FALSE, (ArgIniType) TRUE },
   { "sNoOwnBookUCI", ArgFalse, (void *) &appData.secondHasOwnBookUCI, FALSE, INVALID },
   { "secondXBook", ArgFalse, (void *) &appData.secondHasOwnBookUCI, 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" },
   { "polyglotDir", ArgFilename, (void *) &appData.polyglotDir, TRUE, (ArgIniType) "" },
   { "usePolyglotBook", ArgBoolean, (void *) &appData.usePolyglotBook, TRUE, (ArgIniType) FALSE },
   { "polyglotBook", ArgFilename, (void *) &appData.polyglotBook, TRUE, (ArgIniType) "" },
   { "polyglotDir", ArgFilename, (void *) &appData.polyglotDir, TRUE, (ArgIniType) "" },
   { "usePolyglotBook", ArgBoolean, (void *) &appData.usePolyglotBook, TRUE, (ArgIniType) FALSE },
   { "polyglotBook", ArgFilename, (void *) &appData.polyglotBook, TRUE, (ArgIniType) "" },
@@ -1335,3 +1336,31 @@ SaveSettings(char* name)
   }
   fclose(f);
 }
   }
   fclose(f);
 }
+
+Boolean
+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;
+
+  for (ad = argDescriptors; ad->argName != NULL; ad++)
+    if (strcmp(ad->argName, name) == 0) break;
+
+  if (ad->argName == NULL) return FALSE;
+
+  switch(ad->argType) {
+    case ArgString:
+    case ArgFilename:
+      strcpy(name, *(char**) ad->argLoc);
+      return TRUE;
+    case ArgInt:
+      sprintf(name, "%d", *(int*) ad->argLoc);
+      return TRUE;
+    case ArgBoolean:
+      sprintf(name, "%s", *(Boolean*) ad->argLoc ? "true" : "false");
+      return TRUE;
+    default: ;
+  }
+
+  return FALSE;
+}
index c2997f4..c0cfbd3 100644 (file)
--- a/backend.h
+++ b/backend.h
@@ -204,7 +204,7 @@ VariantClass StringToVariant P((char *e));
 double u64ToDouble P((u64 value));
 void OutputChatMessage P((int partner, char *mess));
 void EditPositionDone P((Boolean fakeRights));
 double u64ToDouble P((u64 value));
 void OutputChatMessage P((int partner, char *mess));
 void EditPositionDone P((Boolean fakeRights));
-
+Boolean GetArgValue P((char *name));
 
 char *StrStr P((char *string, char *match));
 char *StrCaseStr P((char *string, char *match));
 
 char *StrStr P((char *string, char *match));
 char *StrCaseStr P((char *string, char *match));
index e0b6633..cd21c7e 100644 (file)
--- a/common.h
+++ b/common.h
@@ -557,6 +557,7 @@ typedef struct {
     Boolean secondIsUCI;
     Boolean firstHasOwnBookUCI;
     Boolean secondHasOwnBookUCI;
     Boolean secondIsUCI;
     Boolean firstHasOwnBookUCI;
     Boolean secondHasOwnBookUCI;
+    char * adapterCommand;
     char * polyglotDir;
     Boolean usePolyglotBook;
     char * polyglotBook;
     char * polyglotDir;
     Boolean usePolyglotBook;
     char * polyglotBook;
diff --git a/uci.c b/uci.c
index d0f76c4..0885ee0 100644 (file)
--- a/uci.c
+++ b/uci.c
   #include <malloc.h>
 #endif
 
   #include <malloc.h>
 #endif
 
-#ifdef WIN32
-// [HGM] this was probably a Windows-specific constant. Needs to be defined here now I
-//       threw out the Windows-specific includes (winboard.h etc.). 100 seems enough.
-#include <windows.h>
-#define SLASH_CHAR "\\"
-#else
-#define MAX_PATH 100
-#define SLASH_CHAR "/"
-#endif
-
 #include "common.h"
 #include "backend.h"
 
 #include "common.h"
 #include "backend.h"
 
-#define INIFILE_PREFIX      "polyglot_"
-#define INIFILE_SUFFIX_1ST  "1st"
-#define INIFILE_SUFFIX_2ND  "2nd"
-#define INIFILE_EXT         ".ini"
-
-
-static const char * GetIniFilename( ChessProgramState * cps )
-{
-    return cps == &first ? INIFILE_PREFIX INIFILE_SUFFIX_1ST INIFILE_EXT : INIFILE_PREFIX INIFILE_SUFFIX_2ND INIFILE_EXT;
- }
 
 void InitEngineUCI( const char * iniDir, ChessProgramState * cps )
 
 void InitEngineUCI( const char * iniDir, ChessProgramState * cps )
-{
+{   // replace engine command line by adapter command with expanded meta-symbols
     if( cps->isUCI ) {
     if( cps->isUCI ) {
-        const char * iniFileName = GetIniFilename( cps );
-        char polyglotIniFile[ MAX_PATH ];
-        FILE * f;
-
-        /* Build name of initialization file */
-        if( strchr( iniDir, ' ' ) != NULL ) {
-            char iniDirShort[ MAX_PATH ];
-#ifdef WIN32
-            GetShortPathName( iniDir, iniDirShort, sizeof(iniDirShort) );
-
-            strcpy( polyglotIniFile, iniDirShort );
-#else
-           // [HGM] UCI: not sure if this works, but GetShortPathName seems Windows pecific
-           // and names with spaces in it do not work in xboard in many places, so ignore
-            strcpy( polyglotIniFile, iniDir );
-#endif
-        }
-        else {
-            strcpy( polyglotIniFile, iniDir );
-        }
-        
-        strcat( polyglotIniFile, SLASH_CHAR );
-        strcat( polyglotIniFile, iniFileName );
-
-        /* Create initialization file */
-        f = fopen( polyglotIniFile, "w" );
-
-        if( f != NULL ) {
-            fprintf( f, "[Polyglot]\n" );
-
-            if( cps->dir != 0 && strlen(cps->dir) > 0 ) {
-                fprintf( f, "EngineDir = %s\n", cps->dir );
+        char *p, *q;
+        char polyglotCommand[MSG_SIZ];
+
+        p = appData.adapterCommand;
+        q = polyglotCommand;
+        while(*p) {
+          if(*p == '\\') p++; else
+          if(*p == '%') { // substitute marker
+            char argName[MSG_SIZ], *s = argName;
+            if(*++p == '%') { // second %, expand as f or s in option name (e.g. %%cp -> fcp)
+              *s++ = cps == &first ? 'f' : 's';
+              p++;
             }
             }
-
-            if( cps->program != 0 && strlen(cps->program) > 0 ) {
-                fprintf( f, "EngineCommand = %s\n", cps->program );
-            }
-
-            fprintf( f, "Book = %s\n", appData.usePolyglotBook ? "true" : "false" );
-            fprintf( f, "BookFile = %s\n", appData.polyglotBook );
-        
-            fprintf( f, "[Engine]\n" );
-            fprintf( f, "Hash = %d\n", appData.defaultHashSize );
-
-            fprintf( f, "NalimovPath = %s\n", appData.defaultPathEGTB );
-            fprintf( f, "NalimovCache = %d\n", appData.defaultCacheSizeEGTB );
-
-            fprintf( f, "OwnBook = %s\n", cps->hasOwnBookUCI ? "true" : "false" );
-
-            fclose( f );
-
-            /* Replace program with properly configured Polyglot */
-            cps->dir = appData.polyglotDir;
-            cps->program = (char *) malloc( strlen(polyglotIniFile) + 32 );
-            strcpy( cps->program, "polyglot " );
-            strcat( cps->program, polyglotIniFile );
+            while(*p != ' ' && *p) *s++ = *p++; // copy option name
+            *s = NULLCHAR;
+            if(GetArgValue(argName)) { // look up value of option with this name
+              s = argName;
+              while(*s) *q++ = *s++;
+            } else DisplayFatalError("Bad adapter command", 0, 1);
+            continue;
+          }
+          if(*p) *q++ = *p++;
         }
         }
+        *q = NULLCHAR;
+        cps->program = StrSave(polyglotCommand);
+        cps->dir = appData.polyglotDir;
     }
 }
     }
 }