Add forgotten files 1.4.70b
[polyglot.git] / util.c
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
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
59 void my_random_init() {
60    srand(time(NULL));
61 }
62
63 // my_random_int()
64
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
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
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
102 int my_round(double x) {
103
104     return ((int)floor(x+0.5));
105 }
106
107 // my_malloc()
108
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
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
136 void my_free(void * address) {
137
138    ASSERT(address!=NULL);
139
140    free(address);
141 }
142
143 // my_log_open()
144
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
162 void my_log_close() {
163
164    if (LogFile != NULL) fclose(LogFile);
165    LogFile=NULL;
166 }
167
168 // my_log()
169
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
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
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
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
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
278 bool my_string_empty(const char string[]) {
279
280    return string == NULL || string[0] == '\0';
281 }
282
283 // my_string_whitespace()
284
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }