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