1 /* util.cpp
2
3 GNU Chess protocol adapter
4
5 Copyright (C) 2001-2011 Free Software Foundation, Inc.
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21
22 // util.cpp
23
24 // includes
25
26 #include <cctype>
27 #include <cerrno>
28 #include <cmath>
29 #include <cstdarg>
30 #include <cstdio>
31 #include <cstdlib>
32 #include <cstring>
33 #include <ctime>
34
35 #include "main.h"
36 #include "posix.h"
37 #include "util.h"
38 #include "configmake.h"
39
40 namespace adapter {
41
42 // constant variables
43
44 const int MaxFileNameSize = 256;
45
46 // variables
47
48 static bool Error;
49
50 static FILE * LogFile;
51
52 // functions
53
54 // util_init()
55
util_init()56 void util_init() {
57
58 Error = false;
59
60 // init log file
61
62 LogFile = NULL;
63 }
64
65 // my_random_init()
66
my_random_init()67 void my_random_init() {
68
69 srand(time(NULL));
70 }
71
72 // my_random_int()
73
my_random_int(int n)74 int my_random_int(int n) {
75
76 int r;
77
78 ASSERT(n>0);
79
80 r = int(floor(my_random_double()*double(n)));
81 ASSERT(r>=0&&r<n);
82
83 return r;
84 }
85
86 // my_random_double()
87
my_random_double()88 double my_random_double() {
89
90 double r;
91
92 r = double(rand()) / (double(RAND_MAX) + 1.0);
93 ASSERT(r>=0.0&&r<1.0);
94
95 return r;
96 }
97
98 // my_atoll()
99
my_atoll(const char string[])100 sint64 my_atoll(const char string[]) {
101
102 sint64 n;
103
104 sscanf(string,S64_FORMAT,&n);
105
106 return n;
107 }
108
109 // my_round()
110
my_round(double x)111 int my_round(double x) {
112
113 return int(floor(x+0.5));
114 }
115
116 // my_malloc()
117
my_malloc(int size)118 void * my_malloc(int size) {
119
120 void * address;
121
122 ASSERT(size>0);
123
124 address = malloc(size);
125 if (address == NULL) my_fatal("my_malloc(): malloc(): %s\n",strerror(errno));
126
127 return address;
128 }
129
130 // my_realloc()
131
my_realloc(void * address,int size)132 void * my_realloc(void * address, int size) {
133
134 ASSERT(address!=NULL);
135 ASSERT(size>0);
136
137 address = realloc(address,size);
138 if (address == NULL) my_fatal("my_realloc(): realloc(): %s\n",strerror(errno));
139
140 return address;
141 }
142
143 // my_free()
144
my_free(void * address)145 void my_free(void * address) {
146
147 ASSERT(address!=NULL);
148
149 free(address);
150 }
151
152 // my_log_open()
153
my_log_open(const char file_name[])154 void my_log_open(const char file_name[]) {
155
156 ASSERT(file_name!=NULL);
157
158 LogFile = fopen(file_name,"a");
159
160 if (LogFile != NULL) setvbuf(LogFile,NULL,_IOLBF,0); // line buffering
161 }
162
163 // my_log_close()
164
my_log_close()165 void my_log_close() {
166
167 if (LogFile != NULL) fclose(LogFile);
168 }
169
170 // my_log()
171
my_log(const char format[],...)172 void my_log(const char format[], ...) {
173
174 va_list ap;
175
176 ASSERT(format!=NULL);
177
178 if (LogFile != NULL) {
179 va_start(ap,format);
180 vfprintf(LogFile,format,ap);
181 va_end(ap);
182 }
183 }
184
185 // my_fatal()
186
my_fatal(const char format[],...)187 void my_fatal(const char format[], ...) {
188
189 va_list ap;
190
191 ASSERT(format!=NULL);
192
193 va_start(ap,format);
194
195 vfprintf(stderr,format,ap);
196 if (LogFile != NULL) vfprintf(LogFile,format,ap);
197
198 va_end(ap);
199
200 if (Error) { // recursive error
201 my_log("POLYGLOT *** RECURSIVE ERROR ***\n");
202 exit(EXIT_FAILURE);
203 // abort();
204 } else {
205 Error = true;
206 quit();
207 }
208 }
209
210 // my_file_read_line()
211
my_file_read_line(FILE * file,char string[],int size)212 bool my_file_read_line(FILE * file, char string[], int size) {
213
214 int src, dst;
215 int c;
216
217 ASSERT(file!=NULL);
218 ASSERT(string!=NULL);
219 ASSERT(size>0);
220
221 if (fgets(string,size,file) == NULL) {
222 if (feof(file)) {
223 return false;
224 } else { // error
225 my_fatal("my_file_read_line(): fgets(): %s\n",strerror(errno));
226 }
227 }
228
229 // remove CRs and LFs
230
231 src = 0;
232 dst = 0;
233
234 while ((c=string[src++]) != '\0') {
235 if (c != '\r' && c != '\n') string[dst++] = c;
236 }
237
238 string[dst] = '\0';
239
240 return true;
241 }
242
243 // my_string_empty()
244
my_string_empty(const char string[])245 bool my_string_empty(const char string[]) {
246
247 return string == NULL || string[0] == '\0';
248 }
249
250 // my_string_equal()
251
my_string_equal(const char string_1[],const char string_2[])252 bool my_string_equal(const char string_1[], const char string_2[]) {
253
254 ASSERT(string_1!=NULL);
255 ASSERT(string_2!=NULL);
256
257 return strcmp(string_1,string_2) == 0;
258 }
259
260 // my_string_case_equal()
261
my_string_case_equal(const char string_1[],const char string_2[])262 bool my_string_case_equal(const char string_1[], const char string_2[]) {
263
264 int c1, c2;
265
266 ASSERT(string_1!=NULL);
267 ASSERT(string_2!=NULL);
268
269 while (true) {
270
271 c1 = *string_1++;
272 c2 = *string_2++;
273
274 if (tolower(c1) != tolower(c2)) return false;
275 if (c1 == '\0') return true;
276 }
277
278 return false;
279 }
280
281 // my_strdup()
282
my_strdup(const char string[])283 char * my_strdup(const char string[]) {
284
285 char * address;
286
287 ASSERT(string!=NULL);
288
289 // strdup() is not ANSI C
290
291 address = (char *) my_malloc(strlen(string)+1);
292 strcpy(address,string);
293
294 return address;
295 }
296
297 // my_string_clear()
298
my_string_clear(const char ** variable)299 void my_string_clear(const char * * variable) {
300
301 ASSERT(variable!=NULL);
302
303 if (*variable != NULL) {
304 my_free((void*)(*variable));
305 *variable = NULL;
306 }
307 }
308
309 // my_string_set()
310
my_string_set(const char ** variable,const char string[])311 void my_string_set(const char * * variable, const char string[]) {
312
313 ASSERT(variable!=NULL);
314 ASSERT(string!=NULL);
315
316 if (*variable != NULL) my_free((void*)(*variable));
317 *variable = my_strdup(string);
318 }
319
320 // my_timer_reset()
321
my_timer_reset(my_timer_t * timer)322 void my_timer_reset(my_timer_t * timer) {
323
324 ASSERT(timer!=NULL);
325
326 timer->start_real = 0.0;
327 timer->start_cpu = 0.0;
328 timer->elapsed_real = 0.0;
329 timer->elapsed_cpu = 0.0;
330 timer->running = false;
331 }
332
333 // my_timer_start()
334
my_timer_start(my_timer_t * timer)335 void my_timer_start(my_timer_t * timer) {
336
337 ASSERT(timer!=NULL);
338
339 ASSERT(timer->start_real==0.0);
340 ASSERT(timer->start_cpu==0.0);
341 ASSERT(!timer->running);
342
343 timer->running = true;
344 timer->start_real = now_real();
345 timer->start_cpu = now_cpu();
346 }
347
348 // my_timer_stop()
349
my_timer_stop(my_timer_t * timer)350 void my_timer_stop(my_timer_t * timer) {
351
352 ASSERT(timer!=NULL);
353
354 ASSERT(timer->running);
355
356 timer->elapsed_real += now_real() - timer->start_real;
357 timer->elapsed_cpu += now_cpu() - timer->start_cpu;
358 timer->start_real = 0.0;
359 timer->start_cpu = 0.0;
360 timer->running = false;
361 }
362
363 // my_timer_elapsed_real()
364
my_timer_elapsed_real(const my_timer_t * timer)365 double my_timer_elapsed_real(const my_timer_t * timer) {
366
367 double elapsed;
368
369 ASSERT(timer!=NULL);
370
371 elapsed = timer->elapsed_real;
372 if (timer->running) elapsed += now_real() - timer->start_real;
373
374 if (elapsed < 0.0) elapsed = 0.0;
375
376 return elapsed;
377 }
378
379 // my_timer_elapsed_cpu()
380
my_timer_elapsed_cpu(const my_timer_t * timer)381 double my_timer_elapsed_cpu(const my_timer_t * timer) {
382
383 double elapsed;
384
385 ASSERT(timer!=NULL);
386
387 elapsed = timer->elapsed_cpu;
388 if (timer->running) elapsed += now_cpu() - timer->start_cpu;
389
390 if (elapsed < 0.0) elapsed = 0.0;
391
392 return elapsed;
393 }
394
395 // my_timer_cpu_usage()
396
my_timer_cpu_usage(const my_timer_t * timer)397 double my_timer_cpu_usage(const my_timer_t * timer) {
398
399 double real, cpu;
400 double usage;
401
402 ASSERT(timer!=NULL);
403
404 real = my_timer_elapsed_real(timer);
405 cpu = my_timer_elapsed_cpu(timer);
406
407 if (real <= 0.0 || cpu <= 0.0) return 0.0;
408
409 usage = cpu / real;
410 if (usage >= 1.0) usage = 1.0;
411
412 return usage;
413 }
414
415 // compute_pkgdatadir()
416
compute_pkgdatadir()417 char const * compute_pkgdatadir ()
418 {
419
420 char const *pkgdatadir = getenv ("GNUCHESS_PKGDATADIR");
421 return pkgdatadir ? pkgdatadir : PKGDATADIR;
422 }
423
424 } // namespace adapter
425
426 // end of util.cpp
427
428