util.h 8.7 KB
Newer Older
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
#ifndef GIT_COMPAT_UTIL_H
#define GIT_COMPAT_UTIL_H

#ifndef FLEX_ARRAY
/*
 * See if our compiler is known to support flexible array members.
 */
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# define FLEX_ARRAY /* empty */
#elif defined(__GNUC__)
# if (__GNUC__ >= 3)
#  define FLEX_ARRAY /* empty */
# else
#  define FLEX_ARRAY 0 /* older GNU extension */
# endif
#endif

/*
 * Otherwise, default to safer but a bit wasteful traditional style
 */
#ifndef FLEX_ARRAY
# define FLEX_ARRAY 1
#endif
#endif

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

#ifdef __GNUC__
#define TYPEOF(x) (__typeof__(x))
#else
#define TYPEOF(x)
#endif

#define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits))))
#define HAS_MULTI_BITS(i)  ((i) & ((i) - 1))  /* checks if an integer has more than 1 bit set */

/* Approximation of the length of the decimal representation of this type. */
#define decimal_length(x)	((int)(sizeof(x) * 2.56 + 0.5) + 1)

#define _ALL_SOURCE 1
#define _BSD_SOURCE 1
42 43
/* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */
#define _DEFAULT_SOURCE 1
44
#define HAS_BOOL
45 46 47 48

#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
49
#include <sys/statfs.h>
50
#include <fcntl.h>
51
#include <stdbool.h>
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
#include <stddef.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <sys/param.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/time.h>
#include <time.h>
#include <signal.h>
#include <fnmatch.h>
#include <assert.h>
#include <regex.h>
#include <utime.h>
#include <sys/wait.h>
69
#include <poll.h>
70 71 72
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <inttypes.h>
73
#include <linux/kernel.h>
74
#include <linux/magic.h>
B
Borislav Petkov 已提交
75
#include <linux/types.h>
76
#include <sys/ttydefaults.h>
77
#include <api/fs/tracing_path.h>
78
#include <termios.h>
79
#include <linux/bitops.h>
80
#include <termios.h>
81

82 83
extern const char *graph_line;
extern const char *graph_dotted_line;
84
extern char buildid_dir[];
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
/* On most systems <limits.h> would have given us this, but
 * not on some systems (e.g. GNU/Hurd).
 */
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif

#ifndef PRIuMAX
#define PRIuMAX "llu"
#endif

#ifndef PRIu32
#define PRIu32 "u"
#endif

#ifndef PRIx32
#define PRIx32 "x"
#endif

#ifndef PATH_SEP
#define PATH_SEP ':'
#endif

#ifndef STRIP_EXTENSION
#define STRIP_EXTENSION ""
#endif

#ifndef has_dos_drive_prefix
#define has_dos_drive_prefix(path) 0
#endif

#ifndef is_dir_sep
#define is_dir_sep(c) ((c) == '/')
#endif

#ifdef __GNUC__
#define NORETURN __attribute__((__noreturn__))
#else
#define NORETURN
#ifndef __attribute__
#define __attribute__(x)
#endif
#endif

130 131
#define PERF_GTK_DSO  "libperf-gtk.so"

132 133 134 135 136 137
/* General helper functions */
extern void usage(const char *err) NORETURN;
extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));

138 139 140 141 142 143 144 145 146
#include "../../../include/linux/stringify.h"

#define DIE_IF(cnd)	\
	do { if (cnd)	\
		die(" at (" __FILE__ ":" __stringify(__LINE__) "): "	\
		    __stringify(cnd) "\n");				\
	} while (0)


147
extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
148
extern void set_warning_routine(void (*routine)(const char *err, va_list params));
149 150

extern int prefixcmp(const char *str, const char *prefix);
151
extern void set_buildid_dir(const char *dir);
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174

static inline const char *skip_prefix(const char *str, const char *prefix)
{
	size_t len = strlen(prefix);
	return strncmp(str, prefix, len) ? NULL : str + len;
}

#ifdef __GLIBC_PREREQ
#if __GLIBC_PREREQ(2, 1)
#define HAVE_STRCHRNUL
#endif
#endif

#ifndef HAVE_STRCHRNUL
#define strchrnul gitstrchrnul
static inline char *gitstrchrnul(const char *s, int c)
{
	while (*s && *s != c)
		s++;
	return (char *)s;
}
#endif

175 176 177 178
/*
 * Wrappers:
 */
extern char *xstrdup(const char *str);
179
extern void *xrealloc(void *ptr, size_t size) __attribute__((weak));
180

181

182 183 184 185 186
static inline void *zalloc(size_t size)
{
	return calloc(1, size);
}

187 188
#define zfree(ptr) ({ free(*ptr); *ptr = NULL; })

189 190 191 192
static inline int has_extension(const char *filename, const char *ext)
{
	size_t len = strlen(filename);
	size_t extlen = strlen(ext);
193

194 195 196 197 198 199 200
	return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
}

/* Sane ctype - no locale, and works with signed chars */
#undef isascii
#undef isspace
#undef isdigit
201
#undef isxdigit
202
#undef isalpha
F
Frederic Weisbecker 已提交
203
#undef isprint
204
#undef isalnum
205 206
#undef islower
#undef isupper
207 208
#undef tolower
#undef toupper
209

210 211 212 213
#ifndef NSEC_PER_MSEC
#define NSEC_PER_MSEC	1000000L
#endif

214 215
int parse_nsec_time(const char *str, u64 *ptime);

216
extern unsigned char sane_ctype[256];
217 218 219 220 221 222 223
#define GIT_SPACE		0x01
#define GIT_DIGIT		0x02
#define GIT_ALPHA		0x04
#define GIT_GLOB_SPECIAL	0x08
#define GIT_REGEX_SPECIAL	0x10
#define GIT_PRINT_EXTRA		0x20
#define GIT_PRINT		0x3E
224 225 226 227
#define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
#define isascii(x) (((x) & ~0x7f) == 0)
#define isspace(x) sane_istest(x,GIT_SPACE)
#define isdigit(x) sane_istest(x,GIT_DIGIT)
228 229
#define isxdigit(x)	\
	(sane_istest(toupper(x), GIT_ALPHA | GIT_DIGIT) && toupper(x) < 'G')
230 231
#define isalpha(x) sane_istest(x,GIT_ALPHA)
#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
232
#define isprint(x) sane_istest(x,GIT_PRINT)
233 234
#define islower(x) (sane_istest(x,GIT_ALPHA) && (x & 0x20))
#define isupper(x) (sane_istest(x,GIT_ALPHA) && !(x & 0x20))
235 236 237 238 239 240 241 242 243 244
#define tolower(x) sane_case((unsigned char)(x), 0x20)
#define toupper(x) sane_case((unsigned char)(x), 0)

static inline int sane_case(int x, int high)
{
	if (sane_istest(x, GIT_ALPHA))
		x = (x & ~0x20) | high;
	return x;
}

245
int mkdir_p(char *path, mode_t mode);
246
int rm_rf(char *path);
247
int copyfile(const char *from, const char *to);
A
Adrian Hunter 已提交
248
int copyfile_mode(const char *from, const char *to, mode_t mode);
249
int copyfile_offset(int fromfd, loff_t from_ofs, int tofd, loff_t to_ofs, u64 size);
250

251 252 253 254 255
s64 perf_atoll(const char *str);
char **argv_split(const char *str, int *argcp);
void argv_free(char **argv);
bool strglobmatch(const char *str, const char *pat);
bool strlazymatch(const char *str, const char *pat);
256 257 258 259
static inline bool strisglob(const char *str)
{
	return strpbrk(str, "*?[") != NULL;
}
260
int strtailcmp(const char *s1, const char *s2);
261
char *strxfrchar(char *s, char from, char to);
262
unsigned long convert_unit(unsigned long value, char *unit);
263
ssize_t readn(int fd, void *buf, size_t n);
J
Jiri Olsa 已提交
264
ssize_t writen(int fd, void *buf, size_t n);
265

266 267 268 269
struct perf_event_attr;

void event_attr_init(struct perf_event_attr *attr);

270 271 272
#define _STR(x) #x
#define STR(x) _STR(x)

273
size_t hex_width(u64 v);
274
int hex2u64(const char *ptr, u64 *val);
275

276
char *ltrim(char *s);
277 278
char *rtrim(char *s);

279
void dump_stack(void);
280
void sighandler_dump_stack(int sig);
281

282
extern unsigned int page_size;
283
extern int cacheline_size;
284

285
void get_term_dimensions(struct winsize *ws);
286
void set_term_quiet_input(struct termios *old);
287 288 289 290 291 292 293

struct parse_tag {
	char tag;
	int mult;
};

unsigned long parse_tag_value(const char *str, struct parse_tag *tags);
294 295 296

#define SRCLINE_UNKNOWN  ((char *) "??:0")

297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
static inline int path__join(char *bf, size_t size,
			     const char *path1, const char *path2)
{
	return scnprintf(bf, size, "%s%s%s", path1, path1[0] ? "/" : "", path2);
}

static inline int path__join3(char *bf, size_t size,
			      const char *path1, const char *path2,
			      const char *path3)
{
	return scnprintf(bf, size, "%s%s%s%s%s",
			 path1, path1[0] ? "/" : "",
			 path2, path2[0] ? "/" : "", path3);
}

312
struct dso;
313
struct symbol;
314

315
extern bool srcline_full_filename;
W
Wang Nan 已提交
316
char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
317
		  bool show_sym);
318 319
char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
		  bool show_sym, bool unwind_inlines);
320
void free_srcline(char *srcline);
321

322
int filename__read_str(const char *filename, char **buf, size_t *sizep);
323
int perf_event_paranoid(void);
324

325 326 327
void mem_bswap_64(void *src, int byte_size);
void mem_bswap_32(void *src, int byte_size);

328
const char *get_filename_for_perf_kvm(void);
329
bool find_process(const char *name);
330 331 332 333 334

#ifdef HAVE_ZLIB_SUPPORT
int gzip_decompress_to_file(const char *input, int output_fd);
#endif

335 336 337 338
#ifdef HAVE_LZMA_SUPPORT
int lzma_decompress_to_file(const char *input, int output_fd);
#endif

339 340 341 342 343 344 345 346 347 348 349 350
char *asprintf_expr_inout_ints(const char *var, bool in, size_t nints, int *ints);

static inline char *asprintf_expr_in_ints(const char *var, size_t nints, int *ints)
{
	return asprintf_expr_inout_ints(var, true, nints, ints);
}

static inline char *asprintf_expr_not_in_ints(const char *var, size_t nints, int *ints)
{
	return asprintf_expr_inout_ints(var, false, nints, ints);
}

351 352
int get_stack_size(const char *str, unsigned long *_size);

353 354 355
int fetch_kernel_version(unsigned int *puint,
			 char *str, size_t str_sz);

356
#endif /* GIT_COMPAT_UTIL_H */