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