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