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