1
2 // option.c
3
4 // includes
5
6 #include <stdlib.h>
7 #include <string.h>
8
9 #include "option.h"
10 #include "util.h"
11
12
13 // defines
14
15 #define NNB { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL }
16
17 // constants
18
19 static const bool UseDebug = FALSE;
20
21 // variables
22
23
24 option_list_t Option[1];
25
26 option_t DefaultOptions[] = {
27 // options
28
29 { "SettingsFile", "file","0","0", "polyglot.ini", NULL,0,NNB, PG|XBOARD|XBSEL},
30
31 { "SettingsDir", "path","0","0", "<empty>" , NULL,0,NNB, PG},
32
33 { "OnlyWbOptions", "check","0","0", "true" , NULL,0,NNB, PG|XBOARD},
34
35 { "EngineName", "string","0","0", "<empty>" , NULL,0,NNB, PG},
36 { "EngineDir", "path","0","0", "." , NULL,0,NNB, PG},
37 { "EngineCommand", "string","0","0", "<empty>" , NULL,0,NNB, PG},
38
39 { "Log", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD|XBSEL|UCI},
40 { "LogFile", "file","0","0", "polyglot.log", NULL,0,NNB, PG|XBOARD|XBSEL|UCI},
41
42 { "UCI", "check","0","0", "false" , NULL,0,NNB, PG},
43
44 { "UseNice", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD|UCI},
45 { "NiceValue", "spin", "0","20", "5" , NULL,0,NNB, PG|XBOARD|UCI},
46
47 { "Resign", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD|XBSEL},
48 { "ResignMoves", "spin","0","10000", "3" , NULL,0,NNB, PG|XBOARD|XBSEL},
49 { "ResignScore", "spin","0","10000", "600" , NULL,0,NNB, PG|XBOARD|XBSEL},
50
51 { "MateScore", "spin","0","100000", "10000" , NULL,0,NNB, PG|XBOARD},
52
53 { "Book", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD|XBSEL|UCI},
54 { "BookFile", "file","0","0", "book.bin" , NULL,0,NNB, PG|XBOARD|XBSEL|UCI},
55
56 { "BookRandom", "check","0","0", "true" , NULL,0,NNB, PG|XBOARD|XBSEL|UCI},
57 { "BookDepth", "spin","0","256", "256" , NULL,0,NNB, PG|XBOARD|XBSEL|UCI},
58 { "BookTreshold", "spin","0","1000", "5" , NULL,0,NNB, PG|XBOARD|UCI},
59 { "BookLearn", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD},
60
61 { "KibitzMove", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD},
62 { "KibitzPV", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD},
63
64 { "KibitzCommand", "string","0","0", "tellall" , NULL,0,NNB, PG|XBOARD},
65 { "KibitzDelay", "spin","0","1000", "5" , NULL,0,NNB, PG|XBOARD},
66 { "KibitzInterval", "spin","0","1000", "0" , NULL,0,NNB, PG|XBOARD},
67
68 { "ShowPonder", "check","0","0", "true" , NULL,0,NNB, PG|XBOARD},
69 { "ScoreWhite", "check","0","0", "false" , NULL,0,NNB, PG|XBOARD},
70
71 { "STFudge", "spin","0","1000", "20" , NULL,0,NNB, PG|XBOARD|XBSEL},
72
73 // work-arounds
74
75 { "UCIVersion", "spin","1","2", "2" , NULL,0,NNB, PG|XBOARD},
76 { "CanPonder", "check","1","2", "false" , NULL,0,NNB, PG|XBOARD},
77 { "SyncStop", "check","1","2", "false" , NULL,0,NNB, PG|XBOARD|XBSEL},
78 { "Affinity", "spin","-1","32", "-1" , NULL,0,NNB, PG},
79 { "RepeatPV", "check","0","0", "true" , NULL,0,NNB, PG|XBOARD},
80 { "PromoteWorkAround","check","0","0", "false" , NULL,0,NNB, PG|XBOARD},
81
82 // internal
83
84 { "Chess960", "check","0","0", "false" , NULL,0,NNB, PG},
85
86 // These options flag various hacks in the source to work around
87 // WB quirks. They will eventually all be set to false. Probably
88 // in 4.5.0
89
90 { "WbWorkArounds", "check","0","0", "true" , NULL,0,NNB, PG},
91 { "WbWorkArounds2", "check","0","0", "false" , NULL,0,NNB, PG},
92 { "WbWorkArounds3", "check","0","0", "true" , NULL,0,NNB, PG},
93
94 // Buttons
95
96 { "Save", "save","0","0", "false" , NULL,0,NNB, PG|XBOARD|XBSEL},
97
98 // Sentinel
99
100 { NULL, NULL,"0","0", NULL , NULL,0,NNB, 0},
101
102 };
103
104
105 // functions
106
107 // option_is_ok()
108
option_is_ok(const option_list_t * option)109 bool option_is_ok(const option_list_t *option) {
110 if(option->option_nb<0 || option->option_nb>=OptionNb){
111 return FALSE;
112 }
113 return TRUE;
114 }
115
116 // option_init_pg()
117
option_init_pg()118 void option_init_pg() {
119
120 int i;
121 option_t *p=DefaultOptions;
122 char *home_dir;
123 char SettingsDir[StringSize];
124
125 option_init(Option);
126 while(p){
127 if(p->name){
128 option_insert(Option,p);
129 p++;
130 }else{
131 break;
132 }
133 }
134 for(i=0;i<Option->option_nb;i++){
135 Option->options[i].value=my_strdup(Option->options[i].default_);
136 }
137 #ifndef _WIN32
138 home_dir=getenv("HOME");
139 if(!home_dir){
140 home_dir=".";
141 }
142 snprintf(SettingsDir,sizeof(SettingsDir),"%s/.polyglot",home_dir);
143 SettingsDir[sizeof(SettingsDir)-1]='\0';
144 #else
145 sprintf(SettingsDir,".\\_PG");
146 #endif
147 option_set(Option,"SettingsDir",SettingsDir);
148 option_set_default(Option,"SettingsDir",SettingsDir);
149 }
150
151 // option_init()
152
option_init(option_list_t * option)153 void option_init(option_list_t *option){
154 ASSERT(option!=NULL);
155 option->option_nb=0;
156 option->iter=0;
157 memset(option->options,0,sizeof(option->options));
158 }
159
160 // option_insert()
161
option_insert(option_list_t * option,option_t * new_option)162 void option_insert(option_list_t *option, option_t *new_option){
163 int i;
164 option_t *opt;
165 ASSERT(option!=NULL);
166 ASSERT(new_option!=NULL);
167 ASSERT(new_option->name!=NULL);
168 opt=option_find(option,new_option->name);
169 if(!opt){
170 opt=&option->options[option->option_nb];
171 option->option_nb++;
172 }
173 if(option->option_nb>=OptionNb){
174 my_fatal("option_insert(): option list overflow\n");
175 }
176 if(new_option->name) my_string_set(&opt->name, new_option->name);
177 if(new_option->value) my_string_set(&opt->value, new_option->value);
178 if(new_option->min) my_string_set(&opt->min, new_option->min);
179 if(new_option->max) my_string_set(&opt->max, new_option->max);
180 if(new_option->default_) my_string_set(&opt->default_, new_option->default_);
181 if(new_option->type) my_string_set(&opt->type, new_option->type);
182 opt->var_nb=new_option->var_nb;
183 for(i=0;i<new_option->var_nb;i++){
184 my_string_set(&opt->var[i], new_option->var[i]);
185 }
186 opt->mode=new_option->mode;
187 }
188
189 // option_set()
190
option_set(option_list_t * option,const char name[],const char value[])191 bool option_set(option_list_t *option,
192 const char name[],
193 const char value[]) {
194
195 option_t * opt;
196 ASSERT(option!=NULL);
197 ASSERT(name!=NULL);
198 ASSERT(value!=NULL);
199
200 opt = option_find(option,name);
201 if (opt == NULL) return FALSE;
202
203 if(my_string_case_equal(opt->type,"check")){
204 value=(my_string_equal(value,"1")||
205 my_string_case_equal(value,"true"))?"true":"false";
206 }
207
208 my_string_set(&opt->value,value);
209
210 if (UseDebug) my_log("POLYGLOT OPTION SET \"%s\" -> \"%s\"\n",opt->name,opt->value);
211
212 return TRUE;
213 }
214
215 // option_set_default()
216
option_set_default(option_list_t * option,const char name[],const char value[])217 bool option_set_default(option_list_t *option,
218 const char name[],
219 const char value[]) {
220
221 option_t * opt;
222 ASSERT(name!=NULL);
223 ASSERT(value!=NULL);
224
225 opt = option_find(option,name);
226 if (opt == NULL) return FALSE;
227
228 if(my_string_case_equal(opt->type,"check")){
229 value=(my_string_equal(value,"1")||
230 my_string_case_equal(value,"true"))?"true":"false";
231 }
232
233 my_string_set(&opt->default_,value);
234
235 if (UseDebug) my_log("POLYGLOT OPTION DEFAULT SET \"%s\" -> \"%s\"\n",opt->name,opt->default_);
236
237 return TRUE;
238 }
239
240 // option_get()
241
option_get(option_list_t * option,const char name[])242 const char * option_get(option_list_t *option, const char name[]) {
243
244 option_t * opt;
245
246 ASSERT(name!=NULL);
247
248 opt = option_find(option,name);
249 if (opt == NULL) my_fatal("option_get(): unknown option \"%s\"\n",name);
250 if (UseDebug) my_log("POLYGLOT OPTION GET \"%s\" -> \"%s\"\n",opt->name,opt->value);
251
252 return opt->value;
253 }
254
255 // option_get_default()
256
option_get_default(option_list_t * option,const char name[])257 const char * option_get_default(option_list_t *option, const char name[]) {
258
259 option_t * opt;
260
261 ASSERT(name!=NULL);
262
263 opt = option_find(option,name);
264 if (opt == NULL) my_fatal("option_get(): unknown option \"%s\"\n",name);
265
266 if (UseDebug) my_log("POLYGLOT OPTION GET \"%s\" -> \"%s\"\n",opt->name,opt->value);
267
268 return opt->default_;
269 }
270
271 // option_get_bool()
272
option_get_bool(option_list_t * option,const char name[])273 bool option_get_bool(option_list_t *option, const char name[]) {
274
275 const char * value;
276
277 value = option_get(option,name);
278
279 if (FALSE) {
280 } else if (my_string_case_equal(value,"true") || my_string_case_equal(value,"yes") || my_string_equal(value,"1")) {
281 return TRUE;
282 } else if (my_string_case_equal(value,"false") || my_string_case_equal(value,"no") || my_string_equal(value,"0")) {
283 return FALSE;
284 }
285
286 ASSERT(FALSE);
287
288 return FALSE;
289 }
290
291
292 // option_get_double()
293
option_get_double(option_list_t * option,const char name[])294 double option_get_double(option_list_t *option, const char name[]) {
295
296 const char * value;
297
298 value = option_get(option,name);
299
300 return atof(value);
301 }
302
303 // option_get_int()
304
option_get_int(option_list_t * option,const char name[])305 int option_get_int(option_list_t *option, const char name[]) {
306
307 const char * value;
308
309 value = option_get(option,name);
310
311 return atoi(value);
312 }
313
314 // option_get_string()
315
option_get_string(option_list_t * option,const char name[])316 const char * option_get_string(option_list_t *option, const char name[]) {
317
318 const char * value;
319
320 value = option_get(option,name);
321
322 return value;
323 }
324
325 // option_find()
326
option_find(option_list_t * option,const char name[])327 option_t * option_find(option_list_t *option, const char name[]) {
328
329 option_t * opt;
330 int i;
331
332 ASSERT(name!=NULL);
333 for (i=0; i<option->option_nb; i++){
334 opt=option->options+i;
335 if (my_string_case_equal(opt->name,name)){
336 return opt;
337 }
338 }
339
340 return NULL;
341 }
342
343 // option_start_iter()
344
option_start_iter(option_list_t * option)345 void option_start_iter(option_list_t *option){
346 option->iter=0;
347 }
348
349 // option_next()
350
option_next(option_list_t * option)351 option_t * option_next(option_list_t *option){
352 ASSERT(option->iter<=option->option_nb);
353 if(option->iter==option->option_nb){
354 return NULL;
355 }
356 return &option->options[option->iter++];
357
358 }
359
option_free(option_t * option)360 void option_free(option_t *option){
361 int i;
362 my_string_clear(&option->name);
363 my_string_clear(&option->type);
364 my_string_clear(&option->min);
365 my_string_clear(&option->max);
366 my_string_clear(&option->default_);
367 my_string_clear(&option->value);
368 for(i=0;i<option->var_nb;i++){
369 my_string_clear(&option->var[i]);
370 }
371 option->var_nb=0;
372 option->mode=0;
373 }
374
375 // option_clear()
376
option_clear(option_list_t * option)377 void option_clear(option_list_t *option){
378 int i;
379 for (i = 0; i < option->option_nb; i++) {
380 option_free(option->options+i);
381 }
382 option->option_nb=0;
383 }
384
385 // option_from_ini()
386
option_from_ini(option_list_t * option,ini_t * ini,const char * section)387 void option_from_ini(option_list_t *option,
388 ini_t *ini,
389 const char *section){
390 ini_entry_t *entry;
391 ini_start_iter(ini);
392 while((entry=ini_next(ini))){
393 option_set(option,entry->name,entry->value);
394 option_set_default(option,entry->name,entry->value);
395 }
396 }
397
398 // end of option.cpp
399
400