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