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