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