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