version 1.4w10UCIb16
[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    LogFile=NULL;\r
149 }\r
150 \r
151 // my_log()\r
152 \r
153 void my_log(const char format[], ...) {\r
154 \r
155    va_list ap;\r
156 \r
157    ASSERT(format!=NULL);\r
158 \r
159    if (LogFile != NULL) {\r
160       fprintf(LogFile,"%.3f ",now_real());\r
161       va_start(ap,format);\r
162 \r
163       vfprintf(LogFile,format,ap);\r
164       va_end(ap);\r
165 #ifdef _WIN32\r
166       fflush(LogFile);\r
167 #endif\r
168    }\r
169 }\r
170 \r
171 // my_fatal()\r
172 \r
173 void my_fatal(const char format[], ...) {\r
174 \r
175    va_list ap;\r
176 \r
177    ASSERT(format!=NULL);\r
178 \r
179    va_start(ap,format);\r
180 \r
181    vfprintf(stderr,format,ap);\r
182    if (LogFile != NULL) vfprintf(LogFile,format,ap);\r
183 \r
184    va_end(ap);\r
185    if (Error) { // recursive error\r
186       my_log("POLYGLOT *** RECURSIVE ERROR ***\n");\r
187       exit(EXIT_FAILURE);\r
188       // abort();\r
189    } else {\r
190       Error = true;\r
191       quit();\r
192    }\r
193 }\r
194 \r
195 // my_file_read_line()\r
196 \r
197 bool my_file_read_line(FILE * file, char string[], int size) {\r
198 \r
199    int src, dst;\r
200    int c;\r
201 \r
202    ASSERT(file!=NULL);\r
203    ASSERT(string!=NULL);\r
204    ASSERT(size>0);\r
205 \r
206    if (fgets(string,size,file) == NULL) {\r
207       if (feof(file)) {\r
208          return false;\r
209       } else { // error\r
210          my_fatal("my_file_read_line(): fgets(): %s\n",strerror(errno));\r
211       }\r
212    }\r
213 \r
214    // remove CRs and LFs\r
215 \r
216    src = 0;\r
217    dst = 0;\r
218    \r
219    while ((c=string[src++]) != '\0') {\r
220       if (c != '\r' && c != '\n') string[dst++] = c;\r
221    }\r
222 \r
223    string[dst] = '\0';\r
224 \r
225    return true;\r
226 }\r
227 \r
228 // my_string_empty()\r
229 \r
230 bool my_string_empty(const char string[]) {\r
231 \r
232    return string == NULL || string[0] == '\0';\r
233 }\r
234 \r
235 // my_string_whitespace()\r
236 \r
237 bool my_string_whitespace(const char string[]){\r
238     int pos=0;\r
239     while(string[pos]!='\0'){\r
240         if(string[pos]!=' ' && string[pos]!='\t'){\r
241             return false;\r
242         }\r
243         pos++;\r
244     }\r
245     return true;\r
246 }\r
247 \r
248 // my_string_equal()\r
249 \r
250 bool my_string_equal(const char string_1[], const char string_2[]) {\r
251 \r
252    ASSERT(string_1!=NULL);\r
253    ASSERT(string_2!=NULL);\r
254 \r
255    return strcmp(string_1,string_2) == 0;\r
256 }\r
257 \r
258 // my_string_case_equal()\r
259 \r
260 bool my_string_case_equal(const char string_1[], const char string_2[]) {\r
261 \r
262    int c1, c2;\r
263 \r
264    ASSERT(string_1!=NULL);\r
265    ASSERT(string_2!=NULL);\r
266 \r
267    while (true) {\r
268 \r
269       c1 = *string_1++;\r
270       c2 = *string_2++;\r
271 \r
272       if (tolower(c1) != tolower(c2)) return false;\r
273       if (c1 == '\0') return true;\r
274    }\r
275 \r
276    return false;\r
277 }\r
278 \r
279 // my_strdup()\r
280 \r
281 char * my_strdup(const char string[]) {\r
282 \r
283    char * address;\r
284 \r
285    ASSERT(string!=NULL);\r
286 \r
287    // strdup() is not ANSI C\r
288 \r
289    address = (char *) my_malloc(strlen(string)+1);\r
290    strcpy(address,string);\r
291 \r
292    return address;\r
293 }\r
294 \r
295 // my_string_clear()\r
296 \r
297 void my_string_clear(const char * * variable) {\r
298 \r
299    ASSERT(variable!=NULL);\r
300 \r
301    if (*variable != NULL) {\r
302       my_free((void*)(*variable));\r
303       *variable = NULL;\r
304    }\r
305 }\r
306 \r
307 // my_string_set()\r
308 \r
309 void my_string_set(const char * * variable, const char string[]) {\r
310 \r
311    ASSERT(variable!=NULL);\r
312    ASSERT(string!=NULL);\r
313 \r
314    if (*variable != NULL) my_free((void*)(*variable));\r
315    *variable = my_strdup(string);\r
316 }\r
317 \r
318 // my_timer_reset()\r
319 \r
320 void my_timer_reset(my_timer_t * timer) {\r
321 \r
322    ASSERT(timer!=NULL);\r
323 \r
324    timer->start_real = 0.0;\r
325    timer->elapsed_real = 0.0;\r
326    timer->running = false;\r
327 }\r
328 \r
329 // my_timer_start()\r
330 \r
331 void my_timer_start(my_timer_t * timer) {\r
332 // timer->start_real = 0.0;\r
333    timer->elapsed_real = 0.0;\r
334 // timer->running = false;\r
335    ASSERT(timer!=NULL);\r
336 \r
337    timer->running = true;\r
338    timer->start_real = now_real();\r
339 }\r
340 \r
341 // my_timer_stop()\r
342 \r
343 void my_timer_stop(my_timer_t * timer) {\r
344 \r
345    ASSERT(timer!=NULL);\r
346 \r
347    ASSERT(timer->running);\r
348 \r
349    timer->elapsed_real += now_real() - timer->start_real;\r
350    timer->start_real = 0.0;\r
351    timer->running = false;\r
352 }\r
353 \r
354 // my_timer_elapsed_real()\r
355 \r
356 double my_timer_elapsed_real(const my_timer_t * timer) {\r
357 \r
358    double elapsed;\r
359 \r
360    ASSERT(timer!=NULL);\r
361 \r
362    elapsed = timer->elapsed_real;\r
363    if (timer->running) elapsed += now_real() - timer->start_real;\r
364 \r
365    if (elapsed < 0.0) elapsed = 0.0;\r
366 \r
367    return elapsed;\r
368 }\r