version 1.4.46b
[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 }\r
154 \r
155 // my_log_close()\r
156 \r
157 void my_log_close() {\r
158 \r
159    if (LogFile != NULL) fclose(LogFile);\r
160    LogFile=NULL;\r
161 }\r
162 \r
163 // my_log()\r
164 \r
165 void my_log(const char format[], ...) {\r
166     \r
167     char string[FormatBufferSize];\r
168     \r
169     ASSERT(format!=NULL);\r
170 \r
171 //  format\r
172 \r
173     CONSTRUCT_ARG_STRING(format,string);\r
174     \r
175 \r
176     if (LogFile != NULL) {\r
177         fprintf(LogFile,"%.3f %s",now_real(),string);\r
178 #ifdef _WIN32\r
179         fflush(LogFile);\r
180 #endif\r
181     }\r
182 }\r
183 \r
184 // my_fatal()\r
185 \r
186 void my_fatal(const char format[], ...) {\r
187 \r
188     char string[FormatBufferSize];\r
189 \r
190     ASSERT(format!=NULL);\r
191 \r
192 // format\r
193 \r
194     CONSTRUCT_ARG_STRING(format,string);\r
195     \r
196     fprintf(stderr,"%s",string);\r
197     my_log("POLYGLOT %s",string);\r
198 \r
199     if (Error) { // recursive error\r
200         my_log("POLYGLOT *** RECURSIVE ERROR ***\n");\r
201         exit(EXIT_FAILURE);\r
202             // abort();\r
203     } else {\r
204         Error = TRUE;\r
205         quit();\r
206     }\r
207 }\r
208 \r
209 // my_file_read_line()\r
210 \r
211 bool my_file_read_line(FILE * file, char string[], int size) {\r
212 \r
213    int src, dst;\r
214    int c;\r
215 \r
216    ASSERT(file!=NULL);\r
217    ASSERT(string!=NULL);\r
218    ASSERT(size>0);\r
219 \r
220    if (fgets(string,size,file) == NULL) {\r
221       if (feof(file)) {\r
222          return FALSE;\r
223       } else { // error\r
224          my_fatal("my_file_read_line(): fgets(): %s\n",strerror(errno));\r
225       }\r
226    }\r
227 \r
228    // remove CRs and LFs\r
229 \r
230    src = 0;\r
231    dst = 0;\r
232    \r
233    while ((c=string[src++]) != '\0') {\r
234       if (c != '\r' && c != '\n') string[dst++] = c;\r
235    }\r
236 \r
237    string[dst] = '\0';\r
238 \r
239    return TRUE;\r
240 }\r
241 \r
242 // my_file_join()\r
243 \r
244 void my_path_join(char *join_path, const char *path, const char *file){\r
245     char separator;\r
246 #ifdef _WIN32\r
247     separator='\\';\r
248 #else\r
249     separator='/';\r
250 #endif\r
251     snprintf(join_path,StringSize,"%s%c%s",path,separator,file);\r
252     join_path[StringSize-1]='\0';\r
253 }\r
254 \r
255 // my_mkdir()\r
256 \r
257 int my_mkdir(const char *path){\r
258     int ret;\r
259 #ifdef _WIN32\r
260     ret=_mkdir(path);\r
261 #else\r
262     ret=mkdir(path,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);\r
263 #endif\r
264     return ret;\r
265 }\r
266 \r
267 \r
268 // my_string_empty()\r
269 \r
270 bool my_string_empty(const char string[]) {\r
271 \r
272    return string == NULL || string[0] == '\0';\r
273 }\r
274 \r
275 // my_string_whitespace()\r
276 \r
277 bool my_string_whitespace(const char string[]){\r
278     int pos=0;\r
279     while(string[pos]!='\0'){\r
280         if(string[pos]!=' ' && string[pos]!='\t'){\r
281             return FALSE;\r
282         }\r
283         pos++;\r
284     }\r
285     return TRUE;\r
286 }\r
287 \r
288 // my_string_equal()\r
289 \r
290 bool my_string_equal(const char string_1[], const char string_2[]) {\r
291 \r
292    ASSERT(string_1!=NULL);\r
293    ASSERT(string_2!=NULL);\r
294 \r
295    return strcmp(string_1,string_2) == 0;\r
296 }\r
297 \r
298 // my_string_case_equal()\r
299 \r
300 bool my_string_case_equal(const char string_1[], const char string_2[]) {\r
301 \r
302    int c1, c2;\r
303 \r
304    ASSERT(string_1!=NULL);\r
305    ASSERT(string_2!=NULL);\r
306 \r
307    while (TRUE) {\r
308 \r
309       c1 = *string_1++;\r
310       c2 = *string_2++;\r
311 \r
312       if (tolower(c1) != tolower(c2)) return FALSE;\r
313       if (c1 == '\0') return TRUE;\r
314    }\r
315 \r
316    return FALSE;\r
317 }\r
318 \r
319 // my_strtolower()\r
320 \r
321 void my_string_tolower(char *dst, const char *src){\r
322   int c;\r
323   ASSERT(src!=NULL);\r
324   ASSERT(dst!=NULL);\r
325   while((c=*(src++))){\r
326     *dst=tolower(c);\r
327     dst++;\r
328   }\r
329   *(dst++)='\0';\r
330 }\r
331 \r
332 // my_string_case_contains()\r
333 \r
334 const char* my_string_case_contains(const char string_1[], const char string_2[]){\r
335    \r
336    char tmp1[StringSize];\r
337    char tmp2[StringSize];\r
338    char *where;\r
339 \r
340 \r
341    ASSERT(string_1!=NULL);\r
342    ASSERT(string_2!=NULL);\r
343 \r
344    my_string_tolower(tmp1,string_1);\r
345    my_string_tolower(tmp2,string_2);\r
346 \r
347    where=strstr(tmp1,tmp2);\r
348    if(where){\r
349       return string_1+(where-tmp1);\r
350    }\r
351    return NULL;\r
352 \r
353   \r
354 }\r
355 \r
356 \r
357 // my_strdup()\r
358 \r
359 char * my_strdup(const char string[]) {\r
360 \r
361    char * address;\r
362 \r
363    ASSERT(string!=NULL);\r
364 \r
365    // strdup() is not ANSI C\r
366 \r
367    address = (char *) my_malloc(strlen(string)+1);\r
368    strcpy(address,string);\r
369 \r
370    return address;\r
371 }\r
372 \r
373 // my_string_clear()\r
374 \r
375 void my_string_clear(const char * * variable) {\r
376 \r
377    ASSERT(variable!=NULL);\r
378 \r
379    if (*variable != NULL) {\r
380       my_free((void*)(*variable));\r
381       *variable = NULL;\r
382    }\r
383 }\r
384 \r
385 // my_string_set()\r
386 \r
387 void my_string_set(const char * * variable, const char string[]) {\r
388 \r
389    ASSERT(variable!=NULL);\r
390    ASSERT(string!=NULL);\r
391 \r
392    if (*variable != NULL) my_free((void*)(*variable));\r
393    *variable = my_strdup(string);\r
394 }\r
395 \r
396 // now_real()\r
397 \r
398 double now_real() {\r
399 #ifndef _WIN32\r
400    struct timeval tv[1];\r
401    struct timezone tz[1];\r
402 \r
403    tz->tz_minuteswest = 0;\r
404    tz->tz_dsttime = 0; // DST_NONE not declared in linux\r
405 \r
406    if (gettimeofday(tv,tz) == -1) {\r
407       my_fatal("now_real(): gettimeofday(): %s\n",strerror(errno));\r
408    }\r
409 \r
410    return tv->tv_sec + tv->tv_usec * 1E-6;\r
411 #else\r
412    struct _timeb timeptr;\r
413    _ftime(&timeptr);\r
414    return(timeptr.time+((double)timeptr.millitm)/1000.0);\r
415 //   return (double) GetTickCount() / 1000.0;  // we can do better here:-)\r
416 #endif\r
417 }\r
418 \r
419 \r
420 // my_timer_reset()\r
421 \r
422 void my_timer_reset(my_timer_t * timer) {\r
423 \r
424    ASSERT(timer!=NULL);\r
425 \r
426    timer->start_real = 0.0;\r
427    timer->elapsed_real = 0.0;\r
428    timer->running = FALSE;\r
429 }\r
430 \r
431 // my_timer_start()\r
432 \r
433 void my_timer_start(my_timer_t * timer) {\r
434 // timer->start_real = 0.0;\r
435    timer->elapsed_real = 0.0;\r
436 // timer->running = FALSE;\r
437    ASSERT(timer!=NULL);\r
438 \r
439    timer->running = TRUE;\r
440    timer->start_real = now_real();\r
441 }\r
442 \r
443 // my_timer_stop()\r
444 \r
445 void my_timer_stop(my_timer_t * timer) {\r
446 \r
447    ASSERT(timer!=NULL);\r
448 \r
449    ASSERT(timer->running);\r
450 \r
451    timer->elapsed_real += now_real() - timer->start_real;\r
452    timer->start_real = 0.0;\r
453    timer->running = FALSE;\r
454 }\r
455 \r
456 // my_timer_elapsed_real()\r
457 \r
458 double my_timer_elapsed_real(const my_timer_t * timer) {\r
459 \r
460    double elapsed;\r
461 \r
462    ASSERT(timer!=NULL);\r
463 \r
464    elapsed = timer->elapsed_real;\r
465    if (timer->running) elapsed += now_real() - timer->start_real;\r
466 \r
467    if (elapsed < 0.0) elapsed = 0.0;\r
468 \r
469    return elapsed;\r
470 }\r
471 \r
472 \r
473 \r