-
Notifications
You must be signed in to change notification settings - Fork 116
/
Copy pathutil.h
212 lines (155 loc) · 6.57 KB
/
util.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#ifndef PACHI_UTIL_H
#define PACHI_UTIL_H
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#undef MIN
#undef MAX
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define swap(x, y) do { typeof(x) __tmp; __tmp = (x); (x) = (y); (y) = __tmp; } while(0)
#ifdef __cplusplus
#define typeof decltype
#define restrict __restrict__
#endif
/* Returns true if @str starts with @prefix */
int str_prefix(char *prefix, char *str);
/* Argument parsing helpers */
bool valid_number(char *str);
bool valid_float(char *str);
/* Warn user (popup on windows) */
void warning(const char *format, ...)
__attribute__ ((format (printf, 1, 2)));
/* Warning + terminate process */
void die(const char *format, ...)
__attribute__ ((noreturn))
__attribute__ ((format (printf, 1, 2)));
/* Terminate after system call failure (similar to perror()) */
void fail(char *msg)
__attribute__ ((noreturn));
int file_exists(const char *name);
/* windows: cd to pachi directory to avoid cwd issues. */
void win_set_pachi_cwd(char *pachi);
/* Get number of processors. */
int get_nprocessors();
/**************************************************************************************************/
/* Data files */
/* Lookup data file in the following places:
* 1) Current directory
* 2) DATA_DIR environment variable / compile time default
* 3) exe's directory
* Copies first match to @buffer (if no match @filename is still copied). */
#define get_data_file(buffer, filename) get_data_file_(buffer, sizeof(buffer), filename)
void get_data_file_(char buffer[], int size, const char *filename);
/* get_data_file() + fopen() */
FILE *fopen_data_file(const char *filename, const char *mode);
/**************************************************************************************************/
/* Portability definitions. */
#ifdef _WIN32
#define sleep(seconds) pachi_sleep(seconds)
void pachi_sleep(int seconds);
/* No line buffering on windows, set to unbuffered. */
#define setlinebuf(file) setvbuf(file, NULL, _IONBF, 0)
/* Windows MessageBox() */
#define popup(msg) pachi_popup(msg)
void pachi_popup(const char *msg);
/* MinGW gcc, no function prototype for built-in function stpcpy() */
char *stpcpy (char *dest, const char *src);
const char *strcasestr(const char *haystack, const char *needle);
/* Like perror() for windows API calls */
void win_perror(char *function);
#endif /* _WIN32 */
/**************************************************************************************************/
/* const-safe versions of some string functions */
#ifdef strchr
#undef strchr
#endif
/* https://fanf.livejournal.com/144696.html */
#define strchr(str, chr) ((__typeof__(&(str)[0])) strchr((str), (chr)))
#define strrchr(str, chr) ((__typeof__(&(str)[0])) strrchr((str), (chr)))
#define index(str, chr) ((__typeof__(&(str)[0])) index((str), (chr)))
#define rindex(str, chr) ((__typeof__(&(str)[0])) rindex((str), (chr)))
/**************************************************************************************************/
/* Misc. definitions. */
/* Use make DOUBLE_FLOATING=1 in large configurations with counts > 1M
* where 24 bits of floating_t mantissa become insufficient. */
#ifdef DOUBLE_FLOATING
# define floating_t double
# define PRIfloating "%lf"
#else
# define floating_t float
# define PRIfloating "%f"
#endif
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect((x), 0)
static inline void *
checked_malloc(size_t size, char *filename, unsigned int line, const char *func)
{
void *p = malloc(size);
if (!p)
die("%s:%u: %s: OUT OF MEMORY malloc(%u)\n",
filename, line, func, (unsigned) size);
return p;
}
static inline void *
checked_calloc(size_t nmemb, size_t size, const char *filename, unsigned int line, const char *func)
{
void *p = calloc(nmemb, size);
if (!p) die("%s:%u: %s: OUT OF MEMORY calloc(%u, %u)\n",
filename, line, func, (unsigned) nmemb, (unsigned) size);
return p;
}
static inline void *
checked_realloc(void *ptr, size_t size, char *filename, unsigned int line, const char *func)
{
void *p = realloc(ptr, size);
if (!p)
die("%s:%u: %s: OUT OF MEMORY realloc(%u)\n",
filename, line, func, (unsigned) size);
return p;
}
/* casts: make c++ happy */
#define cmalloc(size) checked_malloc((size), __FILE__, __LINE__, __func__)
#define ccalloc(nmemb, size) checked_calloc((nmemb), (size), __FILE__, __LINE__, __func__)
#define malloc2(type) ((type*)cmalloc(sizeof(type)))
#define calloc2(nmemb, type) ((type*)ccalloc(nmemb, sizeof(type)))
#define crealloc(ptr, size) checked_realloc((ptr), (size), __FILE__, __LINE__, __func__)
#define checked_write(fd, pt, size) (assert(write((fd), (pt), (size)) == (size)))
#define checked_fread(pt, size, n, f) (assert(fread((pt), (size), (n), (f)) == (n)))
/**************************************************************************************************/
/* Simple string buffer to store output
* Initial size must be enough to store all output or program will abort.
* String and structure can be allocated using different means, see below. */
typedef struct
{
int remaining;
char *str; /* whole output */
char *cur;
} strbuf_t;
/* Initialize passed string buffer. Returns buf. */
strbuf_t *strbuf_init(strbuf_t *buf, char *buffer, int size);
/* Initialize passed string buffer. Returns buf.
* Internal string is malloc()ed and must be freed afterwards. */
strbuf_t *strbuf_init_alloc(strbuf_t *buf, int size);
/* Create a new string buffer and use a malloc()ed string internally.
* Both must be free()ed afterwards. */
strbuf_t *new_strbuf(int size);
/* Create string buffer for use within current function (stack-allocated). */
#define strbuf(name, size) \
char buffer_ ## name [(size)]; strbuf_t strbuf_ ## name; \
strbuf_t *name = strbuf_init(&strbuf_ ## name, buffer_ ## name, sizeof(buffer_ ## name));
/* Create static string buffer: can return buf->str (but not buf). */
#define static_strbuf(name, size) \
static char buffer_ ## name [(size)]; strbuf_t strbuf_ ## name; \
strbuf_t *name = strbuf_init(&strbuf_ ## name, buffer_ ## name, sizeof(buffer_ ## name));
/* String buffer version of printf():
* Use sbprintf(buf, format, ...) to accumulate output. */
int strbuf_printf(strbuf_t *buf, const char *format, ...)
__attribute__ ((format (printf, 2, 3)));
int strbuf_vprintf(strbuf_t *buf, const char *format, va_list ap);
#define sbprintf strbuf_printf
/**************************************************************************************************/
/* Remove trailing '\n' (or "\r\n" on windows) */
void chomp(char *line);
#endif