#include <stdio.h>\r
#include <stdlib.h>\r
#include <string.h>\r
+#include <time.h>\r
\r
#include "attack.h"\r
#include "board.h"\r
#include "util.h"\r
#include "xboard2uci.h"\r
#include "uci2uci.h"\r
+#include "ini.h"\r
+#include "util.h"\r
+\r
\r
// constants\r
\r
\r
-static const char * const Version = "1.4.35b";\r
+static const char * const Version = "1.4.46b";\r
static const char * const HelpMessage = "\\r
SYNTAX\n\\r
-* polyglot [configfile]\n\\r
-* polyglot -ec enginecommand\n\\r
+* polyglot [configfile] [-noini] [-ec engine] [-ed enginedirectory] [-en enginename] [-log] [-lf logfile] [-hash value] [-bk book] [-pg <name>=<value>]* [-uci <name>=<value>]*\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 dump-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 [configfile] epd-test [engineoptions] [-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 double SearchTime = 3600.0;\r
static const int StringSize = 4096;\r
\r
+static const char * const IniIntro=\r
+ "; This ini file is used internally by PolyGlot\n"\r
+ "; to remember the settings for the UCI engine\n"\r
+ "; whose name is \"%s\".\n"\r
+ "\n"\r
+ "; The values for these settings would be typicallly\n"\r
+ "; obtained from the engine settings dialog\n"\r
+ "; in WinBoard/xboard 4.4.0 and higher.\n"\r
+ "\n" \r
+ "; If the value of the option \"Persist\" is false\n"\r
+ "; then the content of this file is ignored.\n"\r
+ "\n"\r
+ "; It is allowed to manually edit this file\n"\r
+ "; and you may safely delete it as well.\n"\r
+ "\n";\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
+// arg_shift_left()\r
+\r
+static void arg_shift_left(char **argv, int index){\r
+ int i;\r
+ for(i=index; argv[i]!=NULL; i++){\r
+ argv[i]=argv[i+1];\r
+ }\r
+}\r
+\r
+\r
+// make_ini()\r
+\r
+static void make_ini(ini_t *ini){\r
+ option_t *opt;\r
+ char tmp[StringSize];\r
+ ini_insert_ex(ini,"polyglot",\r
+ "EngineName",\r
+ option_get_string(Option,"EngineName"));\r
+ ini_insert_ex(ini,"polyglot",\r
+ "EngineCommand",\r
+ option_get_string(Option,"EngineCommand"));\r
+ ini_insert_ex(ini,"polyglot",\r
+ "EngineDir",\r
+ option_get_string(Option,"EngineDir"));\r
+ option_start_iter(Option);\r
+ while((opt=option_next(Option))){\r
+ if(!my_string_equal(opt->value,opt->default_)&&\r
+ !IS_BUTTON(opt->type) &&\r
+ (opt->mode & XBOARD)){\r
+ ini_insert_ex(ini,"polyglot",opt->name,opt->value);\r
+ }\r
+ }\r
+ option_start_iter(Uci->option);\r
+ while((opt=option_next(Uci->option))){\r
+ if(!my_string_equal(opt->value,opt->default_)&&\r
+ !IS_BUTTON(opt->type)){\r
+ ini_insert_ex(ini,"engine",opt->name,opt->value);\r
+ }\r
+ }\r
+}\r
+\r
+\r
+// write_ini()\r
+\r
+static void write_ini(const char *filename,\r
+ ini_t *ini){\r
+ ini_entry_t *entry;\r
+ char tmp[StringSize];\r
+ FILE *f;\r
+ time_t t=time(NULL);\r
+ f=fopen(filename,"w");\r
+ if(!f){\r
+ // alas this does nothing....\r
+ gui_send(GUI,"tellusererror write_ini(): %s: %s.",filename,strerror(errno));\r
+ // but at least we log the error\r
+ my_log("POLYGLOT write_ini(): %s: %s.\n",filename,strerror(errno));\r
+ return;\r
+ }\r
+ fprintf(f,"; %s\n",ctime(&t));\r
+ fprintf(f,IniIntro,option_get_string(Option,"EngineName"));\r
+ fprintf(f,"[PolyGlot]\n");\r
+ ini_start_iter(ini);\r
+ while((entry=ini_next(ini))){\r
+ if(my_string_case_equal(entry->section,"polyglot")){\r
+ snprintf(tmp,sizeof(tmp),"%s=%s\n",\r
+ entry->name,\r
+ entry->value);\r
+ tmp[sizeof(tmp)-1]='\0';\r
+ fprintf(f,"%s",tmp);\r
+ }\r
+ }\r
+ fprintf(f,"[Engine]\n");\r
+ ini_start_iter(ini);\r
+ while((entry=ini_next(ini))){\r
+ if(my_string_case_equal(entry->section,"engine")){\r
+ snprintf(tmp,sizeof(tmp),"%s=%s\n",\r
+ entry->name,\r
+ entry->value);\r
+ tmp[sizeof(tmp)-1]='\0';\r
+ fprintf(f,"%s",tmp);\r
+ }\r
+ }\r
+ fclose(f);\r
+}\r
+\r
+\r
// main()\r
\r
int main(int argc, char * argv[]) {\r
-\r
+ ini_t ini[1],ini_save[1];\r
+ ini_entry_t *entry;\r
+ char *arg;\r
+ int arg_index;\r
+ bool NoIni, Persist;\r
+ char persist_path[StringSize];\r
+ \r
if(!DEBUG){\r
printf("PolyGlot %s by Fabien Letouzey.\n",Version);\r
}else{\r
attack_init();\r
\r
hash_init();\r
- \r
+\r
my_random_init();\r
\r
- // build book\r
+ ini_init(ini);\r
+ ini_init(ini_save);\r
+\r
+ // book utilities\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],"dump-book")) {\r
- book_dump(argc,argv);\r
- return EXIT_SUCCESS;\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],"info-book")) {\r
- book_info(argc,argv);\r
- return EXIT_SUCCESS;\r
- }\r
+ // perft\r
\r
if (argc >= 2 && my_string_equal(argv[1],"perft")) {\r
do_perft(argc,argv);\r
return EXIT_SUCCESS;\r
}\r
+\r
+ // TODO: If logging is enabled on the command line turn it on NOW\r
+ // and do not allow it to be overridden later. \r
\r
- if (argc >= 3 && my_string_equal(argv[1],"-ec")) {\r
- option_set(Option,"EngineCommand",argv[2]);\r
- engine_open(Engine);\r
- if(!engine_active(Engine)){\r
- my_fatal("Could not start \"%s\"\n",\r
- option_get(Option,"EngineCommand"));\r
+ // What is the config file? This is very hacky right now.\r
+\r
+ // Do we want a config file at all?\r
+\r
+ arg_index=0;\r
+ NoIni=FALSE;\r
+ while((arg=argv[arg_index++])){\r
+ if(my_string_equal(arg,"-noini")){\r
+ NoIni=TRUE;\r
+ break;\r
}\r
- Init=TRUE;\r
- gui_init(GUI);\r
- uci_open(Uci,Engine);\r
- if (my_string_equal(option_get_string(Option,"EngineName"),"<empty>")) {\r
- option_set(Option,"EngineName",Uci->name);\r
+ }\r
+ arg_shift_left(argv,arg_index-1);\r
+ if(NoIni){\r
+ option_set(Option,"OptionFile","<empty>");\r
+ }\r
+\r
+ // Ok see if first argument looks like config file\r
+ \r
+ if(argv[1] && !my_string_equal(argv[1],"epd-test") && !(argv[1][0]=='-')){\r
+ // first argument must be config file\r
+ if(!NoIni){\r
+ option_set(Option,"OptionFile",argv[1]);\r
+ }else{\r
+ // ignore\r
+ }\r
+ arg_shift_left(argv,1);\r
+ }else{\r
+ // Config file is the default.\r
+ // This has already been set above or in "option_init_pg()"\r
+ }\r
+ \r
+\r
+ // if we use a config file: load it!\r
+ \r
+ if(!my_string_equal(option_get_string(Option,"OptionFile"),"<empty>")){\r
+ if(ini_parse(ini,option_get_string(Option,"OptionFile"))){\r
+ my_fatal("main(): Can't open file \"%s\": %s\n",\r
+ option_get_string(Option,"OptionFile"),\r
+ strerror(errno));\r
}\r
- mainloop();\r
- return EXIT_SUCCESS; \r
}\r
+ // remind the reader of what options are in effect\r
+\r
+ my_log("POLYGLOG Options from ini file\n");\r
+ ini_disp(ini);\r
+\r
+ // extract PG options\r
\r
- // read options\r
+ ini_start_iter(ini);\r
+ while((entry=ini_next(ini))){\r
+ if(my_string_case_equal(entry->section,"polyglot")){\r
+ option_set(Option,entry->name,entry->value);\r
+ option_set_default(Option,entry->name,entry->value);\r
+ }\r
+ }\r
\r
+ // start logging if required\r
\r
- if (argc == 2) option_set(Option,"OptionFile",argv[1]); // HACK for compatibility\r
+ if (option_get_bool(Option,"Log")) {\r
+ my_log_open(option_get_string(Option,"LogFile"));\r
+ }\r
+\r
+ // log welcome stuff\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
+ my_log("POLYGLOT *** START ***\n");\r
+ my_log("POLYGLOT INI file \"%s\"\n",option_get_string(Option,"OptionFile"));\r
+\r
+ // open book (presumably this should go else where)\r
+ \r
+ init_book();\r
+\r
+ // scavenge command line for options necessary to start the engine\r
+ \r
+ arg_index=1;\r
+ while((arg=argv[arg_index])){\r
+ if(my_string_equal(arg,"-ec") && argv[arg_index+1]){\r
+ option_set(Option,"EngineCommand",argv[arg_index+1]);\r
+ arg_shift_left(argv,arg_index);\r
+ arg_shift_left(argv,arg_index);\r
+ continue;\r
+ }\r
+ if(my_string_equal(arg,"-ed") && argv[arg_index+1]){\r
+ option_set(Option,"EngineDir",argv[arg_index+1]);\r
+ arg_shift_left(argv,arg_index);\r
+ arg_shift_left(argv,arg_index);\r
+ continue;\r
+ }\r
+ if(my_string_equal(arg,"-en") && argv[arg_index+1]){\r
+ option_set(Option,"EngineName",argv[arg_index+1]);\r
+ arg_shift_left(argv,arg_index);\r
+ arg_shift_left(argv,arg_index);\r
+ continue;\r
+ }\r
+ arg_index++;\r
+ }\r
+\r
+ // start engine\r
+ \r
+ engine_open(Engine);\r
+ if(!engine_active(Engine)){\r
+ my_fatal("Could not start \"%s\"\n",option_get(Option,"EngineCommand"));\r
+ }\r
+\r
+ // switch to UCI mode if necessary\r
+ \r
+ if (option_get_bool(Option,"UCI")) {\r
+ my_log("POLYGLOT *** Switching to UCI mode ***\n");\r
+ }\r
+\r
+ // initialize uci parsing and send uci command. \r
+ // Parse options and wait for uciok\r
+ \r
+ uci_open(Uci,Engine);\r
+\r
+ // get engine name from engine if not supplied in config file\r
+ \r
+ if (my_string_equal(option_get_string(Option,"EngineName"),"<empty>")) {\r
+ option_set(Option,"EngineName",Uci->name);\r
+ }\r
+\r
+ // what is the name of the persist file?\r
+\r
+ if(my_string_equal(option_get_string(Option,"PersistFile"),"<empty>")){\r
+ char tmp[StringSize];\r
+ int i;\r
+ snprintf(tmp,sizeof(tmp),"%s.ini",\r
+ option_get_string(Option,"EngineName"));\r
+ tmp[sizeof(tmp)-1]='\0';\r
+ for(i=0;i<strlen(tmp);i++){\r
+ if(tmp[i]==' '){\r
+ tmp[i]='_';\r
+ }\r
+ }\r
+ option_set(Option,"PersistFile",tmp);\r
+ }\r
+\r
+ // Load the persist file\r
+\r
+ my_path_join(persist_path,\r
+ option_get_string(Option,"PersistDir"),\r
+ option_get_string(Option,"PersistFile"));\r
+\r
+ my_log("POLYGLOT PersistFile=%s\n",persist_path); \r
+ if(ini_parse(ini_save,persist_path)){\r
+ my_log("POLYGLOT Unable to open PersistFile\n"); \r
+ }\r
+\r
+ // Do we want to use the persist file?\r
+\r
+ entry=ini_find(ini_save,"polyglot","Persist");\r
+ if(!entry){\r
+ Persist=option_get_bool(Option,"Persist");\r
+ }else{\r
+ Persist=(my_string_case_equal(entry->value,"false") || \r
+ my_string_equal(entry->value,"0"))?FALSE:TRUE;\r
+ }\r
+\r
+ // if "Persist" now happens to be false, forget about the\r
+ // persist file \r
+\r
+ if(!Persist){\r
+ my_log("POLYGLOT Ignoring PersistFile");\r
+ ini_clear(ini_save);\r
+ }\r
+\r
+ option_set(Option,"Persist",Persist?"true":"false");\r
+\r
+ // parse the command line and merge remaining options\r
+\r
+ arg_index=1;\r
+ while((arg=argv[arg_index])){\r
+ if(my_string_equal(arg,"-log")){\r
+ ini_insert_ex(ini_save,"PolyGlot","Log","true");\r
+ arg_shift_left(argv,arg_index);\r
+ continue;\r
+ }\r
+ if(my_string_equal(arg,"-lf") && argv[arg_index+1]){\r
+ ini_insert_ex(ini_save,"PolyGlot","LogFile",argv[arg_index+1]);\r
+ arg_shift_left(argv,arg_index);\r
+ arg_shift_left(argv,arg_index);\r
+ continue;\r
+ }\r
+ if(my_string_equal(arg,"-hash") && argv[arg_index+1]){\r
+ ini_insert_ex(ini_save,"Engine","Hash",argv[arg_index+1]);\r
+ arg_shift_left(argv,arg_index);\r
+ arg_shift_left(argv,arg_index);\r
+ continue;\r
+ }\r
+ if(my_string_equal(arg,"-bk") && argv[arg_index+1]){\r
+ ini_insert_ex(ini_save,"PolyGlot","Book","true");\r
+ ini_insert_ex(ini_save,"PolyGlot","BookFile",argv[arg_index+1]);\r
+ arg_shift_left(argv,arg_index);\r
+ arg_shift_left(argv,arg_index);\r
+ continue;\r
+ }\r
+ if((my_string_equal(arg,"-pg")||my_string_equal(arg,"-uci")) &&\r
+ argv[arg_index]){\r
+ int ret;\r
+ char section[StringSize];\r
+ char name[StringSize];\r
+ char value[StringSize];\r
+ ret=ini_line_parse(argv[arg_index++],section,name,value);\r
+ if(ret==NAME_VALUE){\r
+ if(my_string_equal(arg,"-pg")){\r
+ ini_insert_ex(ini_save,"PolyGlot",name,value);\r
+ }else{\r
+ ini_insert_ex(ini_save,"Engine",name,value);\r
+ }\r
+ }\r
+ arg_shift_left(argv,arg_index);\r
+ arg_shift_left(argv,arg_index);\r
+ continue;\r
+ }\r
+ arg_index++;\r
+ }\r
+\r
+ // remind the reader once again about options\r
+\r
+ my_log("POLYGLOG Options from PersistFile and command line\n");\r
+ ini_disp(ini_save);\r
+\r
+ // Extract PG options; this time do not set the default.\r
+ // polyglot_set_option() performs the necessary actions such\r
+ // as opening the log file/opening book etcetera.\r
+ // Ignore EngineName, EngineCommand and EngineDir\r
+ // as these are really meant as comments.\r
+ \r
+ ini_start_iter(ini_save);\r
+ while((entry=ini_next(ini_save))){\r
+ if(my_string_case_equal(entry->section,"polyglot")){\r
+ if(my_string_case_equal(entry->value,"EngineName")) \r
+ continue;\r
+ if(my_string_case_equal(entry->value,"EngineCommand")) \r
+ continue;\r
+ if(my_string_case_equal(entry->value,"EngineDir")) \r
+ continue;\r
+ polyglot_set_option(entry->name,entry->value);\r
+ }\r
+ }\r
\r
- parse_option(); // HACK: also launches the engine\r
+ // done initializing\r
+ \r
+ Init = TRUE;\r
+ \r
+ // collect engine options from config file(s) and send to engine\r
+ \r
+ ini_start_iter(ini);\r
+ while((entry=ini_next(ini))){\r
+ if(my_string_case_equal(entry->section,"engine")){\r
+ // also updates value in Uci->option\r
+ uci_send_option(Uci,entry->name,"%s",entry->value);\r
+ // since this comes from the ini file, also update default\r
+ option_set_default(Uci->option,entry->name,entry->value);\r
+ // this is inherited, it probably does not work correctly\r
+ if(my_string_case_equal(entry->name,"MultiPV") &&\r
+ atoi(entry->value)>1){\r
+ Uci->multipv_mode=TRUE;\r
+ }\r
+ }\r
+ }\r
+ ini_start_iter(ini_save);\r
+ while((entry=ini_next(ini_save))){\r
+ if(my_string_case_equal(entry->section,"engine")){\r
+ // also updates value in Uci->option\r
+ uci_send_option(Uci,entry->name,"%s",entry->value);\r
+ // this is inherited, it probably does not work correctly\r
+ if(my_string_case_equal(entry->name,"MultiPV") &&\r
+ atoi(entry->value)>1){\r
+ Uci->multipv_mode=TRUE;\r
+ }\r
+ }\r
+ }\r
+ \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
+ if (argv[1] && my_string_equal(argv[1],"epd-test")){\r
+ argc=0;\r
+ while((arg=argv[argc++]));\r
+ epd_test(argc-1,argv);\r
return EXIT_SUCCESS;\r
}\r
\r
- if (argc >= 3) my_fatal("Too many arguments\n");\r
+ // Anything that hasn't been parsed yet is a syntax error\r
+\r
+ if(argv[1]){\r
+ my_fatal("main(): Unknown option: %s\n",argv[1]);\r
+ }\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
+// polyglot_set_option()\r
+\r
+void polyglot_set_option(const char *name, const char *value){ // this must be cleaned up!\r
+ option_t *opt;\r
+ my_log("POLYGLOT Setting PolyGlot option %s=\"%s\"\n",name,value);\r
+ if(my_string_case_equal(name,"Defaults")){\r
+ option_start_iter(Uci->option);\r
+ while((opt=option_next(Uci->option))){\r
+ if(!IS_BUTTON(opt->type)){\r
+ // also sets opt->value\r
+ uci_send_option(Uci,opt->name,opt->default_);\r
+ }\r
+ }\r
+ option_start_iter(Option);\r
+ while((opt=option_next(Option))){\r
+ if(!IS_BUTTON(opt->type)){\r
+ polyglot_set_option(opt->name,opt->default_);\r
+ }\r
+ }\r
+ xboard2uci_send_options();\r
+ }\r
option_set(Option,name,value);\r
if(option_get_bool(Option,"Book")&&(my_string_case_equal(name,"BookFile")||my_string_case_equal(name,"Book"))){\r
my_log("POLYGLOT *** SETTING BOOK ***\n");\r
my_log("POLYGLOT Unable to open book \"%s\"\n",option_get_string(Option,"BookFile"));\r
}\r
}else if(option_get_bool(Option,"Log")&&(my_string_case_equal(name,"LogFile") ||my_string_case_equal(name,"Log"))){\r
- my_log("POLYGLOT *** SETTING LOGFILE ***\n");\r
+ my_log("POLYGLOT *** SWITCHING LOGFILE ***\n");\r
my_log("POLYGLOT LOGFILE \"%s\"\n",option_get_string(Option,"LogFile"));\r
my_log_close();\r
my_log_open(option_get_string(Option,"LogFile"));\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(Option,"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(Option,name,value);\r
- option_set_default(Option,name,value);\r
- }\r
- }\r
- \r
- if (option_get_bool(Option,"Log")) {\r
- my_log_open(option_get_string(Option,"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(Option,"EngineCommand"));\r
- }\r
-\r
- if (option_get_bool(Option,"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(Option,"EngineName"),"<empty>")) {\r
- option_set(Option,"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
+ ini_t ini[1];\r
+ char persist_path[StringSize];\r
+ int ret;\r
+\r
+ ini_init(ini);\r
+\r
my_log("POLYGLOT *** QUIT ***\n");\r
\r
if (Init) {\r
engine_close(Engine);\r
\r
}\r
- my_log("POLYGLOT Calling exit\n");\r
+ ret=my_mkdir(option_get(Option,"PersistDir"));\r
+ if(ret){\r
+ my_log("POLYGLOT quit(): %s: %s\n",option_get(Option,"PersistDir"),strerror(errno));\r
+ }\r
+ // PersistFile can be named "<empty>" in case of a crash before the\r
+ // engine is started. \r
+ if(!my_string_case_equal(option_get(Option,"PersistFile"),\r
+ "<empty>")){\r
+ // Persistence should only work in XBOARD mode.\r
+ // In UCI mode the GUI is responsible for remembering options.\r
+ if(!option_get_bool(Option,"UCI")){\r
+ my_path_join(persist_path,\r
+ option_get(Option,"PersistDir"),\r
+ option_get(Option,"PersistFile"));\r
+ make_ini(ini);\r
+ if(option_get_bool(Option,"Persist")){\r
+ write_ini(persist_path,ini);\r
+ }else if(!my_string_case_equal(option_get_default(Option,"Persist"),\r
+ option_get_string(Option,"Persist"))){\r
+ // Hack\r
+ ini_insert_ex(ini,"polyglot","Persist","false");\r
+ write_ini(persist_path,ini);\r
+ }else{\r
+ write_ini(persist_path,ini);\r
+ }\r
+ my_log("POLYGLOT Calling exit\n");\r
+ }\r
+ }\r
exit(EXIT_SUCCESS);\r
}\r
\r