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#include <wchar.h>
56
57#define fileno _fileno
58
59#ifndef S_ISREG
60#define S_ISREG(x) (x & _S_IFREG)
61#endif
62#ifndef S_ISFIFO
63#define S_ISFIFO(x) (x & _S_IFIFO)
64#endif
65
66#endif // _WIN32
67
78FILE* file_open(const char *path, const char *mode)
79{
80#if defined(_WIN32)
81 FILE *f;
82 int n_path, n_mode;
83 wchar_t *wpath, *wmode;
84
85 if (path == NULL || mode == NULL) return NULL;
86
87 n_path = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, -1, NULL, 0);
88 n_mode = MultiByteToWideChar(CP_ACP, 0, mode, -1, NULL, 0);
89 if (n_path > 0 && n_mode > 0) {
90 wpath = (wchar_t*) malloc(n_path * sizeof(*wpath));
91 wmode = (wchar_t*) malloc(n_mode * sizeof(*wmode));
92 if (wpath != NULL && wmode != NULL
93 && MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, -1, wpath, n_path) > 0
94 && MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, n_mode) > 0) {
95 f = _wfopen(wpath, wmode);
96 free(wpath);
97 free(wmode);
98 if (f != NULL) return f;
99 } else {
100 if (wpath) free(wpath);
101 if (wmode) free(wmode);
102 }
103 }
104
105 n_path = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
106 n_mode = MultiByteToWideChar(CP_ACP, 0, mode, -1, NULL, 0);
107 if (n_path <= 0 || n_mode <= 0) return NULL;
108
109 wpath = (wchar_t*) malloc(n_path * sizeof(*wpath));
110 wmode = (wchar_t*) malloc(n_mode * sizeof(*wmode));
111 if (wpath == NULL || wmode == NULL) {
112 if (wpath) free(wpath);
113 if (wmode) free(wmode);
114 return NULL;
115 }
116
117 if (MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, n_path) <= 0
118 || MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, n_mode) <= 0) {
119 free(wpath);
120 free(wmode);
121 return NULL;
122 }
123
124 f = _wfopen(wpath, wmode);
125 free(wpath);
126 free(wmode);
127 return f;
128#else
129 return fopen(path, mode);
130#endif
131}
132
133#if defined(__unix__) || defined(__APPLE__)
134
141long long real_clock(void)
142{
143#if _POSIX_TIMERS > 0
144 struct timespec tv;
145 clock_gettime(CLOCK_MONOTONIC, &tv);
146 return tv.tv_sec * 1000ULL + tv.tv_nsec / 1000000ULL;
147#else
148 struct timeval tv;
149 gettimeofday(&tv, NULL);
150 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
151#endif
152}
153
160long long cpu_clock(void)
161{
162 struct rusage u;
163 getrusage(RUSAGE_SELF, &u);
164 return 1000 * u.ru_utime.tv_sec + u.ru_utime.tv_usec / 1000;
165}
166
167#elif defined (_WIN32)
168
169long long real_clock(void)
170{
171 return GetTickCount();
172}
173
174long long cpu_clock(void)
175{
176 return GetTickCount();
177}
178
179#endif
180
188long long (*time_clock)(void) = real_clock;
189
197void time_print(long long t, bool justified, FILE* f)
198{
199 int d, h, m, s, c;
200 int sign;
201 const char *space = justified ? " " : "";
202
203
204 if (t < 0) {sign = -1; t = -t;} else sign = +1;
205 d = t / 86400000; t -= d * 86400000LL;
206 h = t / 3600000; t -= h * 3600000;
207 m = t / 60000; t -= m * 60000;
208 s = t / 1000;
209 c = (t - s * 1000);
210
211 if (d) fprintf(f, "%2d:%02d:%02d:%02d.%03d", sign*d, h, m, s, c);
212 else if (h) fprintf(f, "%s%2d:%02d:%02d.%03d", space, sign*h, m, s, c);
213 else fprintf(f, "%s%s%2d:%02d.%03d", space, space, sign*m, s, c);
214}
215
222long long time_read(FILE *f)
223{
224 long long t = 0;
225 int n, c;
226
227 while (isspace(c = getc(f)));
228 ungetc(c, f);
229 n = 0; while (isdigit(c = getc(f))) n = n * 10 + (c - '0');
230 if (c == ':') {
231 t = 60 * n; // time has the form MM:SS ?
232 n = 0; while (isdigit(c = getc(f))) n = n * 10 + (c - '0');
233 if (c == ':') {
234 t = 60 * (t + n); // time has the form HH:MM:SS ?
235 n = 0; while (isdigit(c = getc(f))) n = n * 10 + (c - '0');
236 if (c == ':') {
237 t = 24 * (t + n); // time has the form D:HH:MM:SS ?
238 n = 0; while (isdigit(c = getc(f))) n = n * 10 + (c - '0');
239 }
240 }
241 }
242
243 t = (t + n) * 1000;
244 if (c != '.') return t;
245 n = 0; while (isdigit(c = getc(f))) n = n * 10 + (c - '0');
246 while (n > 1000) n /= 10;
247 t += n;
248 return t;
249}
250
255void time_stamp(FILE *f)
256{
257 time_t t = time(NULL);
258 struct tm *tm;
259 tm = localtime(&t);
260
261 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);
262}
263
264
269void relax(int t)
270{
271#if defined(__unix__) || defined(__APPLE__)
272 struct timespec ts;
273 ts.tv_sec = t / 1000;
274 ts.tv_nsec = (t % 1000) * 1000000;
275 nanosleep(&ts, NULL);
276#elif defined(_WIN32)
277 Sleep(t);
278#endif
279}
280
288char* format_scientific(double v, const char *unit, char *f)
289{
290 static const char *multiple = "EPTGMk mµnpfa"; //
291 int u;
292
293 if (fabs(v) < 1e-24) {
294 u = 0;
295 } else {
296 u = floor(log10(fabs(v)) / 3.0);
297 if (u > 6) u = 6; else if (u < -6) u = -6;
298 v /= pow(10, 3 * u);
299 }
300
301 if (fabs(v) - floor(fabs(v)) < 0.01) sprintf(f, " %5.1f %c%s", v, multiple[6 - u], unit);
302 else if (fabs(v + 0.05) < 10.0) sprintf(f, " %5.3f %c%s", v, multiple[6 - u], unit);
303 else if (fabs(v + 0.5) < 100.0) sprintf(f, " %5.2f %c%s", v, multiple[6 - u], unit);
304 else sprintf(f, " %5.1f %c%s", v, multiple[6 - u], unit);
305
306 return f;
307}
308
316void print_scientific(double v, const char *unit, FILE *f)
317{
318 char s[32];
319 fprintf(f, "%s", format_scientific(v, unit, s));
320}
321
322
331char* string_read_line(FILE *f)
332{
333 int c, i, n;
334 char *line;
335
336 n = 256; i = 0;
337 line = (char*) malloc(n);
338 if (line == NULL) fatal_error("Allocation error\n");
339
340 while ((c = getc(f)) != EOF && c != '\n') {
341 line[i++] = (char) c;
342 if (i == n) {
343 n *= 2;
344 line = (char*) realloc(line, n);
345 if (line == NULL) fatal_error("Allocation error\n");
346 }
347 }
348 line[i] = '\0';
349
350 if (i == 0 && c == EOF) {
351 free(line);
352 line = NULL;
353 }
354
355 return line;
356}
357
358
365char* string_duplicate(const char *s)
366{
367 char *d;
368
369 if (s) {
370 const int n = strlen(s) + 1;
371 d = (char*) malloc(n);
372 if (d) memcpy(d, s, n);
373 } else {
374 d = NULL;
375 }
376
377 return d;
378}
379
386long long string_to_time(const char *string)
387{
388 long long t = 0;
389 int n = 0;
390 double x = 0.0;
391
392 if (string) {
393 const char *s = parse_skip_spaces(string);
394 s = parse_int(s, &n);
395 if (*s == ':') {
396 t = 60 * n; // time has the form MM:SS ?
397 s = parse_int(s + 1, &n);
398 if (*s == ':') {
399 t = 60 * (t + n); // time has the form HH:MM:SS ?
400 s = parse_int(s + 1, &n);
401 if (*s == ':') {
402 t = 24 * (t + n); // time has the form D:HH:MM:SS ?
403 s = parse_int(s + 1, &n);
404 }
405 }
406 }
407 if (*s == '.' && isdigit(s[1])) {
408 s = parse_real(s, &x);
409 }
410 t = (t + n + x) * 1000;
411 }
412
413 return t;
414}
415
422{
423 if (s) {
424 do {
425 *s = tolower(*s);
426 } while (*s++);
427 }
428}
429
436{
437 if (s) {
438 do {
439 *s = toupper(*s);
440 } while (*s++);
441 }
442}
443
450int string_to_coordinate(const char *s)
451{
452 int x = NOMOVE;
453
454 if (s && *s) {
455 if (tolower(s[0]) == 'p' && s[1] == '@') s += 2;
456 else if (s[0] == '@') ++s;
457
458 if (tolower(s[0]) == 'p' && (tolower(s[1]) == 'a' || tolower(s[1]) == 's')) x = PASS;
459 else if (s[0] == '@' && s[1] == '@') x = PASS; // xboard pass = "@@@@"
460 else {
461 int c = tolower(s[0]) - 'a';
462 int r = s[1] - '1';
463 if (0 <= c && c <= 7 && 0 <= r && r <= 7) x = r * 8 + c;
464 }
465 }
466
467 return x;
468}
469
477char* string_to_word(char *s)
478{
479 char *w = NULL;
480
481 if (s) {
482 while (*s && isspace(*s++)) ;
483 w = --s;
484 while (*s && !isspace(*s++)) ;
485 *s = '\0';
486 }
487 return w;
488}
489
498bool string_to_boolean(const char *s)
499{
500 if (strcmp(s, "false") == 0
501 || strcmp(s, "off") == 0
502 || strcmp(s, "no") == 0
503 || strcmp(s, "0") == 0) return false;
504
505 if (strcmp(s, "true") == 0
506 || strcmp(s, "on") == 0
507 || strcmp(s, "yes") == 0
508 || strcmp(s, "1") == 0) return true;
509
510 errno = EINVAL;
511 return false;
512}
513
523int string_to_int(const char *s, const int default_value)
524{
525 char *end = (char*) s;
526 long n = 0;
527
528 if (s) n = strtol(s, &end, 10);
529
530 if (end == s) {
531 errno = EINVAL;
532 n = default_value;
533 }
534 if (n < INT_MIN) {
535 n = INT_MIN;
536 errno = ERANGE;
537 } else if (n > INT_MAX) {
538 n = INT_MAX;
539 errno = ERANGE;
540 }
541
542 return (int) n;
543}
544
554double string_to_real(const char *s, const double default_value)
555{
556 char *end = (char*) s;
557 double x = 0.0;
558
559 if (s) x = strtod(s, &end);
560
561 if (end == s) {
562 errno = EINVAL;
563 x = default_value;
564 }
565
566 return x;
567}
568
569/* Parsing functions
570 * They differs from string conversion as they convert a
571 * string but return the next position from that string.
572 */
573
580char* parse_skip_spaces(const char *string)
581{
582 if (string) {
583 while (*string && isspace(*string)) ++string;
584 }
585 return (char*) string;
586}
587
594char* parse_skip_word(const char *string)
595{
596 if (string) {
597 while (*string && isspace(*string)) ++string;
598 while (*string && !isspace(*string)) ++string;
599 while (*string && isspace(*string)) ++string;
600 }
601 return (char*) string;
602}
603
611char* parse_find(const char *string, const int c)
612{
613 if (string) {
614 while (*string && *string != c) ++string;
615 }
616 return (char*) string;
617}
618
628char* parse_word(const char *string, char *word, unsigned int n)
629 {
630 if (string) {
631 string = parse_skip_spaces(string);
632 while (*string && !isspace(*string) && n--) *word++ = *string++;
633 *word = '\0';
634 }
635 return (char*) string;
636}
637
648char* parse_field(const char *string, char *word, unsigned int n, char separator)
649 {
650 if (string) {
651 string = parse_skip_spaces(string);
652 while (*string && *string != separator && n--) *word++ = *string++;
653 if (*string == separator) ++string;
654 *word = '\0';
655 }
656 return (char*) string;
657}
658
670char* parse_line(const char *string, char *line, unsigned int n)
671{
672 const char *s = string;
673 if (s) {
674 while (*s && *s != '\n' && *s != '\r' && n--) *line++ = *s++;
675 if (*s == '\0') s = string;
676 else {
677 while (*s && *s != '\n' && *s != '\r' ) ++s;
678 while (*s == '\r' || *s == '\n') ++s;
679 }
680 }
681 *line = '\0';
682 return (char*) s;
683}
684
693char* parse_move(const char *string, const Board *board, Move *move)
694{
695
696 *move = MOVE_INIT;
697
698 if (string) {
699 char *word = parse_skip_spaces(string);
700 int x = string_to_coordinate(word);
701 move->x = x;
702 move->flipped = flip[x](board->player, board->opponent);
703 if ((x == PASS && board_is_pass(board)) || (move->flipped && !board_is_occupied(board, x))) return word + 2;
704 else if (board_is_pass(board)) {
705 move->x = PASS;
706 move->flipped = 0;
707 } else {
708 move->x = NOMOVE;
709 move->flipped = 0;
710 }
711 }
712 return (char*) string;
713}
714
723char* parse_game(const char *string, const Board *board_init, Line *line)
724{
725 const char *next;
726 Board board[1];
727 Move move[1];
728
729 *board = *board_init;
730
731 while ((next = parse_move(string, board, move)) != string || move->x == PASS) {
732 line_push(line, move->x);
733 board_update(board, move);
734 string = next;
735 }
736
737 return (char *) string;
738}
739
748char* parse_board(const char *string, Board *board, int *player)
749{
750 if (string) {
751 int i;
752 const char *s = parse_skip_spaces(string);
753
754 board->player = board->opponent = 0;
755 for (i = A1; i <= H8; ++i) {
756 if (*s == '\0') return (char*) string;
757 switch (tolower(*s)) {
758 case 'b':
759 case 'x':
760 case '*':
761 board->player |= x_to_bit(i);
762 break;
763 case 'o':
764 case 'w':
765 board->opponent |= x_to_bit(i);
766 break;
767 case '-':
768 case '.':
769 break;
770 default:
771 if (!isspace(*s)) return (char*) string;
772 i--;
773 break;
774 }
775 ++s;
776 }
777 board_check(board);
778
779 for (;*s; ++s) {
780 switch (tolower(*s)) {
781 case 'b':
782 case 'x':
783 case '*':
784 *player = BLACK;
785 return (char*) s + 1;
786 case 'o':
787 case 'w':
788 board_swap_players(board);
789 *player = WHITE;
790 return (char*) s + 1;
791 default:
792 break;
793 }
794 }
795 }
796
797 return (char*) string;
798}
799
807char* parse_boolean(const char *string, bool *result)
808{
809 if (string) {
810 char word[6];
811 bool r;
812 errno = 0;
813 string = parse_word(parse_skip_spaces(string), word, 6);
814 r = string_to_boolean(word);
815 if (errno != EINVAL) *result = r;
816 }
817 return (char*) string;
818}
819
827char* parse_int(const char *string, int *result)
828{
829 if (string) {
830 char *s = parse_skip_spaces(string);
831 char *end = s;
832 long long n = 0;
833
834 if (s) n = strtol(s, &end, 10);
835
836 if (end == s) {
837 errno = EINVAL;
838 n = *result;
839 }
840 if (n < INT_MIN) {
841 n = INT_MIN;
842 errno = ERANGE;
843 } else if (n > INT_MAX) {
844 n = INT_MAX;
845 errno = ERANGE;
846 }
847
848 *result = n;
849
850 return end;
851 }
852 return (char*) string;
853}
854
862char* parse_real(const char *string, double *result)
863{
864 if (string) {
865 char *s = parse_skip_spaces(string);
866 char *end = s;
867 double d = 0;
868
869 if (s) d = strtod(s, &end);
870
871 if (end == s) {
872 errno = EINVAL;
873 d = *result;
874 }
875
876 *result = d;
877
878 return end;
879 }
880 return (char*) string;
881}
882
890char* parse_time(const char *string, long long *t)
891{
892 int n = 0;
893 double x = 0.0;
894
895 *t = 0;
896
897 if (string) {
898 const char *s = parse_skip_spaces(string);
899 s = parse_int(s, &n);
900 if (*s == ':') {
901 *t = 60 * n; // time has the form MM:SS ?
902 s = parse_int(s + 1, &n);
903 if (*s == ':') {
904 *t = 60 * (*t + n); // time has the form HH:MM:SS ?
905 s = parse_int(s + 1, &n);
906 if (*s == ':') {
907 *t = 24 * (*t + n); // time has the form D:HH:MM:SS ?
908 s = parse_int(s + 1, &n);
909 }
910 }
911 }
912 if (*s == '.' && isdigit(s[1])) {
913 s = parse_real(s, &x);
914 assert(0.0 <= x && x < 1.0);
915 }
916 *t = (*t + n + x) * 1000;
917 if (errno != EINVAL && errno != ERANGE) string = s;
918 }
919
920 return (char*) string;
921}
922
923
933char* parse_command(const char *string, char *cmd, char *param, const unsigned int size)
934{
935 string = parse_word(string, cmd, size);
937 if (strcmp(cmd, "set") == 0) {
938 string = parse_word(string, cmd, size);
940 }
941 string = parse_skip_spaces(string);
942 if (*string == '=') string = parse_skip_spaces(string + 1);
943 string = parse_line(string, param, size);
944
945 return (char*) string;
946}
947
954void path_get_dir(const char *path, char *dir)
955{
956 const char *c;
957
958 for (c = path; *c; ++c) ;
959 for (;c >= path && *c != '/'; --c) ;
960
961 while (path <= c) *dir++ = *path++;
962 *dir = '\0';
963}
964
973char* file_add_ext(const char *base, const char *ext, char *file)
974{
975 while (*base) *file++ = *base++;
976 while (*ext) *file++ = *ext++;
977 *file = '\0';
978 return file;
979}
980
988void thread_create2(Thread *thread, void* (*function)(void*), void *data) // modified for iOS by lavox. 2018/1/16
989{
990#if defined(__unix__) || (defined(_WIN32) && defined(USE_PTHREAD)) || defined(__APPLE__)
991 pthread_create(thread, NULL, function, data);
992#elif defined(_WIN32)
993 DWORD id;
994 *thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) function, data, 0, &id);
995#endif
996}
997
1006void thread_join(Thread thread)
1007{
1008#if defined(__unix__) || (defined(_WIN32) && defined(USE_PTHREAD)) || defined(__APPLE__)
1009 pthread_join(thread, NULL);
1010#elif defined(_WIN32)
1011 WaitForSingleObject(thread, INFINITE);
1012 CloseHandle(thread);
1013#endif
1014}
1020Thread thread_self(void)
1021{
1022#if defined(__unix__) || (defined(_WIN32) && defined(USE_PTHREAD)) || defined(__APPLE__)
1023 return pthread_self();
1024#elif defined(_WIN32)
1025 return GetCurrentThread();
1026#endif
1027}
1028
1033void thread_set_cpu(Thread thread, int i)
1034{
1035#if defined(__linux__) && !defined(ANDROID)
1036 cpu_set_t cpu;
1037
1038 CPU_ZERO(&cpu);
1039 CPU_SET(i, &cpu);
1040 pthread_setaffinity_np(thread, sizeof (cpu_set_t), &cpu);
1041#elif defined(_WIN32) && !defined(USE_PTHREAD)
1042 SetThreadIdealProcessor(thread, i);
1043#else
1044 (void) thread; (void) i;
1045#endif
1046}
1047
1048
1054{
1055 int n = 0;
1056
1057#if defined(ANDROID)
1058 char file[64];
1059 FILE *f;
1060
1061 for (n = 0; n < MAX_THREADS; ++n) {
1062 sprintf(file, "/sys/devices/system/cpu/cpu%d", n);
1063 f = fopen(file, "r");
1064 if (f == NULL) {
1065 break;
1066 }
1067 fclose(f);
1068 }
1069
1070#elif defined(_SC_NPROCESSORS_ONLN)
1071
1072 n = sysconf(_SC_NPROCESSORS_ONLN);
1073
1074#elif defined(_WIN32)
1075
1076 SYSTEM_INFO info;
1077
1078 GetSystemInfo(&info);
1079 n = info.dwNumberOfProcessors;
1080
1081#elif defined(__APPLE__) /* should also works on any bsd system */
1082
1083 int mib[4];
1084 size_t len;
1085
1086 mib[0] = CTL_HW;
1087 mib[1] = HW_AVAILCPU;
1088 sysctl(mib, 2, &n, &len, NULL, 0);
1089 if (n < 1) {
1090 mib[1] = HW_NCPU;
1091 sysctl( mib, 2, &n, &len, NULL, 0 );
1092 }
1093
1094#endif
1095
1096 if (n < 1) n = 1;
1097
1098 return n;
1099}
1100
1109unsigned long long random_get(Random *random)
1110{
1111 const unsigned long long MASK48 = 0xFFFFFFFFFFFFull;
1112 const unsigned long long A = 0x5DEECE66Dull;
1113 const unsigned long long B = 0xBull;
1114 register unsigned long long r;
1115
1116 random->x = ((A * random->x + B) & MASK48);
1117 r = random->x >> 16;
1118 random->x = ((A * random->x + B) & MASK48);
1119 return (r << 32) | (random->x >> 16);
1120}
1121
1128void random_seed(Random *random, const unsigned long long seed)
1129{
1130 const unsigned long long MASK48 = 0xFFFFFFFFFFFFull;
1131 random->x = (seed & MASK48);
1132}
#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:88
unsigned long long x
Definition util.h:89
void time_print(long long t, bool justified, FILE *f)
Print time as "D:HH:MM:SS.CC".
Definition util.c:197
char * parse_move(const char *string, const Board *board, Move *move)
Parse a move.
Definition util.c:693
long long time_read(FILE *f)
read time as "D:HH:MM:SS.C".
Definition util.c:222
void time_stamp(FILE *f)
Print local time.
Definition util.c:255
void string_to_uppercase(char *s)
Change all char of a string to uppercase.
Definition util.c:435
char * string_duplicate(const char *s)
Duplicate a string.
Definition util.c:365
char * file_add_ext(const char *base, const char *ext, char *file)
Add an extension to a string.
Definition util.c:973
void print_scientific(double v, const char *unit, FILE *f)
Print a value with a unit.
Definition util.c:316
bool string_to_boolean(const char *s)
Convert a string into a boolean.
Definition util.c:498
char * parse_int(const char *string, int *result)
Parse an integer.
Definition util.c:827
void thread_create2(Thread *thread, void *(*function)(void *), void *data)
Create a thread.
Definition util.c:988
char * parse_skip_word(const char *string)
Skip word.
Definition util.c:594
FILE * file_open(const char *path, const char *mode)
Open a file from a UTF-8 path on Windows.
Definition util.c:78
void thread_join(Thread thread)
Join a thread.
Definition util.c:1006
long long(* time_clock)(void)
Time clock.
Definition util.c:188
int string_to_coordinate(const char *s)
Convert the two first chars of a string into a coordinate.
Definition util.c:450
void string_to_lowercase(char *s)
Change all char of a string to lowercase.
Definition util.c:421
char * parse_field(const char *string, char *word, unsigned int n, char separator)
Parse a field.
Definition util.c:648
char * parse_time(const char *string, long long *t)
parse time as "D:HH:MM:SS.C".
Definition util.c:890
char * parse_real(const char *string, double *result)
Parse a real number (as a double floating point).
Definition util.c:862
char * string_read_line(FILE *f)
Read a line.
Definition util.c:331
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:1033
int string_to_int(const char *s, const int default_value)
Convert a string into an integer.
Definition util.c:523
char * parse_command(const char *string, char *cmd, char *param, const unsigned int size)
Parse a command.
Definition util.c:933
int get_cpu_number(void)
Get the number of cpus or cores on the machine.
Definition util.c:1053
char * parse_skip_spaces(const char *string)
Skip spaces.
Definition util.c:580
unsigned long long random_get(Random *random)
Pseudo-random number generator.
Definition util.c:1109
double string_to_real(const char *s, const double default_value)
Convert a string into a real number.
Definition util.c:554
void random_seed(Random *random, const unsigned long long seed)
Pseudo-random number seed.
Definition util.c:1128
char * parse_word(const char *string, char *word, unsigned int n)
Parse a word.
Definition util.c:628
char * parse_line(const char *string, char *line, unsigned int n)
Parse a line.
Definition util.c:670
char * format_scientific(double v, const char *unit, char *f)
Format a value with a unit.
Definition util.c:288
char * string_to_word(char *s)
remove spaces from a string.
Definition util.c:477
void relax(int t)
sleep for t ms.
Definition util.c:269
long long string_to_time(const char *string)
Read time as "D:HH:MM:SS.C".
Definition util.c:386
void path_get_dir(const char *path, char *dir)
Extract the directory of a file path.
Definition util.c:954
char * parse_boolean(const char *string, bool *result)
Parse a boolean.
Definition util.c:807
char * parse_find(const char *string, const int c)
Find a char.
Definition util.c:611
char * parse_game(const char *string, const Board *board_init, Line *line)
Parse a sequence of moves.
Definition util.c:723
Thread thread_self(void)
Current thread.
Definition util.c:1020
char * parse_board(const char *string, Board *board, int *player)
Parse a board.
Definition util.c:748
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:350
#define info(...)
Display a message.
Definition util.h:383
void cpu(void)