version 1.4.46b
[polyglot.git] / main.c
1 \r
2 // main.c\r
3 \r
4 // includes\r
5 \r
6 #include <errno.h>\r
7 #include <stdio.h>\r
8 #include <stdlib.h>\r
9 #include <string.h>\r
10 #include <time.h>\r
11 \r
12 #include "attack.h"\r
13 #include "board.h"\r
14 #include "book.h"\r
15 #include "book_make.h"\r
16 #include "book_merge.h"\r
17 #include "engine.h"\r
18 #include "epd.h"\r
19 #include "fen.h"\r
20 #include "gui.h"\r
21 #include "hash.h"\r
22 #include "list.h"\r
23 #include "main.h"\r
24 #include "mainloop.h"\r
25 #include "move.h"\r
26 #include "move_gen.h"\r
27 #include "option.h"\r
28 #include "piece.h"\r
29 #include "search.h"\r
30 #include "square.h"\r
31 #include "uci.h"\r
32 #include "util.h"\r
33 #include "xboard2uci.h"\r
34 #include "uci2uci.h"\r
35 #include "ini.h"\r
36 #include "util.h"\r
37 \r
38 \r
39 // constants\r
40 \r
41 \r
42 static const char * const Version = "1.4.46b";\r
43 static const char * const HelpMessage = "\\r
44 SYNTAX\n\\r
45 * polyglot [configfile] [-noini] [-ec engine] [-ed enginedirectory] [-en enginename] [-log] [-lf logfile] [-hash value] [-bk book] [-pg <name>=<value>]* [-uci <name>=<value>]*\n\\r
46 * polyglot make-book [-pgn inputfile] [-bin outputfile] [-max-ply ply] [-min-game games] [-min-score score] [-only-white] [-only-black] [-uniform]\n\\r
47 * polyglot merge-book -in1 inputfile1 -in2 inputfile2 [-out outputfile]\n\\r
48 * polyglot info-book [-bin inputfile] [-exact]\n\\r
49 * polyglot dump-book [-bin inputfile] -color color [-out outputfile]\n\\r
50 * polyglot [configfile] epd-test [engineoptions] [-epd inputfile] [-min-depth depth] [-max-depth depth] [-min-time time] [-max-time time] [-depth-delta delta]\n\\r
51 * polyglot perft [-fen fen] [-max-depth depth]\\r
52 ";\r
53 \r
54 static const int SearchDepth = 63;\r
55 static const double SearchTime = 3600.0;\r
56 static const int StringSize = 4096;\r
57 \r
58 static const char * const IniIntro=\r
59               "; This ini file is used internally by PolyGlot\n"\r
60               "; to remember the settings for the UCI engine\n"\r
61               "; whose name is \"%s\".\n"\r
62               "\n"\r
63               "; The values for these settings would be typicallly\n"\r
64               "; obtained from the engine settings dialog\n"\r
65               "; in WinBoard/xboard 4.4.0 and higher.\n"\r
66               "\n" \r
67               "; If the value of the option \"Persist\" is false\n"\r
68               "; then the content of this file is ignored.\n"\r
69               "\n"\r
70               "; It is allowed to manually edit this file\n"\r
71               "; and you may safely delete it as well.\n"\r
72               "\n";\r
73 \r
74 // variables\r
75 \r
76 static bool Init;\r
77 \r
78 // prototypes\r
79 \r
80 static void init_book ();\r
81 static void stop_search  ();\r
82 \r
83 // functions\r
84 \r
85 // arg_shift_left()\r
86 \r
87 static void arg_shift_left(char **argv, int index){\r
88     int i;\r
89     for(i=index; argv[i]!=NULL; i++){\r
90         argv[i]=argv[i+1];\r
91     }\r
92 }\r
93 \r
94 \r
95 // make_ini()\r
96 \r
97 static void make_ini(ini_t *ini){\r
98     option_t *opt;\r
99     char tmp[StringSize];\r
100     ini_insert_ex(ini,"polyglot",\r
101                   "EngineName",\r
102                   option_get_string(Option,"EngineName"));\r
103     ini_insert_ex(ini,"polyglot",\r
104                   "EngineCommand",\r
105                   option_get_string(Option,"EngineCommand"));\r
106     ini_insert_ex(ini,"polyglot",\r
107                   "EngineDir",\r
108                   option_get_string(Option,"EngineDir"));\r
109     option_start_iter(Option);\r
110     while((opt=option_next(Option))){\r
111         if(!my_string_equal(opt->value,opt->default_)&&\r
112            !IS_BUTTON(opt->type) &&\r
113            (opt->mode & XBOARD)){\r
114           ini_insert_ex(ini,"polyglot",opt->name,opt->value);\r
115         }\r
116     }\r
117     option_start_iter(Uci->option);\r
118     while((opt=option_next(Uci->option))){\r
119         if(!my_string_equal(opt->value,opt->default_)&&\r
120            !IS_BUTTON(opt->type)){\r
121           ini_insert_ex(ini,"engine",opt->name,opt->value);\r
122         }\r
123     }\r
124 }\r
125 \r
126 \r
127 // write_ini()\r
128 \r
129 static void write_ini(const char *filename,\r
130                          ini_t *ini){\r
131     ini_entry_t *entry;\r
132     char tmp[StringSize];\r
133     FILE *f;\r
134     time_t t=time(NULL);\r
135     f=fopen(filename,"w");\r
136     if(!f){\r
137       // alas this does nothing....\r
138       gui_send(GUI,"tellusererror write_ini(): %s: %s.",filename,strerror(errno));\r
139       // but at least we log the error\r
140       my_log("POLYGLOT write_ini(): %s: %s.\n",filename,strerror(errno));\r
141       return;\r
142     }\r
143     fprintf(f,"; %s\n",ctime(&t));\r
144     fprintf(f,IniIntro,option_get_string(Option,"EngineName"));\r
145     fprintf(f,"[PolyGlot]\n");\r
146     ini_start_iter(ini);\r
147     while((entry=ini_next(ini))){\r
148       if(my_string_case_equal(entry->section,"polyglot")){\r
149         snprintf(tmp,sizeof(tmp),"%s=%s\n",\r
150                  entry->name,\r
151                  entry->value);\r
152         tmp[sizeof(tmp)-1]='\0';\r
153         fprintf(f,"%s",tmp);\r
154       }\r
155     }\r
156     fprintf(f,"[Engine]\n");\r
157     ini_start_iter(ini);\r
158     while((entry=ini_next(ini))){\r
159       if(my_string_case_equal(entry->section,"engine")){\r
160         snprintf(tmp,sizeof(tmp),"%s=%s\n",\r
161                  entry->name,\r
162                  entry->value);\r
163         tmp[sizeof(tmp)-1]='\0';\r
164         fprintf(f,"%s",tmp);\r
165       }\r
166     }\r
167     fclose(f);\r
168 }\r
169 \r
170 \r
171 // main()\r
172 \r
173 int main(int argc, char * argv[]) {\r
174     ini_t ini[1],ini_save[1];\r
175     ini_entry_t *entry;\r
176     char *arg;\r
177     int arg_index;\r
178     bool NoIni, Persist;\r
179     char persist_path[StringSize];\r
180  \r
181     if(!DEBUG){\r
182         printf("PolyGlot %s by Fabien Letouzey.\n",Version);\r
183     }else{\r
184         printf("PolyGlot %s by Fabien Letouzey (debug build).\n",Version);\r
185     }\r
186 \r
187     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
188         printf("%s\n",HelpMessage);\r
189         return EXIT_SUCCESS;\r
190     }\r
191 \r
192    // init\r
193 \r
194     Init = FALSE;\r
195 \r
196     util_init();\r
197     option_init_pg();\r
198     \r
199     square_init();\r
200     piece_init();\r
201     attack_init();\r
202     \r
203     hash_init();\r
204 \r
205     my_random_init();\r
206 \r
207     ini_init(ini);\r
208     ini_init(ini_save);\r
209 \r
210         // book utilities\r
211     \r
212     if (argc >= 2 && my_string_equal(argv[1],"make-book")) {\r
213         book_make(argc,argv);\r
214         return EXIT_SUCCESS;\r
215     }\r
216     \r
217     if (argc >= 2 && my_string_equal(argv[1],"merge-book")) {\r
218         book_merge(argc,argv);\r
219         return EXIT_SUCCESS;\r
220     }\r
221 \r
222     if (argc >= 2 && my_string_equal(argv[1],"dump-book")) {\r
223         book_dump(argc,argv);\r
224         return EXIT_SUCCESS;\r
225     }\r
226     \r
227     if (argc >= 2 && my_string_equal(argv[1],"info-book")) {\r
228         book_info(argc,argv);\r
229         return EXIT_SUCCESS;\r
230     }\r
231 \r
232         // perft\r
233     \r
234     if (argc >= 2 && my_string_equal(argv[1],"perft")) {\r
235         do_perft(argc,argv);\r
236         return EXIT_SUCCESS;\r
237     }\r
238 \r
239         // TODO: If logging is enabled on the command line turn it on NOW\r
240         // and do not allow it to be overridden later. \r
241     \r
242         // What is the config file? This is very hacky right now.\r
243 \r
244         // Do we want a config file at all?\r
245 \r
246     arg_index=0;\r
247     NoIni=FALSE;\r
248     while((arg=argv[arg_index++])){\r
249         if(my_string_equal(arg,"-noini")){\r
250             NoIni=TRUE;\r
251             break;\r
252         }\r
253     }\r
254     arg_shift_left(argv,arg_index-1);\r
255     if(NoIni){\r
256         option_set(Option,"OptionFile","<empty>");\r
257     }\r
258 \r
259         // Ok see if first argument looks like config file\r
260     \r
261     if(argv[1] && !my_string_equal(argv[1],"epd-test") && !(argv[1][0]=='-')){\r
262                 // first argument must be  config file\r
263         if(!NoIni){\r
264             option_set(Option,"OptionFile",argv[1]);\r
265         }else{\r
266                 // ignore\r
267         }\r
268         arg_shift_left(argv,1);\r
269     }else{\r
270             // Config file is the default.\r
271             // This has already been set above or in "option_init_pg()"\r
272     }\r
273     \r
274 \r
275         // if we use a config file: load it!\r
276     \r
277     if(!my_string_equal(option_get_string(Option,"OptionFile"),"<empty>")){\r
278         if(ini_parse(ini,option_get_string(Option,"OptionFile"))){\r
279             my_fatal("main(): Can't open file \"%s\": %s\n",\r
280                    option_get_string(Option,"OptionFile"),\r
281                    strerror(errno));\r
282         }\r
283     }\r
284         // remind the reader of what options are in effect\r
285 \r
286     my_log("POLYGLOG Options from ini file\n");\r
287     ini_disp(ini);\r
288 \r
289         // extract PG options\r
290     \r
291     ini_start_iter(ini);\r
292     while((entry=ini_next(ini))){\r
293         if(my_string_case_equal(entry->section,"polyglot")){\r
294             option_set(Option,entry->name,entry->value);\r
295             option_set_default(Option,entry->name,entry->value);\r
296         }\r
297     }\r
298 \r
299         // start logging if required\r
300     \r
301     if (option_get_bool(Option,"Log")) {\r
302         my_log_open(option_get_string(Option,"LogFile"));\r
303     }\r
304 \r
305         // log welcome stuff\r
306     \r
307     if(!DEBUG){\r
308         my_log("PolyGlot %s by Fabien Letouzey\n",Version);\r
309     }else{\r
310         my_log("PolyGlot %s by Fabien Letouzey (debug build)\n",Version);\r
311     }    \r
312     my_log("POLYGLOT *** START ***\n");\r
313     my_log("POLYGLOT INI file \"%s\"\n",option_get_string(Option,"OptionFile"));\r
314 \r
315         // open book (presumably this should go else where)\r
316     \r
317     init_book();\r
318 \r
319         // scavenge command line for options necessary to start the engine\r
320     \r
321     arg_index=1;\r
322     while((arg=argv[arg_index])){\r
323         if(my_string_equal(arg,"-ec") && argv[arg_index+1]){\r
324             option_set(Option,"EngineCommand",argv[arg_index+1]);\r
325             arg_shift_left(argv,arg_index);\r
326             arg_shift_left(argv,arg_index);\r
327             continue;\r
328         }\r
329         if(my_string_equal(arg,"-ed") && argv[arg_index+1]){\r
330             option_set(Option,"EngineDir",argv[arg_index+1]);\r
331             arg_shift_left(argv,arg_index);\r
332             arg_shift_left(argv,arg_index);\r
333             continue;\r
334         }\r
335         if(my_string_equal(arg,"-en") && argv[arg_index+1]){\r
336             option_set(Option,"EngineName",argv[arg_index+1]);\r
337             arg_shift_left(argv,arg_index);\r
338             arg_shift_left(argv,arg_index);\r
339             continue;\r
340         }\r
341         arg_index++;\r
342     }\r
343 \r
344         // start engine\r
345     \r
346     engine_open(Engine);\r
347     if(!engine_active(Engine)){\r
348         my_fatal("Could not start \"%s\"\n",option_get(Option,"EngineCommand"));\r
349     }\r
350 \r
351         // switch to UCI mode if necessary\r
352     \r
353     if (option_get_bool(Option,"UCI")) {\r
354         my_log("POLYGLOT *** Switching to UCI mode ***\n");\r
355     }\r
356 \r
357         // initialize uci parsing and send uci command. \r
358         // Parse options and wait for uciok\r
359     \r
360     uci_open(Uci,Engine);\r
361 \r
362         // get engine name from engine if not supplied in config file\r
363     \r
364     if (my_string_equal(option_get_string(Option,"EngineName"),"<empty>")) {\r
365         option_set(Option,"EngineName",Uci->name);\r
366     }\r
367 \r
368         // what is the name of the persist file?\r
369 \r
370     if(my_string_equal(option_get_string(Option,"PersistFile"),"<empty>")){\r
371         char tmp[StringSize];\r
372         int i;\r
373         snprintf(tmp,sizeof(tmp),"%s.ini",\r
374                  option_get_string(Option,"EngineName"));\r
375         tmp[sizeof(tmp)-1]='\0';\r
376         for(i=0;i<strlen(tmp);i++){\r
377           if(tmp[i]==' '){\r
378             tmp[i]='_';\r
379           }\r
380         }\r
381         option_set(Option,"PersistFile",tmp);\r
382     }\r
383 \r
384     // Load the persist file\r
385 \r
386     my_path_join(persist_path,\r
387                  option_get_string(Option,"PersistDir"),\r
388                  option_get_string(Option,"PersistFile"));\r
389 \r
390     my_log("POLYGLOT PersistFile=%s\n",persist_path);   \r
391     if(ini_parse(ini_save,persist_path)){\r
392       my_log("POLYGLOT Unable to open PersistFile\n"); \r
393     }\r
394 \r
395     // Do we want to use the persist file?\r
396 \r
397     entry=ini_find(ini_save,"polyglot","Persist");\r
398     if(!entry){\r
399       Persist=option_get_bool(Option,"Persist");\r
400     }else{\r
401       Persist=(my_string_case_equal(entry->value,"false") || \r
402                my_string_equal(entry->value,"0"))?FALSE:TRUE;\r
403     }\r
404 \r
405     // if "Persist" now happens to be false, forget about the\r
406     // persist file    \r
407 \r
408     if(!Persist){\r
409       my_log("POLYGLOT Ignoring PersistFile");\r
410       ini_clear(ini_save);\r
411     }\r
412 \r
413     option_set(Option,"Persist",Persist?"true":"false");\r
414 \r
415     // parse the command line and merge remaining options\r
416 \r
417     arg_index=1;\r
418     while((arg=argv[arg_index])){\r
419         if(my_string_equal(arg,"-log")){\r
420             ini_insert_ex(ini_save,"PolyGlot","Log","true");\r
421             arg_shift_left(argv,arg_index);\r
422             continue;\r
423         }\r
424         if(my_string_equal(arg,"-lf") && argv[arg_index+1]){\r
425             ini_insert_ex(ini_save,"PolyGlot","LogFile",argv[arg_index+1]);\r
426             arg_shift_left(argv,arg_index);\r
427             arg_shift_left(argv,arg_index);\r
428             continue;\r
429         }\r
430         if(my_string_equal(arg,"-hash") && argv[arg_index+1]){\r
431             ini_insert_ex(ini_save,"Engine","Hash",argv[arg_index+1]);\r
432             arg_shift_left(argv,arg_index);\r
433             arg_shift_left(argv,arg_index);\r
434             continue;\r
435         }\r
436         if(my_string_equal(arg,"-bk") && argv[arg_index+1]){\r
437             ini_insert_ex(ini_save,"PolyGlot","Book","true");\r
438             ini_insert_ex(ini_save,"PolyGlot","BookFile",argv[arg_index+1]);\r
439             arg_shift_left(argv,arg_index);\r
440             arg_shift_left(argv,arg_index);\r
441             continue;\r
442         }\r
443         if((my_string_equal(arg,"-pg")||my_string_equal(arg,"-uci")) &&\r
444            argv[arg_index]){\r
445             int ret;\r
446             char section[StringSize];\r
447             char name[StringSize];\r
448             char value[StringSize];\r
449             ret=ini_line_parse(argv[arg_index++],section,name,value);\r
450             if(ret==NAME_VALUE){\r
451                 if(my_string_equal(arg,"-pg")){\r
452                     ini_insert_ex(ini_save,"PolyGlot",name,value);\r
453                 }else{\r
454                     ini_insert_ex(ini_save,"Engine",name,value);\r
455                 }\r
456             }\r
457             arg_shift_left(argv,arg_index);\r
458             arg_shift_left(argv,arg_index);\r
459             continue;\r
460         }\r
461         arg_index++;\r
462     }\r
463 \r
464         // remind the reader once again about options\r
465 \r
466     my_log("POLYGLOG Options from PersistFile and command line\n");\r
467     ini_disp(ini_save);\r
468 \r
469         // Extract PG options; this time do not set the default.\r
470         // polyglot_set_option() performs the necessary actions such\r
471         // as opening the log file/opening book etcetera.\r
472         // Ignore EngineName, EngineCommand and EngineDir\r
473         // as these are really meant as comments.\r
474     \r
475     ini_start_iter(ini_save);\r
476     while((entry=ini_next(ini_save))){\r
477         if(my_string_case_equal(entry->section,"polyglot")){\r
478             if(my_string_case_equal(entry->value,"EngineName")) \r
479                continue;\r
480             if(my_string_case_equal(entry->value,"EngineCommand")) \r
481                continue;\r
482             if(my_string_case_equal(entry->value,"EngineDir")) \r
483                continue;\r
484             polyglot_set_option(entry->name,entry->value);\r
485         }\r
486     }\r
487 \r
488         // done initializing\r
489     \r
490     Init = TRUE;\r
491     \r
492         // collect engine options from config file(s) and send to engine\r
493     \r
494     ini_start_iter(ini);\r
495     while((entry=ini_next(ini))){\r
496         if(my_string_case_equal(entry->section,"engine")){\r
497                 // also updates value in Uci->option\r
498             uci_send_option(Uci,entry->name,"%s",entry->value);\r
499                 // since this comes from the ini file, also update default\r
500             option_set_default(Uci->option,entry->name,entry->value);\r
501                 // this is inherited, it probably does not work correctly\r
502            if(my_string_case_equal(entry->name,"MultiPV") &&\r
503               atoi(entry->value)>1){\r
504                Uci->multipv_mode=TRUE;\r
505            }\r
506         }\r
507     }\r
508     ini_start_iter(ini_save);\r
509     while((entry=ini_next(ini_save))){\r
510         if(my_string_case_equal(entry->section,"engine")){\r
511                 // also updates value in Uci->option\r
512             uci_send_option(Uci,entry->name,"%s",entry->value);\r
513                 // this is inherited, it probably does not work correctly\r
514             if(my_string_case_equal(entry->name,"MultiPV") &&\r
515                atoi(entry->value)>1){\r
516                 Uci->multipv_mode=TRUE;\r
517             }\r
518         }\r
519     }\r
520    \r
521     \r
522         // EPD test\r
523     \r
524     if (argv[1] && my_string_equal(argv[1],"epd-test")){\r
525         argc=0;\r
526         while((arg=argv[argc++]));\r
527         epd_test(argc-1,argv);\r
528         return EXIT_SUCCESS;\r
529     }\r
530     \r
531         // Anything that hasn't been parsed yet is a syntax error\r
532 \r
533     if(argv[1]){\r
534         my_fatal("main(): Unknown option: %s\n",argv[1]);\r
535     }\r
536 \r
537 \r
538     gui_init(GUI);\r
539     mainloop();\r
540     return EXIT_SUCCESS; \r
541 }\r
542 \r
543 // polyglot_set_option()\r
544 \r
545 void polyglot_set_option(const char *name, const char *value){ // this must be cleaned up!\r
546     option_t *opt;\r
547     my_log("POLYGLOT Setting PolyGlot option %s=\"%s\"\n",name,value);\r
548     if(my_string_case_equal(name,"Defaults")){\r
549       option_start_iter(Uci->option);\r
550       while((opt=option_next(Uci->option))){\r
551         if(!IS_BUTTON(opt->type)){\r
552         // also sets opt->value\r
553           uci_send_option(Uci,opt->name,opt->default_);\r
554         }\r
555       }\r
556       option_start_iter(Option);\r
557       while((opt=option_next(Option))){\r
558         if(!IS_BUTTON(opt->type)){\r
559           polyglot_set_option(opt->name,opt->default_);\r
560         }\r
561       }\r
562       xboard2uci_send_options();\r
563     }\r
564     option_set(Option,name,value);\r
565     if(option_get_bool(Option,"Book")&&(my_string_case_equal(name,"BookFile")||my_string_case_equal(name,"Book"))){\r
566         my_log("POLYGLOT *** SETTING BOOK ***\n");\r
567         my_log("POLYGLOT BOOK \"%s\"\n",option_get_string(Option,"BookFile"));\r
568         book_close();\r
569         book_clear();\r
570         book_open(option_get_string(Option,"BookFile"));\r
571         if(!book_is_open()){\r
572             my_log("POLYGLOT Unable to open book \"%s\"\n",option_get_string(Option,"BookFile"));\r
573         }\r
574     }else if(option_get_bool(Option,"Log")&&(my_string_case_equal(name,"LogFile") ||my_string_case_equal(name,"Log"))){\r
575         my_log("POLYGLOT *** SWITCHING LOGFILE ***\n");\r
576         my_log("POLYGLOT LOGFILE \"%s\"\n",option_get_string(Option,"LogFile"));\r
577         my_log_close();\r
578         my_log_open(option_get_string(Option,"LogFile"));\r
579     }else if(option_get_bool(Option,"UseNice") &&(my_string_case_equal(name,"NiceValue")||my_string_case_equal(name,"UseNice"))){\r
580         my_log("POLYGLOT Adjust Engine Piority\n");\r
581         engine_set_nice_value(Engine,atoi(option_get_string(Option,"NiceValue")));\r
582     }else if(my_string_case_equal(name,"Book") && !option_get_bool(Option,"Book")){\r
583         book_close();\r
584         book_clear();\r
585     }else if(my_string_case_equal(name,"UseNice") && !option_get_bool(Option,"UseNice")){\r
586         my_log("POLYGLOT Adjust Engine Piority\n");\r
587         engine_set_nice_value(Engine,0);\r
588     }else if(my_string_case_equal(name,"Log") && !option_get_bool(Option,"Log")){\r
589         my_log("POLYGLOT QUIT LOGGING\n");\r
590         my_log_close();\r
591     }\r
592 }\r
593 \r
594 \r
595 // init_book()\r
596 \r
597 static void init_book(){\r
598     book_clear();\r
599     if (option_get_bool(Option,"Book")){\r
600         my_log("POLYGLOT *** SETTING BOOK ***\n");\r
601         my_log("POLYGLOT BOOK \"%s\"\n",option_get_string(Option,"BookFile"));\r
602         book_open(option_get_string(Option,"BookFile"));\r
603         if(!book_is_open()){\r
604             my_log("POLYGLOT Unable to open book \"%s\"\n",\r
605                    option_get_string(Option,"BookFile"));\r
606         }\r
607     }\r
608 }\r
609 \r
610 \r
611 // quit()\r
612 \r
613 void quit() {\r
614 \r
615     ini_t ini[1];\r
616     char persist_path[StringSize];\r
617     int ret;\r
618 \r
619     ini_init(ini);\r
620 \r
621     my_log("POLYGLOT *** QUIT ***\n");\r
622     \r
623     if (Init) {\r
624         \r
625         stop_search();\r
626         engine_send(Engine,"quit");\r
627         my_log("POLYGLOT Closing engine\n");\r
628         engine_close(Engine);\r
629         \r
630     }\r
631     ret=my_mkdir(option_get(Option,"PersistDir"));\r
632     if(ret){\r
633       my_log("POLYGLOT quit(): %s: %s\n",option_get(Option,"PersistDir"),strerror(errno));\r
634     }\r
635     // PersistFile can be named "<empty>" in case of a crash before the\r
636     // engine is started. \r
637     if(!my_string_case_equal(option_get(Option,"PersistFile"),\r
638                              "<empty>")){\r
639       // Persistence should only work in XBOARD mode.\r
640       // In UCI mode the GUI is responsible for remembering options.\r
641       if(!option_get_bool(Option,"UCI")){\r
642         my_path_join(persist_path,\r
643                      option_get(Option,"PersistDir"),\r
644                      option_get(Option,"PersistFile"));\r
645         make_ini(ini);\r
646         if(option_get_bool(Option,"Persist")){\r
647           write_ini(persist_path,ini);\r
648         }else if(!my_string_case_equal(option_get_default(Option,"Persist"),\r
649                                        option_get_string(Option,"Persist"))){\r
650           // Hack\r
651           ini_insert_ex(ini,"polyglot","Persist","false");\r
652           write_ini(persist_path,ini);\r
653         }else{\r
654           write_ini(persist_path,ini);\r
655         }\r
656         my_log("POLYGLOT Calling exit\n");\r
657       }\r
658     }\r
659     exit(EXIT_SUCCESS);\r
660 }\r
661 \r
662 // stop_search()\r
663 \r
664 static void stop_search() {\r
665     \r
666     if (Init && Uci->searching) {\r
667         \r
668         ASSERT(Uci->searching);\r
669         ASSERT(Uci->pending_nb>=1);\r
670         \r
671         my_log("POLYGLOT STOP SEARCH\n");\r
672         \r
673         if (option_get_bool(Option,"SyncStop")) {\r
674             uci_send_stop_sync(Uci);\r
675         } else {\r
676             uci_send_stop(Uci);\r
677         }\r
678     }\r
679 }\r
680 \r
681 \r
682 // end of main.cpp\r
683 \r