X-Git-Url: http://winboard.nl/cgi-bin?p=polyglot.git;a=blobdiff_plain;f=main.c;h=e06d59c9c34800999bd161086962d93761769645;hp=830dfa25dd01af2c0ea7a3734053268fb308c55c;hb=HEAD;hpb=c6505b9bddf0ed2f461a473d4be40c98608d9866 diff --git a/main.c b/main.c index 830dfa2..e06d59c 100644 --- a/main.c +++ b/main.c @@ -1,676 +1,670 @@ - -// main.c - -// includes - -#include -#include -#include -#include -#include - -#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.50b"; -static const char * const HelpMessage = "\ -SYNTAX\n\ -* polyglot [configfile] [-noini] [-ec engine] [-ed enginedirectory] [-en enginename] [-log] [-lf logfile] [-hash value] [-bk book] [-pg =]* [-uci =]*\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; -static const int StringSize = 4096; - -// 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){ - const char *quote; - ini_entry_t *entry; - char tmp[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")){ - if(strchr(entry->value,';')|| strchr(entry->value,'#')|| strchr(entry->value,'"')){ - quote="\""; - }else{ - quote=""; - } - snprintf(tmp,sizeof(tmp),"%s=%s%s%s\n", - entry->name, - quote, - entry->value, - quote); - 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")){ - if(strchr(entry->value,';')|| strchr(entry->value,'#')|| strchr(entry->value,'"')){ - quote="\""; - }else{ - quote=""; - } - snprintf(tmp,sizeof(tmp),"%s=%s%s%s\n", - entry->name, - quote, - entry->value, - quote); - 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; - - 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",""); - } - - // 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"),"")){ - if(ini_parse(ini,option_get_string(Option,"SettingsFile"))){ - my_fatal("main(): Can't open 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",""); - } - } - - // 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"),"")){ - 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); - } - - // start engine - - engine_open(Engine); - if(!engine_active(Engine)){ - my_fatal("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 - - 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"),"")) { - 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"),"")){ - - // 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;isection,"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); - // this is inherited, it probably does not work correctly - if(my_string_case_equal(entry->name,"MultiPV") && - atoi(entry->value)>1){ - Uci->multipv_mode=TRUE; - } - } - } - - - - // 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(): Option: \"%s\" not found\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) { - - stop_search(); - engine_send(Engine,"quit"); - my_log("POLYGLOT Closing engine\n"); - engine_close(Engine); - - } - 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 - + +// main.c + +// includes + +#include +#include +#include +#include +#include + +#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 =]* [-uci =]*\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",""); + } + + // 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"),"")){ + 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",""); + } + } + + // 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"),"")){ + 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"),"")){ + 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"),"")) { + 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"),"")){ + + // 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;isection,"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 +