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