Add forgotten files 1.4.70b
[polyglot.git] / main.c
diff --git a/main.c b/main.c
index 70c5917..e06d59c 100644 (file)
--- a/main.c
+++ b/main.c
-\r
-// main.c\r
-\r
-// includes\r
-\r
-#include <errno.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-#include "attack.h"\r
-#include "board.h"\r
-#include "book.h"\r
-#include "book_make.h"\r
-#include "book_merge.h"\r
-#include "engine.h"\r
-#include "epd.h"\r
-#include "fen.h"\r
-#include "gui.h"\r
-#include "hash.h"\r
-#include "list.h"\r
-#include "main.h"\r
-#include "mainloop.h"\r
-#include "move.h"\r
-#include "move_gen.h"\r
-#include "option.h"\r
-#include "piece.h"\r
-#include "search.h"\r
-#include "square.h"\r
-#include "uci.h"\r
-#include "util.h"\r
-#include "xboard2uci.h"\r
-#include "uci2uci.h"\r
-\r
-// constants\r
-\r
-\r
-static const char * const Version = "1.4.32b";\r
-static const char * const HelpMessage = "\\r
-SYNTAX\n\\r
-* polyglot [configfile]\n\\r
-* polyglot -ec enginecommand\n\\r
-* polyglot make-book [-pgn inputfile] [-bin outputfile] [-max-ply ply] [-min-game games] [-min-score score] [-only-white] [-only-black] [-uniform]\n\\r
-* polyglot merge-book -in1 inputfile1 -in2 inputfile2 [-out outputfile]\n\\r
-* polyglot info-book [-bin inputfile] [-exact]\n\\r
-* polyglot dumb-book [-bin inputfile] -color color [-out outputfile]\n\\r
-* polyglot [configfile] epd-test [-epd inputfile] [-min-depth depth] [-max-depth depth] [-min-time time] [-max-time time] [-depth-delta delta]\n\\r
-* polyglot perft [-fen fen] [-max-depth depth]\\r
-";\r
-\r
-static const int SearchDepth = 63;\r
-static const double SearchTime = 3600.0;\r
-static const int StringSize = 4096;\r
-\r
-// variables\r
-\r
-static bool Init;\r
-\r
-// prototypes\r
-\r
-static void parse_option ();\r
-static void init_book ();\r
-static bool parse_line   (char line[], char * * name_ptr, char * * value_ptr);\r
-static void stop_search  ();\r
-\r
-// functions\r
-\r
-// main()\r
-\r
-int main(int argc, char * argv[]) {\r
-\r
-    if(!DEBUG){\r
-        printf("PolyGlot %s by Fabien Letouzey.\n",Version);\r
-    }else{\r
-        printf("PolyGlot %s by Fabien Letouzey (debug build).\n",Version);\r
-    }\r
-\r
-    if(argc>=2 && ((my_string_case_equal(argv[1],"help")) || (my_string_case_equal(argv[1],"-help")) || (my_string_case_equal(argv[1],"--help")) ||  (my_string_case_equal(argv[1],"-h")) ||  my_string_case_equal(argv[1],"/?"))){\r
-        printf("%s\n",HelpMessage);\r
-        return EXIT_SUCCESS;\r
-    }\r
-\r
-   // init\r
-\r
-    Init = FALSE;\r
-\r
-    util_init();\r
-    option_init();\r
-    \r
-    square_init();\r
-    piece_init();\r
-    attack_init();\r
-    \r
-    hash_init();\r
-    \r
-    my_random_init();\r
-\r
-        // build book\r
-    \r
-    if (argc >= 2 && my_string_equal(argv[1],"make-book")) {\r
-        book_make(argc,argv);\r
-        return EXIT_SUCCESS;\r
-    }\r
-    \r
-    if (argc >= 2 && my_string_equal(argv[1],"merge-book")) {\r
-        book_merge(argc,argv);\r
-        return EXIT_SUCCESS;\r
-    }\r
-\r
-       if (argc >= 2 && my_string_equal(argv[1],"merge-book")) {\r
-      book_merge(argc,argv);\r
-      return EXIT_SUCCESS;\r
-   }\r
-\r
-   if (argc >= 2 && my_string_equal(argv[1],"dump-book")) {\r
-      book_dump(argc,argv);\r
-      return EXIT_SUCCESS;\r
-   }\r
-\r
-   if (argc >= 2 && my_string_equal(argv[1],"info-book")) {\r
-      book_info(argc,argv);\r
-      return EXIT_SUCCESS;\r
-   }\r
-    \r
-    if (argc >= 2 && my_string_equal(argv[1],"perft")) {\r
-        do_perft(argc,argv);\r
-        return EXIT_SUCCESS;\r
-    }\r
-    \r
-    if (argc >= 3 && my_string_equal(argv[1],"-ec")) {\r
-        option_set("EngineCommand",argv[2]);\r
-        engine_open(Engine);\r
-        if(!engine_active(Engine)){\r
-            my_fatal("Could not start \"%s\"\n",option_get("EngineCommand"));\r
-        }\r
-        Init=TRUE;\r
-        gui_init(GUI);\r
-        uci_open(Uci,Engine);\r
-        if (my_string_equal(option_get_string("EngineName"),"<empty>")) {\r
-            option_set("EngineName",Uci->name);\r
-        }\r
-        mainloop();\r
-        return EXIT_SUCCESS; \r
-    }\r
-    \r
-        // read options\r
-    \r
-    if (argc == 2) option_set("OptionFile",argv[1]); // HACK for compatibility\r
-\r
-    parse_option(); // HACK: also launches the engine\r
-    \r
-        // EPD test\r
-    \r
-    if (argc >= 2 && my_string_equal(argv[1],"epd-test")){\r
-        epd_test(argc,argv);\r
-        return EXIT_SUCCESS;\r
-    }else if(argc >= 3 && my_string_equal(argv[2],"epd-test")){\r
-        epd_test(argc-1,argv+1);\r
-        return EXIT_SUCCESS;\r
-    }\r
-    \r
-    if (argc >= 3) my_fatal("Too many arguments\n");\r
-\r
-\r
-    init_book();\r
-    gui_init(GUI);\r
-    mainloop();\r
-    return EXIT_SUCCESS; \r
-}\r
-\r
-// polyglot_set_option\r
-\r
-void polyglot_set_option(char *name, char *value){ // this must be cleaned up!\r
-    option_set(name,value);\r
-    if(option_get_bool("Book")&&(my_string_case_equal(name,"BookFile")||my_string_case_equal(name,"Book"))){\r
-        my_log("POLYGLOT *** SETTING BOOK ***\n");\r
-        my_log("POLYGLOT BOOK \"%s\"\n",option_get_string("BookFile"));\r
-        book_close();\r
-        book_clear();\r
-        book_open(option_get_string("BookFile"));\r
-        if(!book_is_open()){\r
-            my_log("POLYGLOT Unable to open book \"%s\"\n",option_get_string("BookFile"));\r
-        }\r
-    }else if(option_get_bool("Log")&&(my_string_case_equal(name,"LogFile") ||my_string_case_equal(name,"Log"))){\r
-        my_log("POLYGLOT *** SETTING LOGFILE ***\n");\r
-        my_log("POLYGLOT LOGFILE \"%s\"\n",option_get_string("LogFile"));\r
-        my_log_close();\r
-        my_log_open(option_get_string("LogFile"));\r
-    }else if(option_get_bool("UseNice") &&(my_string_case_equal(name,"NiceValue")||my_string_case_equal(name,"UseNice"))){\r
-        my_log("POLYGLOT Adjust Engine Piority\n");\r
-        engine_set_nice_value(Engine,atoi(option_get_string("NiceValue")));\r
-    }else if(my_string_case_equal(name,"Book") && !option_get_bool("Book")){\r
-        book_close();\r
-        book_clear();\r
-    }else if(my_string_case_equal(name,"UseNice") && !option_get_bool("UseNice")){\r
-        my_log("POLYGLOT Adjust Engine Piority\n");\r
-        engine_set_nice_value(Engine,0);\r
-    }else if(my_string_case_equal(name,"Log") && !option_get_bool("Log")){\r
-        my_log("POLYGLOT QUIT LOGGING\n");\r
-        my_log_close();\r
-    }\r
-}\r
-\r
-\r
-// init_book()\r
-\r
-static void init_book(){\r
-    book_clear();\r
-    if (option_get_bool("Book")){\r
-        my_log("POLYGLOT *** SETTING BOOK ***\n");\r
-        my_log("POLYGLOT BOOK \"%s\"\n",option_get_string("BookFile"));\r
-        book_open(option_get_string("BookFile"));\r
-        if(!book_is_open()){\r
-            my_log("POLYGLOT Unable to open book \"%s\"\n",\r
-                   option_get_string("BookFile"));\r
-        }\r
-    }\r
-}\r
-\r
-// parse_option()\r
-\r
-static void parse_option() {\r
-\r
-    const char * file_name;\r
-    FILE * file;\r
-    char line[256];\r
-    char * name, * value;\r
-    file_name = option_get_string("OptionFile");\r
-    \r
-    file = fopen(file_name,"r");\r
-    if (file == NULL) {\r
-        my_fatal("Can't open file \"%s\": %s\n",file_name,strerror(errno));\r
-    }\r
-    \r
-        // PolyGlot options (assumed first)\r
-    \r
-   while (TRUE) {\r
-       \r
-       if (!my_file_read_line(file,line,256)) {\r
-           my_fatal("parse_option(): missing [Engine] section\n");\r
-       }\r
-       \r
-       if (my_string_case_equal(line,"[engine]")) break;\r
-       \r
-       if (parse_line(line,&name,&value)) {\r
-           option_set(name,value);\r
-           option_set_default(name,value);\r
-       }\r
-   }\r
-   \r
-   if (option_get_bool("Log")) {\r
-       my_log_open(option_get_string("LogFile"));\r
-   }\r
-   \r
-   if(!DEBUG){\r
-       my_log("PolyGlot %s by Fabien Letouzey\n",Version);\r
-   }else{\r
-       my_log("PolyGlot %s by Fabien Letouzey (debug build)\n",Version);\r
-   }\r
-\r
-   my_log("POLYGLOT *** START ***\n");\r
-   my_log("POLYGLOT INI file \"%s\"\n",file_name);\r
-   engine_open(Engine);\r
-   if(!engine_active(Engine)){\r
-       my_fatal("Could not start \"%s\"\n",option_get("EngineCommand"));\r
-   }\r
-\r
-   if (option_get_bool("UCI")) {\r
-       my_log("POLYGLOT *** Switching to UCI mode ***\n");\r
-   }\r
-   uci_open(Uci,Engine);\r
-   Init = TRUE;\r
-   while (my_file_read_line(file,line,256)) {\r
-       if (line[0] == '[') my_fatal("parse_option(): unknown section %s\n",line);\r
-       if (parse_line(line,&name,&value)) {\r
-           uci_send_option(Uci,name,"%s",value);\r
-               //to get a decent display in winboard_x we need to now if an engine really is doing multipv analysis\r
-               // "multipv 1" in the pv is meaningless,f.i. toga sends that all the time\r
-               //therefore check if MultiPV is set to a decent value in the polyglot ini file\r
-           if(my_string_case_equal(name,"MultiPV") && atoi(value)>1)  Uci->multipv_mode=TRUE;\r
-       }\r
-   }\r
-   if (my_string_equal(option_get_string("EngineName"),"<empty>")) {\r
-       option_set("EngineName",Uci->name);\r
-   }\r
-   \r
-   fclose(file);\r
-}\r
-\r
-// parse_line()\r
-\r
-static bool parse_line(char line[], char * * name_ptr, char * * value_ptr) {\r
-    \r
-    char * ptr;\r
-    char * name, * value;\r
-    \r
-    ASSERT(line!=NULL);\r
-    ASSERT(name_ptr!=NULL);\r
-    ASSERT(value_ptr!=NULL);\r
-    \r
-        // remove comments\r
-    \r
-    ptr = strchr(line,';');\r
-    if (ptr != NULL) *ptr = '\0';\r
-    \r
-    ptr = strchr(line,'#');\r
-    if (ptr != NULL) *ptr = '\0';\r
-    \r
-        // split at '='\r
-    \r
-    ptr = strchr(line,'=');\r
-    if (ptr == NULL) return FALSE;\r
-    \r
-    name = line;\r
-    value = ptr+1;\r
-   \r
-        // cleanup name\r
-    \r
-    while (*name == ' ') name++; // remove leading spaces\r
-    \r
-    while (ptr > name && ptr[-1] == ' ') ptr--; // remove trailing spaces\r
-    *ptr = '\0';\r
-    \r
-    if (*name == '\0') return FALSE;\r
-    \r
-        // cleanup value\r
-    \r
-    ptr = &value[strlen(value)]; // pointer to string terminator\r
-    \r
-    while (*value == ' ') value++; // remove leading spaces\r
-    \r
-    while (ptr > value && ptr[-1] == ' ') ptr--; // remove trailing spaces\r
-    *ptr = '\0';\r
-    \r
-    if (*value == '\0') return FALSE;\r
-   \r
-        // end\r
-    \r
-    *name_ptr = name;\r
-    *value_ptr = value;\r
-    \r
-    return TRUE;\r
-}\r
-\r
-// quit()\r
-\r
-void quit() {\r
-\r
-    my_log("POLYGLOT *** QUIT ***\n");\r
-    \r
-    if (Init) {\r
-        \r
-        stop_search();\r
-        engine_send(Engine,"quit");\r
-        my_log("POLYGLOT Closing engine\n");\r
-        engine_close(Engine);\r
-        \r
-    }\r
-    my_log("POLYGLOT Calling exit\n");\r
-    exit(EXIT_SUCCESS);\r
-}\r
-\r
-// stop_search()\r
-\r
-static void stop_search() {\r
-    \r
-    if (Init && Uci->searching) {\r
-        \r
-        ASSERT(Uci->searching);\r
-        ASSERT(Uci->pending_nb>=1);\r
-        \r
-        my_log("POLYGLOT STOP SEARCH\n");\r
-        \r
-        if (option_get_bool("SyncStop")) {\r
-            uci_send_stop_sync(Uci);\r
-        } else {\r
-            uci_send_stop(Uci);\r
-        }\r
-    }\r
-}\r
-\r
-\r
-// end of main.cpp\r
-\r
+
+// main.c
+
+// includes
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "attack.h"
+#include "board.h"
+#include "book.h"
+#include "book_make.h"
+#include "book_merge.h"
+#include "engine.h"
+#include "epd.h"
+#include "fen.h"
+#include "gui.h"
+#include "hash.h"
+#include "list.h"
+#include "main.h"
+#include "mainloop.h"
+#include "move.h"
+#include "move_gen.h"
+#include "option.h"
+#include "piece.h"
+#include "search.h"
+#include "square.h"
+#include "uci.h"
+#include "util.h"
+#include "xboard2uci.h"
+#include "uci2uci.h"
+#include "ini.h"
+#include "util.h"
+
+
+// constants
+
+
+static const char * const Version = "1.4.70b";
+static const char * const HelpMessage = "\
+SYNTAX\n\
+* polyglot [configfile] [-noini] [-ec engine] [-ed enginedirectory] [-en enginename] [-log true/false] [-lf logfile] [-pg <name>=<value>]* [-uci <name>=<value>]*\n\
+* polyglot make-book [-pgn inputfile] [-bin outputfile] [-max-ply ply] [-min-game games] [-min-score score] [-only-white] [-only-black] [-uniform]\n\
+* polyglot merge-book -in1 inputfile1 -in2 inputfile2 [-out outputfile]\n\
+* polyglot info-book [-bin inputfile] [-exact]\n\
+* polyglot dump-book [-bin inputfile] -color color [-out outputfile]\n\
+* polyglot [configfile] epd-test [engineoptions] [-epd inputfile] [-min-depth depth] [-max-depth depth] [-min-time time] [-max-time time] [-depth-delta delta]\n\
+* polyglot perft [-fen fen] [-max-depth depth]\
+";
+
+static const int SearchDepth = 63;
+static const double SearchTime = 3600.0;
+
+// variables
+
+static bool Init;
+
+// prototypes
+
+static void stop_search  ();
+
+// functions
+
+// arg_shift_left()
+
+static void arg_shift_left(char **argv, int index){
+    int i;
+    for(i=index; argv[i]!=NULL; i++){
+        argv[i]=argv[i+1];
+    }
+}
+
+// parse_args()
+
+static void parse_args(ini_t *ini, char **argv){
+    int arg_index;
+    char *arg;
+    arg_index=0;
+    while((arg=argv[arg_index])){
+        if(my_string_equal(arg,"-ec") && argv[arg_index+1]){
+            ini_insert_ex(ini,"PolyGlot","EngineCommand",argv[arg_index+1]);
+            arg_shift_left(argv,arg_index);
+            arg_shift_left(argv,arg_index);
+            continue;
+        }if(my_string_equal(arg,"-ed") && argv[arg_index+1]){
+            ini_insert_ex(ini,"PolyGlot","EngineDir",argv[arg_index+1]);
+            arg_shift_left(argv,arg_index);
+            arg_shift_left(argv,arg_index);
+            continue;
+        }
+        if(my_string_equal(arg,"-en") && argv[arg_index+1]){
+            ini_insert_ex(ini,"PolyGlot","EngineName",argv[arg_index+1]);
+            arg_shift_left(argv,arg_index);
+            arg_shift_left(argv,arg_index);
+            continue;
+        }
+        if(my_string_equal(arg,"-log") &&
+           argv[arg_index+1] &&
+           IS_BOOL(argv[arg_index+1])){
+            ini_insert_ex(ini,
+                          "PolyGlot",
+                          "Log",
+                          TO_BOOL(argv[arg_index+1])?"true":"false");
+            arg_shift_left(argv,arg_index);
+            arg_shift_left(argv,arg_index);
+            continue;
+        }
+        if(my_string_equal(arg,"-lf") && argv[arg_index+1]){
+            ini_insert_ex(ini,"PolyGlot","LogFile",argv[arg_index+1]);
+            arg_shift_left(argv,arg_index);
+            arg_shift_left(argv,arg_index);
+            continue;
+        }
+        if(my_string_equal(arg,"-wb") &&
+           argv[arg_index+1]&&
+           IS_BOOL(argv[arg_index+1])){
+               ini_insert_ex(ini,"PolyGlot",
+                             "OnlyWbOptions",
+                             TO_BOOL(argv[arg_index+1])?"true":"false");
+               arg_shift_left(argv,arg_index);
+               arg_shift_left(argv,arg_index);
+               continue;
+        }
+        if((my_string_equal(arg,"-pg")||my_string_equal(arg,"-uci")) &&
+           argv[arg_index+1]){
+            int ret;
+            char section[StringSize];
+            char name[StringSize];
+            char value[StringSize];
+            ret=ini_line_parse(argv[arg_index+1],section,name,value);
+            if(ret==NAME_VALUE){
+                if(my_string_equal(arg,"-pg")){
+                    ini_insert_ex(ini,"PolyGlot",name,value);
+                }else{
+                    ini_insert_ex(ini,"Engine",name,value);
+                }
+            }
+            arg_shift_left(argv,arg_index);
+            arg_shift_left(argv,arg_index);
+            continue;
+        }
+        arg_index++;
+    }
+}
+
+
+// make_ini()
+
+static void make_ini(ini_t *ini){
+    option_t *opt;
+    ini_insert_ex(ini,"polyglot",
+                 "EngineCommand",
+                 option_get(Option,"EngineCommand"));
+    ini_insert_ex(ini,"polyglot",
+                 "EngineDir",
+                 option_get(Option,"EngineDir"));
+    option_start_iter(Option);
+    while((opt=option_next(Option))){
+        if(my_string_case_equal(opt->name,"SettingsFile")) continue;
+        if(my_string_case_equal(opt->name,"EngineCommand")) continue;
+        if(my_string_case_equal(opt->name,"EngineDir")) continue;
+        if(!my_string_equal(opt->value,opt->default_)&& !IS_BUTTON(opt->type))
+        {
+            ini_insert_ex(ini,"polyglot",opt->name,opt->value);
+        }
+    }
+    option_start_iter(Uci->option);
+    while((opt=option_next(Uci->option))){
+        if(!strncmp(opt->name,"UCI_",4) &&
+            !my_string_case_equal(opt->name,"UCI_LimitStrength") &&
+            !my_string_case_equal(opt->name,"UCI_Elo"))continue;
+        if(!my_string_equal(opt->value,opt->default_)&&
+           !IS_BUTTON(opt->type)){
+            ini_insert_ex(ini,"engine",opt->name,opt->value);
+        }
+    }
+}
+
+
+// write_ini()
+
+static void write_ini(const char *filename,
+                        ini_t *ini){
+  // TODO Quote, dequote
+    const char *quote;
+    ini_entry_t *entry;
+    char tmp[StringSize];
+    char tmp1[StringSize];
+    char tmp2[StringSize];
+    FILE *f;
+    time_t t=time(NULL);
+    f=fopen(filename,"w");
+    if(!f){
+      gui_send(GUI,"tellusererror write_ini(): %s: %s.",filename,strerror(errno));
+      my_log("POLYGLOT write_ini(): %s: %s.\n",filename,strerror(errno));
+      return;
+    }
+    fprintf(f,"; Created: %s\n",ctime(&t));
+    fprintf(f,"[PolyGlot]\n");
+    ini_start_iter(ini);
+    while((entry=ini_next(ini))){
+      if(my_string_case_equal(entry->section,"polyglot")){
+         my_quote(tmp1,entry->name,ini_specials);
+         my_quote(tmp2,entry->value,ini_specials);
+          snprintf(tmp,sizeof(tmp),"%s=%s\n",
+                   tmp1,
+                   tmp2);
+       tmp[sizeof(tmp)-1]='\0';
+       fprintf(f,"%s",tmp);
+      }
+    }
+    fprintf(f,"[Engine]\n");
+    ini_start_iter(ini);
+    while((entry=ini_next(ini))){
+      if(my_string_case_equal(entry->section,"engine")){
+        my_quote(tmp1,entry->name,ini_specials);
+       my_quote(tmp2,entry->value,ini_specials);
+       snprintf(tmp,sizeof(tmp),"%s=%s\n",
+                     tmp1,
+                     tmp2);
+       tmp[sizeof(tmp)-1]='\0';
+       fprintf(f,"%s",tmp);
+      }
+    }
+    fclose(f);
+}
+
+// welcome_message()
+
+void welcome_message(char *buf){
+    if(!DEBUG){
+        sprintf(buf,
+                "PolyGlot %s by Fabien Letouzey.\n",
+                Version);
+    }else{
+        sprintf(buf,
+                "PolyGlot %s by Fabien Letouzey (debug build).\n",
+                Version);
+    }
+}
+
+int wb_select(){
+    option_t *opt;
+    option_start_iter(Option);
+    while((opt=option_next(Option))){
+        opt->mode&=~XBOARD;
+        if(opt->mode & XBSEL){
+            opt->mode|=XBOARD; 
+        }
+    }
+}
+
+// main()
+
+int main(int argc, char * argv[]) {
+    ini_t ini[1], ini_command[1];
+    ini_entry_t *entry;
+    char *arg;
+    int arg_index;
+    bool NoIni;
+    option_t *opt;
+    char welcome[StringSize];
+
+
+    welcome_message(welcome);
+    printf("%s",welcome);
+
+
+    if(argc>=2 && ((my_string_case_equal(argv[1],"help")) || (my_string_case_equal(argv[1],"-help")) || (my_string_case_equal(argv[1],"--help")) ||  (my_string_case_equal(argv[1],"-h")) ||  my_string_case_equal(argv[1],"/?"))){
+        printf("%s\n",HelpMessage);
+        return EXIT_SUCCESS;
+    }
+
+   // init
+
+    Init = FALSE;
+
+    gui_init(GUI);
+
+    util_init();
+    option_init_pg();
+    
+    square_init();
+    piece_init();
+    attack_init();
+    
+    hash_init();
+
+    my_random_init();
+
+    ini_init(ini);
+    ini_init(ini_command);
+
+        // book utilities: do not touch these
+    
+    if (argc >= 2 && my_string_equal(argv[1],"make-book")) {
+        book_make(argc,argv);
+        return EXIT_SUCCESS;
+    }
+    
+    if (argc >= 2 && my_string_equal(argv[1],"merge-book")) {
+        book_merge(argc,argv);
+        return EXIT_SUCCESS;
+    }
+
+    if (argc >= 2 && my_string_equal(argv[1],"dump-book")) {
+        book_dump(argc,argv);
+        return EXIT_SUCCESS;
+    }
+    
+    if (argc >= 2 && my_string_equal(argv[1],"info-book")) {
+        book_info(argc,argv);
+        return EXIT_SUCCESS;
+    }
+
+        // perft
+    
+    if (argc >= 2 && my_string_equal(argv[1],"perft")) {
+        do_perft(argc,argv);
+        return EXIT_SUCCESS;
+    }
+    
+        // What is the config file? This is very hacky right now.
+
+        // Do we want a config file at all?
+
+    arg_index=0;
+    NoIni=FALSE;
+    while((arg=argv[arg_index++])){
+        if(my_string_equal(arg,"-noini")){
+            NoIni=TRUE;
+            break;
+        }
+    }
+    arg_shift_left(argv,arg_index-1);
+    parse_args(ini_command,argv+1);
+    if(NoIni){
+        option_set(Option,"SettingsFile","<empty>");
+    }
+
+        // Ok see if first argument looks like config file
+    
+    if(argv[1] && !my_string_equal(argv[1],"epd-test") && !(argv[1][0]=='-')){
+                // first argument must be  config file
+        if(!NoIni){
+            option_set(Option,"SettingsFile",argv[1]);
+        }else{
+                // ignore
+        }
+        arg_shift_left(argv,1);
+    }else{
+            // Config file is the default.
+            // This has already been set above or in "option_init_pg()"
+    }
+
+
+
+        // if we use a config file: load it!
+    
+    if(!my_string_equal(option_get_string(Option,"SettingsFile"),"<empty>")){
+        if(ini_parse(ini,option_get_string(Option,"SettingsFile"))){
+            my_fatal("main(): Can't open config file \"%s\": %s\n",
+                   option_get_string(Option,"SettingsFile"),
+                   strerror(errno));
+        }
+    }
+
+        // Extract some important options
+
+    if((entry=ini_find(ini,"polyglot","EngineCommand"))){
+        option_set(Option,entry->name,entry->value);
+    }
+    if((entry=ini_find(ini,"polyglot","EngineDir"))){
+        option_set(Option,entry->name,entry->value);
+    }
+    if((entry=ini_find(ini,"polyglot","EngineName"))){
+        option_set(Option,entry->name,entry->value);
+    }
+    if((entry=ini_find(ini,"polyglot","Log"))){
+        polyglot_set_option(entry->name,entry->value);
+    }
+    if((entry=ini_find(ini,"polyglot","LogFile"))){
+        polyglot_set_option(entry->name,entry->value);
+    }
+    
+        // Concession to WB 4.4.0
+        // Treat "polyglot_1st.ini" and "polyglot_2nd.ini" specially
+
+    if(option_get_bool(Option,"WbWorkArounds3")){
+        const char *SettingsFile=option_get(Option,"SettingsFile");
+        if(strstr(SettingsFile,"polyglot_1st.ini")||
+           strstr(SettingsFile,"polyglot_2nd.ini")){
+            option_set(Option,"SettingsFile","<empty>");
+        }
+    }
+
+        // Look at command line for logging option. It is important
+        // to start logging as soon as possible.
+
+     if((entry=ini_find(ini_command,"PolyGlot","Log"))){
+         option_set(Option,entry->name,entry->value);
+    }
+    if((entry=ini_find(ini_command,"PolyGlot","LogFile"))){
+        option_set(Option,entry->name,entry->value);
+    }
+    
+       // start logging if required
+    
+    if (option_get_bool(Option,"Log")) {
+        my_log_open(option_get_string(Option,"LogFile"));
+    }
+
+        // log welcome stuff
+    
+    my_log("%s",welcome);
+    my_log("POLYGLOT *** START ***\n");
+    if(!my_string_equal(option_get_string(Option,"SettingsFile"),"<empty>")){
+        my_log("POLYGLOT INI file \"%s\"\n",option_get_string(Option,"SettingsFile"));
+    }
+
+
+        // scavenge command line for options necessary to start the engine
+
+
+    if((entry=ini_find(ini_command,"PolyGlot","EngineCommand"))){
+        option_set(Option,entry->name,entry->value);
+    }
+    if((entry=ini_find(ini_command,"PolyGlot","EngineDir"))){
+        option_set(Option,entry->name,entry->value);
+    }
+    if((entry=ini_find(ini_command,"PolyGlot","EngineName"))){
+        option_set(Option,entry->name,entry->value);
+    }
+
+    // Make sure that EngineCommand has been set
+    if(my_string_case_equal(option_get(Option,"EngineCommand"),"<empty>")){
+      my_fatal("main(): EngineCommand not set\n");
+    }
+
+        // start engine
+    
+    engine_open(Engine);
+
+    if(!engine_active(Engine)){
+        my_fatal("main(): Could not start \"%s\"\n",option_get(Option,"EngineCommand"));
+    }
+
+        // switch to UCI mode if necessary
+    
+    if (option_get_bool(Option,"UCI")) {
+        my_log("POLYGLOT *** Switching to UCI mode ***\n");
+    }
+
+        // initialize uci parsing and send uci command. 
+        // Parse options and wait for uciok
+    
+    // XXX
+    uci_open(Uci,Engine);
+
+    option_set_default(Option,"EngineName",Uci->name);
+
+        // get engine name from engine if not supplied in config file or on
+        // the command line
+
+    if (my_string_equal(option_get_string(Option,"EngineName"),"<empty>")) {
+        option_set(Option,"EngineName",Uci->name);
+    }
+
+
+        // In the case we have been invoked with NoIni or StandardIni
+        // we still have to load a config file.
+
+    if(my_string_equal(option_get_string(Option,"SettingsFile"),"<empty>")){
+
+            //  construct the name of the ConfigFile from the EngineName
+        
+        char tmp[StringSize];
+        char option_file[StringSize];
+        int i;
+        snprintf(tmp,sizeof(tmp),"%s.ini",
+                 option_get_string(Option,"EngineName"));
+        tmp[sizeof(tmp)-1]='\0';
+        for(i=0;i<strlen(tmp);i++){
+            if(tmp[i]==' '){
+                tmp[i]='_';
+            }
+        }
+        my_path_join(option_file,
+                     option_get_string(Option,"SettingsDir"),
+                     tmp);
+    // Load the config file
+        option_set(Option,"SettingsFile",option_file);
+
+        my_log("POLYGLOT INI file \"%s\"\n",option_get_string(Option,"SettingsFile"));
+        if(ini_parse(ini,option_file)){
+            my_log("POLYGLOT Unable to open %s\n",
+                   option_get_string(Option,"SettingsFile")); 
+        }
+    }
+
+
+    // Parse the command line and merge remaining options.
+
+    ini_start_iter(ini_command);
+    while((entry=ini_next(ini_command))){
+        ini_insert(ini,entry);
+    }
+
+        // Remind the reader about the options that are now in effect.
+
+    my_log("POLYGLOG OPTIONS \n");
+    ini_disp(ini);
+
+            // extract PG options
+    
+    ini_start_iter(ini);
+    while((entry=ini_next(ini))){
+        if(my_string_case_equal(entry->section,"polyglot")){
+            opt=option_find(Option,entry->name);
+            if(opt && !IS_BUTTON(opt->type)){
+                polyglot_set_option(entry->name,entry->value);
+            }
+        }
+    }
+
+        // Cater to our biggest customer:-)
+    
+    if(option_get_bool(Option,"OnlyWbOptions")){
+        wb_select();
+    }
+
+        // done initializing
+    
+    Init = TRUE;
+    
+        // collect engine options from config file(s) and send to engine
+    
+    ini_start_iter(ini);
+    while((entry=ini_next(ini))){
+        if(my_string_case_equal(entry->section,"engine")){
+                // also updates value in Uci->option
+            uci_send_option(Uci,entry->name,"%s",entry->value);
+        }
+    }
+
+    
+    
+        // EPD test
+    
+    if (argv[1] && my_string_equal(argv[1],"epd-test")){
+        argc=0;
+        while((arg=argv[argc++]));
+        epd_test(argc-1,argv);
+        return EXIT_SUCCESS;
+    }
+    
+        // Anything that hasn't been parsed yet is a syntax error
+        // It seems that XBoard sometimes passes empty strings as arguments
+        // to PolyGlot. We ignore these. 
+
+    argc=1;
+    while((arg=argv[argc++])){
+        if(!my_string_equal(arg,"")){
+            my_fatal("main(): Incorrect use of option: \"%s\"\n",argv[argc-1]);
+        }
+    }
+
+    //    gui_init(GUI);
+    mainloop();
+    return EXIT_SUCCESS; 
+}
+
+// polyglot_set_option()
+
+void polyglot_set_option(const char *name, const char *value){ // this must be cleaned up!
+    ini_t ini[1];
+    int ret;
+    ini_init(ini);
+    my_log("POLYGLOT Setting PolyGlot option \"%s=%s\"\n",name,value);
+    if(my_string_case_equal(name,"Save")){
+        ret=my_mkdir(option_get(Option,"SettingsDir"));
+        if(ret){
+            my_log("POLYGLOT polyglot_set_option(): %s: %s\n",
+                   option_get(Option,"SettingsDir"),
+                   strerror(errno));
+        }
+        make_ini(ini);
+        write_ini(option_get(Option,"SettingsFile"),ini);
+        return;
+    }
+//    if(my_string_equal(option_get(Option,name),value)){
+//        my_log("Not setting PolyGlot option \"%s\" "
+//               "since it already as the correct value.\n",
+//               name);
+//        return;
+//    }
+    option_set(Option,name,value);
+    if(option_get_bool(Option,"Book")&&(my_string_case_equal(name,"BookFile")||my_string_case_equal(name,"Book"))){
+        my_log("POLYGLOT *** SETTING BOOK ***\n");
+        my_log("POLYGLOT BOOK \"%s\"\n",option_get_string(Option,"BookFile"));
+        book_close();
+        book_clear();
+        book_open(option_get_string(Option,"BookFile"));
+        if(!book_is_open()){
+            my_log("POLYGLOT Unable to open book \"%s\"\n",option_get_string(Option,"BookFile"));
+        }
+    }else if(option_get_bool(Option,"Log")&&(my_string_case_equal(name,"LogFile") ||my_string_case_equal(name,"Log"))){
+        my_log("POLYGLOT *** SWITCHING LOGFILE ***\n");
+        my_log("POLYGLOT NEW LOGFILE \"%s\"\n",option_get_string(Option,"LogFile"));
+        my_log_close();
+        my_log_open(option_get_string(Option,"LogFile"));
+    }else if(option_get_bool(Option,"UseNice") &&(my_string_case_equal(name,"NiceValue")||my_string_case_equal(name,"UseNice"))){
+        my_log("POLYGLOT Adjust Engine Piority\n");
+        engine_set_nice_value(Engine,atoi(option_get_string(Option,"NiceValue")));
+    }else if(my_string_case_equal(name,"Book") && !option_get_bool(Option,"Book")){
+        book_close();
+        book_clear();
+    }else if(my_string_case_equal(name,"UseNice") && !option_get_bool(Option,"UseNice")){
+        my_log("POLYGLOT Adjust Engine Piority\n");
+        engine_set_nice_value(Engine,0);
+    }else if(my_string_case_equal(name,"Log") && !option_get_bool(Option,"Log")){
+        my_log("POLYGLOT QUIT LOGGING\n");
+        my_log_close();
+    }
+}
+
+
+
+// quit()
+
+void quit() {
+    my_log("POLYGLOT *** QUIT ***\n");
+    if (Init && !Engine->pipex->quit_pending) {
+        stop_search();
+       Engine->pipex->quit_pending=TRUE;
+        engine_send(Engine,"quit");
+        engine_close(Engine);
+        
+    }
+    my_sleep(200);
+    my_log("POLYGLOT Calling exit\n");
+    exit(EXIT_SUCCESS);
+}
+
+// stop_search()
+
+static void stop_search() {
+    
+    if (Init && Uci->searching) {
+        
+        ASSERT(Uci->searching);
+        ASSERT(Uci->pending_nb>=1);
+        
+        my_log("POLYGLOT STOP SEARCH\n");
+        
+        if (option_get_bool(Option,"SyncStop")) {
+            uci_send_stop_sync(Uci);
+        } else {
+            uci_send_stop(Uci);
+        }
+    }
+}
+
+
+// end of main.c
+