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