33#if defined(__unix__) || defined(__APPLE__)
37#include <sys/resource.h>
44#include <sys/sysinfo.h>
60#define S_ISREG(x) (x & _S_IFREG)
63#define S_ISFIFO(x) (x & _S_IFIFO)
83 wchar_t *wpath, *wmode;
85 if (path == NULL || mode == NULL)
return NULL;
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);
98 if (f != NULL)
return f;
100 if (wpath) free(wpath);
101 if (wmode) free(wmode);
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;
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);
117 if (MultiByteToWideChar(CP_ACP, 0, path, -1, wpath, n_path) <= 0
118 || MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, n_mode) <= 0) {
124 f = _wfopen(wpath, wmode);
129 return fopen(path, mode);
133#if defined(__unix__) || defined(__APPLE__)
145 clock_gettime(CLOCK_MONOTONIC, &tv);
146 return tv.tv_sec * 1000ULL + tv.tv_nsec / 1000000ULL;
149 gettimeofday(&tv, NULL);
150 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
163 getrusage(RUSAGE_SELF, &u);
164 return 1000 * u.ru_utime.tv_sec + u.ru_utime.tv_usec / 1000;
167#elif defined (_WIN32)
171 return GetTickCount();
176 return GetTickCount();
201 const char *space = justified ?
" " :
"";
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;
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);
227 while (isspace(c = getc(f)));
229 n = 0;
while (isdigit(c = getc(f))) n = n * 10 + (c -
'0');
232 n = 0;
while (isdigit(c = getc(f))) n = n * 10 + (c -
'0');
235 n = 0;
while (isdigit(c = getc(f))) n = n * 10 + (c -
'0');
238 n = 0;
while (isdigit(c = getc(f))) n = n * 10 + (c -
'0');
244 if (c !=
'.')
return t;
245 n = 0;
while (isdigit(c = getc(f))) n = n * 10 + (c -
'0');
246 while (n > 1000) n /= 10;
257 time_t t = time(NULL);
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);
271#if defined(__unix__) || defined(__APPLE__)
273 ts.tv_sec = t / 1000;
274 ts.tv_nsec = (t % 1000) * 1000000;
275 nanosleep(&ts, NULL);
290 static const char *multiple =
"EPTGMk mµnpfa";
293 if (fabs(v) < 1e-24) {
296 u = floor(log10(fabs(v)) / 3.0);
297 if (u > 6) u = 6;
else if (u < -6) u = -6;
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);
337 line = (
char*) malloc(n);
338 if (line == NULL)
fatal_error(
"Allocation error\n");
340 while ((c = getc(f)) != EOF && c !=
'\n') {
341 line[i++] = (char) c;
344 line = (
char*) realloc(line, n);
345 if (line == NULL)
fatal_error(
"Allocation error\n");
350 if (i == 0 && c == EOF) {
370 const int n = strlen(s) + 1;
371 d = (
char*) malloc(n);
372 if (d) memcpy(d, s, n);
407 if (*s ==
'.' && isdigit(s[1])) {
410 t = (t + n + x) * 1000;
455 if (tolower(s[0]) ==
'p' && s[1] ==
'@') s += 2;
456 else if (s[0] ==
'@') ++s;
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;
461 int c = tolower(s[0]) -
'a';
463 if (0 <= c && c <= 7 && 0 <= r && r <= 7) x = r * 8 + c;
482 while (*s && isspace(*s++)) ;
484 while (*s && !isspace(*s++)) ;
500 if (strcmp(s,
"false") == 0
501 || strcmp(s,
"off") == 0
502 || strcmp(s,
"no") == 0
503 || strcmp(s,
"0") == 0)
return false;
505 if (strcmp(s,
"true") == 0
506 || strcmp(s,
"on") == 0
507 || strcmp(s,
"yes") == 0
508 || strcmp(s,
"1") == 0)
return true;
525 char *end = (
char*) s;
528 if (s) n = strtol(s, &end, 10);
537 }
else if (n > INT_MAX) {
556 char *end = (
char*) s;
559 if (s) x = strtod(s, &end);
583 while (*
string && isspace(*
string)) ++string;
585 return (
char*) string;
597 while (*
string && isspace(*
string)) ++string;
598 while (*
string && !isspace(*
string)) ++string;
599 while (*
string && isspace(*
string)) ++string;
601 return (
char*) string;
614 while (*
string && *
string != c) ++string;
616 return (
char*) string;
628char*
parse_word(
const char *
string,
char *word,
unsigned int n)
632 while (*
string && !isspace(*
string) && n--) *word++ = *
string++;
635 return (
char*) string;
648char*
parse_field(
const char *
string,
char *word,
unsigned int n,
char separator)
652 while (*
string && *
string != separator && n--) *word++ = *
string++;
653 if (*
string == separator) ++string;
656 return (
char*) string;
670char*
parse_line(
const char *
string,
char *line,
unsigned int n)
672 const char *s = string;
674 while (*s && *s !=
'\n' && *s !=
'\r' && n--) *line++ = *s++;
675 if (*s ==
'\0') s = string;
677 while (*s && *s !=
'\n' && *s !=
'\r' ) ++s;
678 while (*s ==
'\r' || *s ==
'\n') ++s;
712 return (
char*) string;
731 while ((next =
parse_move(
string, board, move)) !=
string || move->
x ==
PASS) {
737 return (
char *) string;
755 for (i =
A1; i <=
H8; ++i) {
756 if (*s ==
'\0')
return (
char*) string;
757 switch (tolower(*s)) {
771 if (!isspace(*s))
return (
char*) string;
780 switch (tolower(*s)) {
785 return (
char*) s + 1;
790 return (
char*) s + 1;
797 return (
char*) string;
815 if (errno != EINVAL) *result = r;
817 return (
char*) string;
834 if (s) n = strtol(s, &end, 10);
843 }
else if (n > INT_MAX) {
852 return (
char*) string;
869 if (s) d = strtod(s, &end);
880 return (
char*) string;
912 if (*s ==
'.' && isdigit(s[1])) {
914 assert(0.0 <= x && x < 1.0);
916 *t = (*t + n + x) * 1000;
917 if (errno != EINVAL && errno != ERANGE)
string = s;
920 return (
char*) string;
933char*
parse_command(
const char *
string,
char *cmd,
char *param,
const unsigned int size)
937 if (strcmp(cmd,
"set") == 0) {
945 return (
char*) string;
958 for (c = path; *c; ++c) ;
959 for (;c >= path && *c !=
'/'; --c) ;
961 while (path <= c) *dir++ = *path++;
975 while (*base) *file++ = *base++;
976 while (*ext) *file++ = *ext++;
990#if defined(__unix__) || (defined(_WIN32) && defined(USE_PTHREAD)) || defined(__APPLE__)
991 pthread_create(thread, NULL, function, data);
994 *thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) function, data, 0, &
id);
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);
1022#if defined(__unix__) || (defined(_WIN32) && defined(USE_PTHREAD)) || defined(__APPLE__)
1023 return pthread_self();
1024#elif defined(_WIN32)
1025 return GetCurrentThread();
1035#if defined(__linux__) && !defined(ANDROID)
1040 pthread_setaffinity_np(thread,
sizeof (cpu_set_t), &
cpu);
1041#elif defined(_WIN32) && !defined(USE_PTHREAD)
1042 SetThreadIdealProcessor(thread, i);
1044 (void) thread; (void) i;
1062 sprintf(file,
"/sys/devices/system/cpu/cpu%d", n);
1063 f = fopen(file,
"r");
1070#elif defined(_SC_NPROCESSORS_ONLN)
1072 n = sysconf(_SC_NPROCESSORS_ONLN);
1074#elif defined(_WIN32)
1078 GetSystemInfo(&
info);
1079 n =
info.dwNumberOfProcessors;
1081#elif defined(__APPLE__)
1087 mib[1] = HW_AVAILCPU;
1088 sysctl(mib, 2, &n, &len, NULL, 0);
1091 sysctl( mib, 2, &n, &len, NULL, 0 );
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;
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);
1130 const unsigned long long MASK48 = 0xFFFFFFFFFFFFull;
1131 random->
x = (seed & MASK48);
#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
unsigned long long player
Definition board.h:27
unsigned long long opponent
Definition board.h:27
unsigned long long flipped
Definition move.h:21
int x
Definition move.h:22
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