1 
2 // util.c
3 
4 // includes
5 
6 #ifdef _WIN32
7 #include <windows.h>
8 #include <direct.h>
9 #else
10 #include <unistd.h>
11 #endif
12 
13 #include <ctype.h>
14 #include <errno.h>
15 #include <math.h>
16 #include <stdarg.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <time.h>
21 #ifndef _MSC_VER
22 #include <sys/time.h>
23 #endif
24 
25 #include "main.h"
26 #include "util.h"
27 #include "gui.h"
28 
29 // macros
30 
31 #define StringSize 4096
32 
33 // variables
34 
35 static bool Error;
36 
37 FILE * LogFile=NULL;
38 
39 // functions
40 
41 // util_init()
42 
util_init()43 void util_init() {
44 
45    Error = FALSE;
46 
47    // init log file
48 
49    LogFile = NULL;
50 
51    // switch file buffering off
52 
53    setbuf(stdin,NULL);
54    setbuf(stdout,NULL);
55 }
56 
57 // my_random_init()
58 
my_random_init()59 void my_random_init() {
60    srand(time(NULL));
61 }
62 
63 // my_random_int()
64 
my_random_int(int n)65 int my_random_int(int n) {
66 
67    int r;
68 
69    ASSERT(n>0);
70 
71    r = ((int)floor(my_random_double()*((double)n)));
72    ASSERT(r>=0&&r<n);
73 
74    return r;
75 }
76 
77 // my_random_double()
78 
my_random_double()79 double my_random_double() {
80 
81    double r;
82 
83    r = ((double)rand()) / (((double)RAND_MAX) + 1.0);
84    ASSERT(r>=0.0&&r<1.0);
85 
86    return r;
87 }
88 
89 // my_atoll()
90 
my_atoll(const char string[])91 sint64 my_atoll(const char string[]) {
92 
93    sint64 n;
94 
95    sscanf(string,S64_FORMAT,&n);
96 
97    return n;
98 }
99 
100 // my_round()
101 
my_round(double x)102 int my_round(double x) {
103 
104     return ((int)floor(x+0.5));
105 }
106 
107 // my_malloc()
108 
my_malloc(size_t size)109 void * my_malloc(size_t size) {
110 
111    void * address;
112 
113    ASSERT(size>0);
114 
115    address = malloc(size);
116    if (address == NULL) my_fatal("my_malloc(): malloc(): %s\n",strerror(errno));
117 
118    return address;
119 }
120 
121 // my_realloc()
122 
my_realloc(void * address,size_t size)123 void * my_realloc(void * address, size_t size) {
124 
125    ASSERT(address!=NULL);
126    ASSERT(size>0);
127 
128    address = realloc(address,size);
129    if (address == NULL) my_fatal("my_realloc(): realloc(): %s\n",strerror(errno));
130 
131    return address;
132 }
133 
134 // my_free()
135 
my_free(void * address)136 void my_free(void * address) {
137 
138    ASSERT(address!=NULL);
139 
140    free(address);
141 }
142 
143 // my_log_open()
144 
my_log_open(const char file_name[])145 void my_log_open(const char file_name[]) {
146 
147    ASSERT(file_name!=NULL);
148 
149    LogFile = fopen(file_name,"a");
150 #ifndef _WIN32
151 //line buffering doesn't work too well in MSVC and/or windows
152    if (LogFile != NULL) setvbuf(LogFile,NULL,_IOLBF,0); // line buffering
153 #endif
154    if(LogFile!=NULL){
155        my_log("POLYGLOT *** LOGFILE OPENED ***\n");
156    }
157 
158 }
159 
160 // my_log_close()
161 
my_log_close()162 void my_log_close() {
163 
164    if (LogFile != NULL) fclose(LogFile);
165    LogFile=NULL;
166 }
167 
168 // my_log()
169 
my_log(const char format[],...)170 void my_log(const char format[], ...) {
171 
172     char string[FormatBufferSize];
173 
174     ASSERT(format!=NULL);
175 
176 //  format
177 
178     CONSTRUCT_ARG_STRING(format,string);
179 
180 
181     if (LogFile != NULL) {
182         fprintf(LogFile,"%.3f %s",now_real(),string);
183 #ifdef _WIN32
184         fflush(LogFile);
185 #endif
186     }
187 }
188 
189 // my_fatal()
190 
my_fatal(const char format[],...)191 void my_fatal(const char format[], ...) {
192 
193     char string[FormatBufferSize];
194 
195     ASSERT(format!=NULL);
196 
197 // format
198 
199     CONSTRUCT_ARG_STRING(format,string);
200 
201     my_log("POLYGLOT %s",string);
202     // This should be gui_send but this does not work.
203     // Why?
204 
205     printf("tellusererror POLYGLOT: %s",string);
206 
207     if (Error) { // recursive error
208         my_log("POLYGLOT *** RECURSIVE ERROR ***\n");
209         exit(EXIT_FAILURE);
210             // abort();
211     } else {
212       Error = TRUE;
213       quit();
214     }
215 }
216 
217 // my_file_read_line()
218 
my_file_read_line(FILE * file,char string[],int size)219 bool my_file_read_line(FILE * file, char string[], int size) {
220 
221    int src, dst;
222    int c;
223 
224    ASSERT(file!=NULL);
225    ASSERT(string!=NULL);
226    ASSERT(size>0);
227 
228    if (fgets(string,size,file) == NULL) {
229       if (feof(file)) {
230          return FALSE;
231       } else { // error
232          my_fatal("my_file_read_line(): fgets(): %s\n",strerror(errno));
233       }
234    }
235 
236    // remove CRs and LFs
237 
238    src = 0;
239    dst = 0;
240 
241    while ((c=string[src++]) != '\0') {
242       if (c != '\r' && c != '\n') string[dst++] = c;
243    }
244 
245    string[dst] = '\0';
246 
247    return TRUE;
248 }
249 
250 // my_file_join()
251 
my_path_join(char * join_path,const char * path,const char * file)252 void my_path_join(char *join_path, const char *path, const char *file){
253     char separator;
254 #ifdef _WIN32
255     separator='\\';
256 #else
257     separator='/';
258 #endif
259     snprintf(join_path,StringSize,"%s%c%s",path,separator,file);
260     join_path[StringSize-1]='\0';
261 }
262 
263 // my_mkdir()
264 
my_mkdir(const char * path)265 int my_mkdir(const char *path){
266     int ret;
267 #ifdef _WIN32
268     ret=_mkdir(path);
269 #else
270     ret=mkdir(path,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
271 #endif
272     return ret;
273 }
274 
275 
276 // my_string_empty()
277 
my_string_empty(const char string[])278 bool my_string_empty(const char string[]) {
279 
280    return string == NULL || string[0] == '\0';
281 }
282 
283 // my_string_whitespace()
284 
my_string_whitespace(const char string[])285 bool my_string_whitespace(const char string[]){
286     int pos=0;
287     while(string[pos]!='\0'){
288         if(string[pos]!=' ' && string[pos]!='\t'){
289             return FALSE;
290         }
291         pos++;
292     }
293     return TRUE;
294 }
295 
296 // my_string_equal()
297 
my_string_equal(const char string_1[],const char string_2[])298 bool my_string_equal(const char string_1[], const char string_2[]) {
299 
300    ASSERT(string_1!=NULL);
301    ASSERT(string_2!=NULL);
302 
303    return strcmp(string_1,string_2) == 0;
304 }
305 
306 // my_string_case_equal()
307 
my_string_case_equal(const char string_1[],const char string_2[])308 bool my_string_case_equal(const char string_1[], const char string_2[]) {
309 
310    int c1, c2;
311 
312    ASSERT(string_1!=NULL);
313    ASSERT(string_2!=NULL);
314 
315    while (TRUE) {
316 
317       c1 = *string_1++;
318       c2 = *string_2++;
319 
320       if (tolower(c1) != tolower(c2)) return FALSE;
321       if (c1 == '\0') return TRUE;
322    }
323 
324    return FALSE;
325 }
326 
327 // my_strtolower()
328 
my_string_tolower(char * dst,const char * src)329 void my_string_tolower(char *dst, const char *src){
330   int c;
331   ASSERT(src!=NULL);
332   ASSERT(dst!=NULL);
333   while((c=*(src++))){
334     *dst=tolower(c);
335     dst++;
336   }
337   *(dst++)='\0';
338 }
339 
340 // my_string_case_contains()
341 
my_string_case_contains(const char string_1[],const char string_2[])342 const char* my_string_case_contains(const char string_1[], const char string_2[]){
343 
344    char tmp1[StringSize];
345    char tmp2[StringSize];
346    char *where;
347 
348 
349    ASSERT(string_1!=NULL);
350    ASSERT(string_2!=NULL);
351 
352    my_string_tolower(tmp1,string_1);
353    my_string_tolower(tmp2,string_2);
354 
355    where=strstr(tmp1,tmp2);
356    if(where){
357       return string_1+(where-tmp1);
358    }
359    return NULL;
360 
361 
362 }
363 
364 
365 // my_strdup()
366 
my_strdup(const char string[])367 char * my_strdup(const char string[]) {
368 
369    char * address;
370 
371    ASSERT(string!=NULL);
372 
373    // strdup() is not ANSI C
374 
375    address = (char *) my_malloc(strlen(string)+1);
376    strcpy(address,string);
377 
378    return address;
379 }
380 
381 // my_string_clear()
382 
my_string_clear(const char ** variable)383 void my_string_clear(const char * * variable) {
384 
385    ASSERT(variable!=NULL);
386 
387    if (*variable != NULL) {
388       my_free((void*)(*variable));
389       *variable = NULL;
390    }
391 }
392 
393 // my_string_set()
394 
my_string_set(const char ** variable,const char string[])395 void my_string_set(const char * * variable, const char string[]) {
396 
397    ASSERT(variable!=NULL);
398    ASSERT(string!=NULL);
399 
400    if (*variable != NULL) my_free((void*)(*variable));
401    *variable = my_strdup(string);
402 }
403 
404 // now_real()
405 
now_real()406 double now_real() {
407 #ifndef _WIN32
408    struct timeval tv[1];
409    struct timezone tz[1];
410 
411    tz->tz_minuteswest = 0;
412    tz->tz_dsttime = 0; // DST_NONE not declared in linux
413 
414    if (gettimeofday(tv,tz) == -1) {
415       my_fatal("now_real(): gettimeofday(): %s\n",strerror(errno));
416    }
417 
418    return tv->tv_sec + tv->tv_usec * 1E-6;
419 #else
420    struct _timeb timeptr;
421    _ftime(&timeptr);
422    return(timeptr.time+((double)timeptr.millitm)/1000.0);
423 //   return (double) GetTickCount() / 1000.0;  // we can do better here:-)
424 #endif
425 }
426 
427 
428 // my_timer_reset()
429 
my_timer_reset(my_timer_t * timer)430 void my_timer_reset(my_timer_t * timer) {
431 
432    ASSERT(timer!=NULL);
433 
434    timer->start_real = 0.0;
435    timer->elapsed_real = 0.0;
436    timer->running = FALSE;
437 }
438 
439 // my_timer_start()
440 
my_timer_start(my_timer_t * timer)441 void my_timer_start(my_timer_t * timer) {
442 // timer->start_real = 0.0;
443    timer->elapsed_real = 0.0;
444 // timer->running = FALSE;
445    ASSERT(timer!=NULL);
446 
447    timer->running = TRUE;
448    timer->start_real = now_real();
449 }
450 
451 // my_timer_stop()
452 
my_timer_stop(my_timer_t * timer)453 void my_timer_stop(my_timer_t * timer) {
454 
455    ASSERT(timer!=NULL);
456 
457    ASSERT(timer->running);
458 
459    timer->elapsed_real += now_real() - timer->start_real;
460    timer->start_real = 0.0;
461    timer->running = FALSE;
462 }
463 
464 // my_timer_elapsed_real()
465 
my_timer_elapsed_real(const my_timer_t * timer)466 double my_timer_elapsed_real(const my_timer_t * timer) {
467 
468    double elapsed;
469 
470    ASSERT(timer!=NULL);
471 
472    elapsed = timer->elapsed_real;
473    if (timer->running) elapsed += now_real() - timer->start_real;
474 
475    if (elapsed < 0.0) elapsed = 0.0;
476 
477    return elapsed;
478 }
479 
480 
my_dequote(char * out,const char * in,const char * special)481 void my_dequote(char *out, const char *in, const char *special){
482   const char *p;
483   char *q;
484   char c;
485   p=in;
486   q=out;
487   while((c=*(p++))){
488     if(c=='\\' && strchr(special,*p)){
489       *(q++)=*(p++);
490     }else{
491       *(q++)=c;
492     }
493   }
494   *q='\0';
495 }
496 
my_quote(char * out,const char * in,const char * special)497 void my_quote(char *out, const char *in, const char *special){
498   const char *p;
499   char *q;
500   char c;
501   p=in;
502   q=out;
503   while(q-out< StringSize-2 && (c=*(p++))){
504     if(c=='\\'){
505       if(*p!=0 && strchr(special,*p)){
506 	*(q++)='\\';
507       }
508     }else if(strchr(special,c)){
509       *(q++)='\\';
510     }
511     *(q++)=c;
512   }
513   *q='\0';
514 }
515 
516 
my_sleep(int msec)517 void my_sleep(int msec){
518 #ifndef _WIN32
519   struct timespec tm;
520   tm.tv_sec=msec/1000;
521   tm.tv_nsec=1000000*(msec%1000);
522   nanosleep(&tm,NULL);
523 #else
524   Sleep(msec);
525 #endif
526 }
527