6ac2cf137cc9a1c506163b3099550edf22ff71ba
[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     { NULL,               NULL,"0","0",         NULL        , NULL,0,NNB,  0},\r
82 \r
83 };\r
84 \r
85 \r
86 // functions\r
87 \r
88 // option_is_ok()\r
89 \r
90 bool option_is_ok(const option_list_t *option) {\r
91     if(option->option_nb<0 || option->option_nb>=OptionNb){\r
92         return FALSE;\r
93     }\r
94     return TRUE;\r
95 }\r
96 \r
97 // option_init_pg()\r
98 \r
99 void option_init_pg() {\r
100 \r
101     int i;\r
102     option_t *p=DefaultOptions;\r
103     \r
104     option_init(Option);\r
105     while(p){\r
106         if(p->name){\r
107             option_insert(Option,p);\r
108             p++;\r
109         }else{\r
110             break;\r
111         }\r
112     }\r
113     for(i=0;i<Option->option_nb;i++){\r
114         Option->options[i].value=my_strdup(Option->options[i].default_);\r
115     }\r
116 }\r
117 \r
118 // option_init()\r
119 \r
120 void option_init(option_list_t *option){\r
121     ASSERT(option!=NULL);\r
122     option->option_nb=0;\r
123     option->iter=0;\r
124     memset(option->options,0,sizeof(option->options));\r
125 }\r
126 \r
127 // option_insert()\r
128 \r
129 void option_insert(option_list_t *option, option_t *new_option){\r
130     int i;\r
131     option_t *opt;\r
132     ASSERT(option!=NULL);\r
133     ASSERT(new_option!=NULL);\r
134     ASSERT(new_option->name!=NULL);\r
135     opt=option_find(option,new_option->name);\r
136     if(!opt){\r
137         opt=&option->options[option->option_nb];\r
138         option->option_nb++;\r
139     }\r
140     if(option->option_nb>=OptionNb){\r
141         my_fatal("option_insert(): option list overflow\n");\r
142     }\r
143     if(new_option->name)     my_string_set(&opt->name,     new_option->name);\r
144     if(new_option->value)    my_string_set(&opt->value,    new_option->value);\r
145     if(new_option->min)      my_string_set(&opt->min,      new_option->min);\r
146     if(new_option->max)      my_string_set(&opt->max,      new_option->max);\r
147     if(new_option->default_) my_string_set(&opt->default_, new_option->default_);\r
148     if(new_option->type)     my_string_set(&opt->type,     new_option->type);\r
149     opt->var_nb=new_option->var_nb;\r
150     for(i=0;i<new_option->var_nb;i++){\r
151         my_string_set(&opt->var[i], new_option->var[i]);\r
152     }\r
153     opt->mode=new_option->mode;\r
154 }\r
155 \r
156 // option_set()\r
157 \r
158 bool option_set(option_list_t *option, \r
159                 const char name[], \r
160                 const char value[]) {\r
161 \r
162    option_t * opt;\r
163    ASSERT(option!=NULL);\r
164    ASSERT(name!=NULL);\r
165    ASSERT(value!=NULL);\r
166 \r
167    opt = option_find(option,name);\r
168    if (opt == NULL) return FALSE;\r
169 \r
170    my_string_set(&opt->value,value);\r
171 \r
172    if (UseDebug) my_log("POLYGLOT OPTION SET \"%s\" -> \"%s\"\n",opt->name,opt->value);\r
173 \r
174    return TRUE;\r
175 }\r
176 \r
177 // option_set_default()\r
178 \r
179 bool option_set_default(option_list_t *option,\r
180                            const char name[], \r
181                            const char value[]) {\r
182 \r
183    option_t * opt;\r
184    ASSERT(name!=NULL);\r
185    ASSERT(value!=NULL);\r
186 \r
187    opt = option_find(option,name);\r
188    if (opt == NULL) return FALSE;\r
189 \r
190    my_string_set(&opt->default_,value);\r
191 \r
192    if (UseDebug) my_log("POLYGLOT OPTION DEFAULT SET \"%s\" -> \"%s\"\n",opt->name,opt->default_);\r
193 \r
194    return TRUE;\r
195 }\r
196 \r
197 // option_get()\r
198 \r
199 const char * option_get(option_list_t *option, const char name[]) {\r
200 \r
201    option_t * opt;\r
202 \r
203    ASSERT(name!=NULL);\r
204 \r
205    opt = option_find(option,name);\r
206    if (opt == NULL) my_fatal("option_get(): unknown option \"%s\"\n",name);\r
207    if (UseDebug) my_log("POLYGLOT OPTION GET \"%s\" -> \"%s\"\n",opt->name,opt->value);\r
208 \r
209    return opt->value;\r
210 }\r
211 \r
212 // option_get_default()\r
213 \r
214 const char * option_get_default(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 \r
223    if (UseDebug) my_log("POLYGLOT OPTION GET \"%s\" -> \"%s\"\n",opt->name,opt->value);\r
224 \r
225    return opt->default_;\r
226 }\r
227 \r
228 // option_get_bool()\r
229 \r
230 bool option_get_bool(option_list_t *option, const char name[]) {\r
231 \r
232    const char * value;\r
233 \r
234    value = option_get(option,name);\r
235 \r
236    if (FALSE) {\r
237    } else if (my_string_case_equal(value,"true") || my_string_case_equal(value,"yes") || my_string_equal(value,"1")) {\r
238       return TRUE;\r
239    } else if (my_string_case_equal(value,"false") || my_string_case_equal(value,"no") || my_string_equal(value,"0")) {\r
240       return FALSE;\r
241    }\r
242 \r
243    ASSERT(FALSE);\r
244 \r
245    return FALSE;\r
246 }\r
247 \r
248 \r
249 // option_get_double()\r
250 \r
251 double option_get_double(option_list_t *option, const char name[]) {\r
252 \r
253    const char * value;\r
254 \r
255    value = option_get(option,name);\r
256 \r
257    return atof(value);\r
258 }\r
259 \r
260 // option_get_int()\r
261 \r
262 int option_get_int(option_list_t *option, const char name[]) {\r
263 \r
264    const char * value;\r
265 \r
266    value = option_get(option,name);\r
267 \r
268    return atoi(value);\r
269 }\r
270 \r
271 // option_get_string()\r
272 \r
273 const char * option_get_string(option_list_t *option, const char name[]) {\r
274 \r
275    const char * value;\r
276 \r
277    value = option_get(option,name);\r
278 \r
279    return value;\r
280 }\r
281 \r
282 // option_find()\r
283 \r
284 option_t * option_find(option_list_t *option, const char name[]) {\r
285 \r
286    option_t * opt;\r
287    int i;\r
288 \r
289    ASSERT(name!=NULL);\r
290    for (i=0; i<option->option_nb; i++){\r
291        opt=option->options+i;\r
292        if (my_string_case_equal(opt->name,name)){\r
293            return opt;\r
294        }\r
295    }\r
296    \r
297    return NULL;\r
298 }\r
299 \r
300 // option_start_iter()\r
301 \r
302 void option_start_iter(option_list_t *option){\r
303     option->iter=0;\r
304 }\r
305 \r
306 // option_next()\r
307 \r
308 option_t * option_next(option_list_t *option){\r
309     ASSERT(option->iter<=option->option_nb);\r
310     if(option->iter==option->option_nb){\r
311         return NULL;\r
312     }\r
313     return &option->options[option->iter++];\r
314         \r
315 }\r
316 \r
317 void option_free(option_t *option){\r
318       int i;\r
319       my_string_clear(&option->name);\r
320       my_string_clear(&option->type);\r
321       my_string_clear(&option->min);\r
322       my_string_clear(&option->max);\r
323       my_string_clear(&option->default_);\r
324       my_string_clear(&option->value);\r
325       for(i=0;i<option->var_nb;i++){\r
326          my_string_clear(&option->var[i]);\r
327       }\r
328       option->var_nb=0;\r
329       option->mode=0;\r
330 }\r
331 \r
332 // option_clear()\r
333 \r
334 void option_clear(option_list_t *option){\r
335     int i;\r
336     for (i = 0; i < option->option_nb; i++) {\r
337         option_free(option->options+i);\r
338    }\r
339    option->option_nb=0;\r
340 }\r
341 \r
342 // option_from_ini()\r
343 \r
344 void option_from_ini(option_list_t *option,\r
345                      ini_t *ini,\r
346                      const char *section){\r
347     ini_entry_t *entry;\r
348     ini_start_iter(ini);\r
349     while((entry=ini_next(ini))){\r
350         option_set(option,entry->name,entry->value);\r
351         option_set_default(option,entry->name,entry->value);\r
352     }\r
353 }\r
354 \r
355 // end of option.cpp\r
356 \r