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