My Project
util.c
Go to the documentation of this file.
1
14#include "bit.h"
15#include "board.h"
16#include "move.h"
17#include "util.h"
18#include "options.h"
19#include "const.h"
20
21#include <assert.h>
22#include <limits.h>
23#include <math.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <ctype.h>
27#include <errno.h>
28#include <string.h>
29#include <stdbool.h>
30#include <signal.h>
31#include <time.h>
32
33#if defined(__unix__) || defined(__APPLE__)
34
35#include <unistd.h>
36#include <sys/time.h>
37#include <sys/resource.h>
38#include <sys/stat.h>
39
40#endif // __unix__ || __APPLE__
41
42#if defined(__linux__)
43
44#include <sys/sysinfo.h>
45#include <sched.h>
46
47#endif // __linux__
48
49#if defined(_WIN32)
50
51#include <winsock2.h>
52#include <windows.h>
53#include <sys/types.h>
54#include <sys/stat.h>
55
56#define fileno _fileno
57
58#ifndef S_ISREG
59#define S_ISREG(x) (x & _S_IFREG)
60#endif
61#ifndef S_ISFIFO
62#define S_ISFIFO(x) (x & _S_IFIFO)
63#endif
64
65#endif // _WIN32
66
67#if defined(__unix__) || defined(__APPLE__)
68
75long long real_clock(void)
76{
77#if _POSIX_TIMERS > 0
78 struct timespec tv;
79 clock_gettime(CLOCK_MONOTONIC, &tv);
80 return tv.tv_sec * 1000ULL + tv.tv_nsec / 1000000ULL;
81#else
82 struct timeval tv;
83 gettimeofday(&tv, NULL);
84 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
85#endif
86}
87
94long long cpu_clock(void)
95{
96 struct rusage u;
97 getrusage(RUSAGE_SELF, &u);
98 return 1000 * u.ru_utime.tv_sec + u.ru_utime.tv_usec / 1000;
99}
100
101#elif defined (_WIN32)
102
103long long real_clock(void)
104{
105 return GetTickCount();
106}
107
108long long cpu_clock(void)
109{
110 return GetTickCount();
111}
112
113#endif
114
122long long (*time_clock)(void) = real_clock;
123
131void time_print(long long t, bool justified, FILE* f)
132{
133 int d, h, m, s, c;
134 int sign;
135 const char *space = justified ? " " : "";
136
137
138 if (t < 0) {sign = -1; t = -t;} else sign = +1;
139 d = t / 86400000; t -= d * 86400000LL;
140 h = t / 3600000; t -= h * 3600000;
141 m = t / 60000; t -= m * 60000;
142 s = t / 1000;
143 c = (t - s * 1000);
144
145 if (d) fprintf(f, "%2d:%02d:%02d:%02d.%03d", sign*d, h, m, s, c);
146 else if (h) fprintf(f, "%s%2d:%02d:%02d.%03d", space, sign*h, m, s, c);
147 else fprintf(f, "%s%s%2d:%02d.%03d", space, space, sign*m, s, c);
148}
149
156long long time_read(FILE *f)
157{
158 long long t = 0;
159 int n, c;
160
161 while (isspace(c = getc(f)));
162 ungetc(c, f);
163 n = 0; while (isdigit(c = getc(f))) n = n * 10 + (c - '0');
164 if (c == ':') {
165 t = 60 * n; // time has the form MM:SS ?
166 n = 0; while (isdigit(c = getc(f))) n = n * 10 + (c - '0');
167 if (c == ':') {
168 t = 60 * (t + n); // time has the form HH:MM:SS ?
169 n = 0; while (isdigit(c = getc(f))) n = n * 10 + (c - '0');
170 if (c == ':') {
171 t = 24 * (t + n); // time has the form D:HH:MM:SS ?
172 n = 0; while (isdigit(c = getc(f))) n = n * 10 + (c - '0');
173 }
174 }
175 }
176
177 t = (t + n) * 1000;
178 if (c != '.') return t;
179 n = 0; while (isdigit(c = getc(f))) n = n * 10 + (c - '0');
180 while (n > 1000) n /= 10;
181 t += n;
182 return t;
183}
184
189void time_stamp(FILE *f)
190{
191 time_t t = time(NULL);
192 struct tm *tm;
193 tm = localtime(&t);
194
195 fprintf(f, "[%4d/%2d/%2d %2d:%2d:%2d] ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
196}
197
198
203void relax(int t)
204{
205#if defined(__unix__) || defined(__APPLE__)
206 struct timespec ts;
207 ts.tv_sec = t / 1000;
208 ts.tv_nsec = (t % 1000) * 1000000;
209 nanosleep(&ts, NULL);
210#elif defined(_WIN32)
211 Sleep(t);
212#endif
213}
214
222char* format_scientific(double v, const char *unit, char *f)
223{
224 static const char *multiple = "EPTGMk mµnpfa"; //
225 int u;
226
227 if (fabs(v) < 1e-24) {
228 u = 0;
229 } else {
230 u = floor(log10(fabs(v)) / 3.0);
231 if (u > 6) u = 6; else if (u < -6) u = -6;
232 v /= pow(10, 3 * u);
233 }
234
235 if (fabs(v) - floor(fabs(v)) < 0.01) sprintf(f, " %5.1f %c%s", v, multiple[6 - u], unit);
236 else if (fabs(v + 0.05) < 10.0) sprintf(f, " %5.3f %c%s", v, multiple[6 - u], unit);
237 else if (fabs(v + 0.5) < 100.0) sprintf(f, " %5.2f %c%s", v, multiple[6 - u], unit);
238 else sprintf(f, " %5.1f %c%s", v, multiple[6 - u], unit);
239
240 return f;
241}
242
250void print_scientific(double v, const char *unit, FILE *f)
251{
252 char s[32];
253 fprintf(f, "%s", format_scientific(v, unit, s));
254}
255
256
265char* string_read_line(FILE *f)
266{
267 int c, i, n;
268 char *line;
269
270 n = 256; i = 0;
271 line = (char*) malloc(n);
272 if (line == NULL) fatal_error("Allocation error\n");
273
274 while ((c = getc(f)) != EOF && c != '\n') {
275 line[i++] = (char) c;
276 if (i == n) {
277 n *= 2;
278 line = (char*) realloc(line, n);
279 if (line == NULL) fatal_error("Allocation error\n");
280 }
281 }
282 line[i] = '\0';
283
284 if (i == 0 && c == EOF) {
285 free(line);
286 line = NULL;
287 }
288
289 return line;
290}
291
292
299char* string_duplicate(const char *s)
300{
301 char *d;
302
303 if (s) {
304 const int n = strlen(s) + 1;
305 d = (char*) malloc(n);
306 if (d) memcpy(d, s, n);
307 } else {
308 d = NULL;
309 }
310
311 return d;
312}
313
320long long string_to_time(const char *string)
321{
322 long long t = 0;
323 int n = 0;
324 double x = 0.0;
325
326 if (string) {
327 const char *s = parse_skip_spaces(string);
328 s = parse_int(s, &n);
329 if (*s == ':') {
330 t = 60 * n; // time has the form MM:SS ?
331 s = parse_int(s + 1, &n);
332 if (*s == ':') {
333 t = 60 * (t + n); // time has the form HH:MM:SS ?
334 s = parse_int(s + 1, &n);
335 if (*s == ':') {
336 t = 24 * (t + n); // time has the form D:HH:MM:SS ?
337 s = parse_int(s + 1, &n);
338 }
339 }
340 }
341 if (*s == '.' && isdigit(s[1])) {
342 s = parse_real(s, &x);
343 }
344 t = (t + n + x) * 1000;
345 }
346
347 return t;
348}
349
356{
357 if (s) {
358 do {
359 *s = tolower(*s);
360 } while (*s++);
361 }
362}
363
370{
371 if (s) {
372 do {
373 *s = toupper(*s);
374 } while (*s++);
375 }
376}
377
384int string_to_coordinate(const char *s)
385{
386 int x = NOMOVE;
387
388 if (s && *s) {
389 if (tolower(s[0]) == 'p' && s[1] == '@') s += 2;
390 else if (s[0] == '@') ++s;
391
392 if (tolower(s[0]) == 'p' && (tolower(s[1]) == 'a' || tolower(s[1]) == 's')) x = PASS;
393 else if (s[0] == '@' && s[1] == '@') x = PASS; // xboard pass = "@@@@"
394 else {
395 int c = tolower(s[0]) - 'a';
396 int r = s[1] - '1';
397 if (0 <= c && c <= 7 && 0 <= r && r <= 7) x = r * 8 + c;
398 }
399 }
400
401 return x;
402}
403
411char* string_to_word(char *s)
412{
413 char *w = NULL;
414
415 if (s) {
416 while (*s && isspace(*s++)) ;
417 w = --s;
418 while (*s && !isspace(*s++)) ;
419 *s = '\0';
420 }
421 return w;
422}
423
432bool string_to_boolean(const char *s)
433{
434 if (strcmp(s, "false") == 0
435 || strcmp(s, "off") == 0
436 || strcmp(s, "no") == 0
437 || strcmp(s, "0") == 0) return false;
438
439 if (strcmp(s, "true") == 0
440 || strcmp(s, "on") == 0
441 || strcmp(s, "yes") == 0
442 || strcmp(s, "1") == 0) return true;
443
444 errno = EINVAL;
445 return false;
446}
447
457int string_to_int(const char *s, const int default_value)
458{
459 char *end = (char*) s;
460 long n = 0;
461
462 if (s) n = strtol(s, &end, 10);
463
464 if (end == s) {
465 errno = EINVAL;
466 n = default_value;
467 }
468 if (n < INT_MIN) {
469 n = INT_MIN;
470 errno = ERANGE;
471 } else if (n > INT_MAX) {
472 n = INT_MAX;
473 errno = ERANGE;
474 }
475
476 return (int) n;
477}
478
488double string_to_real(const char *s, const double default_value)
489{
490 char *end = (char*) s;
491 double x = 0.0;
492
493 if (s) x = strtod(s, &end);
494
495 if (end == s) {
496 errno = EINVAL;
497 x = default_value;
498 }
499
500 return x;
501}
502
503/* Parsing functions
504 * They differs from string conversion as they convert a
505 * string but return the next position from that string.
506 */
507
514char* parse_skip_spaces(const char *string)
515{
516 if (string) {
517 while (*string && isspace(*string)) ++string;
518 }
519 return (char*) string;
520}
521
528char* parse_skip_word(const char *string)
529{
530 if (string) {
531 while (*string && isspace(*string)) ++string;
532 while (*string && !isspace(*string)) ++string;
533 while (*string && isspace(*string)) ++string;
534 }
535 return (char*) string;
536}
537
545char* parse_find(const char *string, const int c)
546{
547 if (string) {
548 while (*string && *string != c) ++string;
549 }
550 return (char*) string;
551}
552
562char* parse_word(const char *string, char *word, unsigned int n)
563 {
564 if (string) {
565 string = parse_skip_spaces(string);
566 while (*string && !isspace(*string) && n--) *word++ = *string++;
567 *word = '\0';
568 }
569 return (char*) string;
570}
571
582char* parse_field(const char *string, char *word, unsigned int n, char separator)
583 {
584 if (string) {
585 string = parse_skip_spaces(string);
586 while (*string && *string != separator && n--) *word++ = *string++;
587 if (*string == separator) ++string;
588 *word = '\0';
589 }
590 return (char*) string;
591}
592
604char* parse_line(const char *string, char *line, unsigned int n)
605{
606 const char *s = string;
607 if (s) {
608 while (*s && *s != '\n' && *s != '\r' && n--) *line++ = *s++;
609 if (*s == '\0') s = string;
610 else {
611 while (*s && *s != '\n' && *s != '\r' ) ++s;
612 while (*s == '\r' || *s == '\n') ++s;
613 }
614 }
615 *line = '\0';
616 return (char*) s;
617}
618
627char* parse_move(const char *string, const Board *board, Move *move)
628{
629
630 *move = MOVE_INIT;
631
632 if (string) {
633 char *word = parse_skip_spaces(string);
634 int x = string_to_coordinate(word);
635 move->x = x;
636 move->flipped = flip[x](board->player, board->opponent);
637 if ((x == PASS && board_is_pass(board)) || (move->flipped && !board_is_occupied(board, x))) return word + 2;
638 else if (board_is_pass(board)) {
639 move->x = PASS;
640 move->flipped = 0;
641 } else {
642 move->x = NOMOVE;
643 move->flipped = 0;
644 }
645 }
646 return (char*) string;
647}
648
657char* parse_game(const char *string, const Board *board_init, Line *line)
658{
659 const char *next;
660 Board board[1];
661 Move move[1];
662
663 *board = *board_init;
664
665 while ((next = parse_move(string, board, move)) != string || move->x == PASS) {
666 line_push(line, move->x);
667 board_update(board, move);
668 string = next;
669 }
670
671 return (char *) string;
672}
673
682char* parse_board(const char *string, Board *board, int *player)
683{
684 if (string) {
685 int i;
686 const char *s = parse_skip_spaces(string);
687
688 board->player = board->opponent = 0;
689 for (i = A1; i <= H8; ++i) {
690 if (*s == '\0') return (char*) string;
691 switch (tolower(*s)) {
692 case 'b':
693 case 'x':
694 case '*':
695 board->player |= x_to_bit(i);
696 break;
697 case 'o':
698 case 'w':
699 board->opponent |= x_to_bit(i);
700 break;
701 case '-':
702 case '.':
703 break;
704 default:
705 if (!isspace(*s)) return (char*) string;
706 i--;
707 break;
708 }
709 ++s;
710 }
711 board_check(board);
712
713 for (;*s; ++s) {
714 switch (tolower(*s)) {
715 case 'b':
716 case 'x':
717 case '*':
718 *player = BLACK;
719 return (char*) s + 1;
720 case 'o':
721 case 'w':
722 board_swap_players(board);
723 *player = WHITE;
724 return (char*) s + 1;
725 default:
726 break;
727 }
728 }
729 }
730
731 return (char*) string;
732}
733
741char* parse_boolean(const char *string, bool *result)
742{
743 if (string) {
744 char word[6];
745 bool r;
746 errno = 0;
747 string = parse_word(parse_skip_spaces(string), word, 6);
748 r = string_to_boolean(word);
749 if (errno != EINVAL) *result = r;
750 }
751 return (char*) string;
752}
753
761char* parse_int(const char *string, int *result)
762{
763 if (string) {
764 char *s = parse_skip_spaces(string);
765 char *end = s;
766 long long n = 0;
767
768 if (s) n = strtol(s, &end, 10);
769
770 if (end == s) {
771 errno = EINVAL;
772 n = *result;
773 }
774 if (n < INT_MIN) {
775 n = INT_MIN;
776 errno = ERANGE;
777 } else if (n > INT_MAX) {
778 n = INT_MAX;
779 errno = ERANGE;
780 }
781
782 *result = n;
783
784 return end;
785 }
786 return (char*) string;
787}
788
796char* parse_real(const char *string, double *result)
797{
798 if (string) {
799 char *s = parse_skip_spaces(string);
800 char *end = s;
801 double d = 0;
802
803 if (s) d = strtod(s, &end);
804
805 if (end == s) {
806 errno = EINVAL;
807 d = *result;
808 }
809
810 *result = d;
811
812 return end;
813 }
814 return (char*) string;
815}
816
824char* parse_time(const char *string, long long *t)
825{
826 int n = 0;
827 double x = 0.0;
828
829 *t = 0;
830
831 if (string) {
832 const char *s = parse_skip_spaces(string);
833 s = parse_int(s, &n);
834 if (*s == ':') {
835 *t = 60 * n; // time has the form MM:SS ?
836 s = parse_int(s + 1, &n);
837 if (*s == ':') {
838 *t = 60 * (*t + n); // time has the form HH:MM:SS ?
839 s = parse_int(s + 1, &n);
840 if (*s == ':') {
841 *t = 24 * (*t + n); // time has the form D:HH:MM:SS ?
842 s = parse_int(s + 1, &n);
843 }
844 }
845 }
846 if (*s == '.' && isdigit(s[1])) {
847 s = parse_real(s, &x);
848 assert(0.0 <= x && x < 1.0);
849 }
850 *t = (*t + n + x) * 1000;
851 if (errno != EINVAL && errno != ERANGE) string = s;
852 }
853
854 return (char*) string;
855}
856
857
867char* parse_command(const char *string, char *cmd, char *param, const unsigned int size)
868{
869 string = parse_word(string, cmd, size);
871 if (strcmp(cmd, "set") == 0) {
872 string = parse_word(string, cmd, size);
874 }
875 string = parse_skip_spaces(string);
876 if (*string == '=') string = parse_skip_spaces(string + 1);
877 string = parse_line(string, param, size);
878
879 return (char*) string;
880}
881
888void path_get_dir(const char *path, char *dir)
889{
890 const char *c;
891
892 for (c = path; *c; ++c) ;
893 for (;c >= path && *c != '/'; --c) ;
894
895 while (path <= c) *dir++ = *path++;
896 *dir = '\0';
897}
898
907char* file_add_ext(const char *base, const char *ext, char *file)
908{
909 while (*base) *file++ = *base++;
910 while (*ext) *file++ = *ext++;
911 *file = '\0';
912 return file;
913}
914
922void thread_create2(Thread *thread, void* (*function)(void*), void *data) // modified for iOS by lavox. 2018/1/16
923{
924#if defined(__unix__) || (defined(_WIN32) && defined(USE_PTHREAD)) || defined(__APPLE__)
925 pthread_create(thread, NULL, function, data);
926#elif defined(_WIN32)
927 DWORD id;
928 *thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) function, data, 0, &id);
929#endif
930}
931
940void thread_join(Thread thread)
941{
942#if defined(__unix__) || (defined(_WIN32) && defined(USE_PTHREAD)) || defined(__APPLE__)
943 pthread_join(thread, NULL);
944#elif defined(_WIN32)
945 WaitForSingleObject(thread, INFINITE);
946 CloseHandle(thread);
947#endif
948}
954Thread thread_self(void)
955{
956#if defined(__unix__) || (defined(_WIN32) && defined(USE_PTHREAD)) || defined(__APPLE__)
957 return pthread_self();
958#elif defined(_WIN32)
959 return GetCurrentThread();
960#endif
961}
962
967void thread_set_cpu(Thread thread, int i)
968{
969#if defined(__linux__) && !defined(ANDROID)
970 cpu_set_t cpu;
971
972 CPU_ZERO(&cpu);
973 CPU_SET(i, &cpu);
974 pthread_setaffinity_np(thread, sizeof (cpu_set_t), &cpu);
975#elif defined(_WIN32) && !defined(USE_PTHREAD)
976 SetThreadIdealProcessor(thread, i);
977#else
978 (void) thread; (void) i;
979#endif
980}
981
982
988{
989 int n = 0;
990
991#if defined(ANDROID)
992 char file[64];
993 FILE *f;
994
995 for (n = 0; n < MAX_THREADS; ++n) {
996 sprintf(file, "/sys/devices/system/cpu/cpu%d", n);
997 f = fopen(file, "r");
998 if (f == NULL) {
999 break;
1000 }
1001 fclose(f);
1002 }
1003
1004#elif defined(_SC_NPROCESSORS_ONLN)
1005
1006 n = sysconf(_SC_NPROCESSORS_ONLN);
1007
1008#elif defined(_WIN32)
1009
1010 SYSTEM_INFO info;
1011
1012 GetSystemInfo(&info);
1013 n = info.dwNumberOfProcessors;
1014
1015#elif defined(__APPLE__) /* should also works on any bsd system */
1016
1017 int mib[4];
1018 size_t len;
1019
1020 mib[0] = CTL_HW;
1021 mib[1] = HW_AVAILCPU;
1022 sysctl(mib, 2, &n, &len, NULL, 0);
1023 if (n < 1) {
1024 mib[1] = HW_NCPU;
1025 sysctl( mib, 2, &n, &len, NULL, 0 );
1026 }
1027
1028#endif
1029
1030 if (n < 1) n = 1;
1031
1032 return n;
1033}
1034
1043unsigned long long random_get(Random *random)
1044{
1045 const unsigned long long MASK48 = 0xFFFFFFFFFFFFull;
1046 const unsigned long long A = 0x5DEECE66Dull;
1047 const unsigned long long B = 0xBull;
1048 register unsigned long long r;
1049
1050 random->x = ((A * random->x + B) & MASK48);
1051 r = random->x >> 16;
1052 random->x = ((A * random->x + B) & MASK48);
1053 return (r << 32) | (random->x >> 16);
1054}
1055
1062void random_seed(Random *random, const unsigned long long seed)
1063{
1064 const unsigned long long MASK48 = 0xFFFFFFFFFFFFull;
1065 random->x = (seed & MASK48);
1066}
#define x_to_bit(x)
Definition bit.h:43
void board_update(Board *board, const Move *move)
Update a board.
Definition board.c:469
void board_swap_players(Board *board)
Swap players.
Definition board.c:137
void board_init(Board *board)
Set a board to the starting position.
Definition board.c:280
bool board_is_pass(const Board *board)
Check if current player should pass.
Definition board.c:1191
void board_check(const Board *board)
Check board consistency.
Definition board.c:291
bool board_is_occupied(const Board *board, const int x)
Check if a square is occupied.
Definition board.c:1180
unsigned long long(* flip[BOARD_SIZE+2])(const unsigned long long, const unsigned long long)
Definition flip_bitscan.c:1912
@ PASS
Definition const.h:37
@ NOMOVE
Definition const.h:37
@ A1
Definition const.h:29
@ H8
Definition const.h:36
@ WHITE
Definition const.h:43
@ BLACK
Definition const.h:42
#define MAX_THREADS
Definition const.h:15
void line_push(Line *line, const int x)
Add a move to the sequence.
Definition move.c:561
const Move MOVE_INIT
Definition move.c:25
Definition board.h:26
unsigned long long player
Definition board.h:27
unsigned long long opponent
Definition board.h:27
Definition move.h:35
Definition move.h:20
unsigned long long flipped
Definition move.h:21
int x
Definition move.h:22
Definition util.h:87
unsigned long long x
Definition util.h:88
void time_print(long long t, bool justified, FILE *f)
Print time as "D:HH:MM:SS.CC".
Definition util.c:131
char * parse_move(const char *string, const Board *board, Move *move)
Parse a move.
Definition util.c:627
long long time_read(FILE *f)
read time as "D:HH:MM:SS.C".
Definition util.c:156
void time_stamp(FILE *f)
Print local time.
Definition util.c:189
void string_to_uppercase(char *s)
Change all char of a string to uppercase.
Definition util.c:369
char * string_duplicate(const char *s)
Duplicate a string.
Definition util.c:299
char * file_add_ext(const char *base, const char *ext, char *file)
Add an extension to a string.
Definition util.c:907
void print_scientific(double v, const char *unit, FILE *f)
Print a value with a unit.
Definition util.c:250
bool string_to_boolean(const char *s)
Convert a string into a boolean.
Definition util.c:432
char * parse_int(const char *string, int *result)
Parse an integer.
Definition util.c:761
void thread_create2(Thread *thread, void *(*function)(void *), void *data)
Create a thread.
Definition util.c:922
char * parse_skip_word(const char *string)
Skip word.
Definition util.c:528
void thread_join(Thread thread)
Join a thread.
Definition util.c:940
long long(* time_clock)(void)
Time clock.
Definition util.c:122
int string_to_coordinate(const char *s)
Convert the two first chars of a string into a coordinate.
Definition util.c:384
void string_to_lowercase(char *s)
Change all char of a string to lowercase.
Definition util.c:355
char * parse_field(const char *string, char *word, unsigned int n, char separator)
Parse a field.
Definition util.c:582
char * parse_time(const char *string, long long *t)
parse time as "D:HH:MM:SS.C".
Definition util.c:824
char * parse_real(const char *string, double *result)
Parse a real number (as a double floating point).
Definition util.c:796
char * string_read_line(FILE *f)
Read a line.
Definition util.c:265
void thread_set_cpu(Thread thread, int i)
Choose a single core or cpu to run on, under linux systems, to avoid context changes.
Definition util.c:967
int string_to_int(const char *s, const int default_value)
Convert a string into an integer.
Definition util.c:457
char * parse_command(const char *string, char *cmd, char *param, const unsigned int size)
Parse a command.
Definition util.c:867
int get_cpu_number(void)
Get the number of cpus or cores on the machine.
Definition util.c:987
char * parse_skip_spaces(const char *string)
Skip spaces.
Definition util.c:514
unsigned long long random_get(Random *random)
Pseudo-random number generator.
Definition util.c:1043
double string_to_real(const char *s, const double default_value)
Convert a string into a real number.
Definition util.c:488
void random_seed(Random *random, const unsigned long long seed)
Pseudo-random number seed.
Definition util.c:1062
char * parse_word(const char *string, char *word, unsigned int n)
Parse a word.
Definition util.c:562
char * parse_line(const char *string, char *line, unsigned int n)
Parse a line.
Definition util.c:604
char * format_scientific(double v, const char *unit, char *f)
Format a value with a unit.
Definition util.c:222
char * string_to_word(char *s)
remove spaces from a string.
Definition util.c:411
void relax(int t)
sleep for t ms.
Definition util.c:203
long long string_to_time(const char *string)
Read time as "D:HH:MM:SS.C".
Definition util.c:320
void path_get_dir(const char *path, char *dir)
Extract the directory of a file path.
Definition util.c:888
char * parse_boolean(const char *string, bool *result)
Parse a boolean.
Definition util.c:741
char * parse_find(const char *string, const int c)
Find a char.
Definition util.c:545
char * parse_game(const char *string, const Board *board_init, Line *line)
Parse a sequence of moves.
Definition util.c:657
Thread thread_self(void)
Current thread.
Definition util.c:954
char * parse_board(const char *string, Board *board, int *player)
Parse a board.
Definition util.c:682
Miscellaneous utilities header.
long long real_clock(void)
long long cpu_clock(void)
#define fatal_error(...)
Display an error message as "FATAL_ERROR : file name : function name : line number : ....
Definition util.h:349
#define info(...)
Display a message.
Definition util.h:382
void cpu(void)