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