|
|
1.1 root 1: //
2: // nono
1.1.1.4 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.15 root 7: //
8: // 基本ヘッダ
9: //
10:
1.1 root 11: #pragma once
12:
1.1.1.3 root 13: #include "config-nono.h"
1.1 root 14: #include <cassert>
15: #include <cerrno>
16: #include <cstdarg>
17: #include <cstdio>
18: #include <cstdint>
19: #include <cstdlib>
20: #include <cstring>
1.1.1.3 root 21: #include <memory>
1.1 root 22: #include <string>
23:
24: #include <err.h>
25: #include <inttypes.h>
26: #include <unistd.h>
27: #include <sys/cdefs.h>
28: #include <sys/types.h>
29:
1.1.1.4 root 30: using uint8 = uint8_t;
31: using uint16 = uint16_t;
32: using uint32 = uint32_t;
33: using uint64 = uint64_t;
34: using int8 = int8_t;
35: using int16 = int16_t;
36: using int32 = int32_t;
37: using int64 = int64_t;
1.1 root 38:
39: #if defined(HAVE_BSD_BSD_H)
40: #include <bsd/bsd.h>
41: #endif
42:
1.1.1.15 root 43: #include "myendian.h"
44:
1.1.1.20 root 45: // For cppcheck...
46: #if !defined(__CONCAT)
47: #define __CONCAT(a, b) a ## b
48: #endif
49:
1.1 root 50: #if !defined(__printflike)
51: #if defined(HAVE___ATTRIBUTE_FORMAT)
52: # define __printflike(a,b) __attribute__((__format__(__printf__, (a), (b))))
53: #else
54: # define __printflike(a,b)
55: #endif
56: #endif
57:
58: #if !defined(__unreachable)
59: #if defined(HAVE___BUILTIN_UNREACHABLE)
60: # define __unreachable() __builtin_unreachable()
61: #else
62: # define __unreachable() ((void)0)
63: #endif
64: #endif
65:
66: // gcc でコンパイラに最適化の条件を与える。
67: #if defined(HAVE___BUILTIN_ASSUME)
68: #define __assume(cond) __builtin_assume(cond)
69: #else
70: #define __assume(cond) if (!(cond)) __unreachable()
71: #endif
72:
73: #if !defined(__packed)
74: #if defined(HAVE___ATTRIBUTE_PACKED)
75: # define __packed __attribute__((__packed__))
76: #else
77: # error not tested.
78: #endif
79: #endif
80:
1.1.1.16 root 81: // FreeBSD(12.1) の __predict_true/false は定義がいまいちで使えない。
82: // __builtin_expect() があることが分かればどの環境でも自前で定義できるので
83: // 既存定義は取り消す。
1.1 root 84: #if defined(HAVE___BUILTIN_EXPECT)
1.1.1.16 root 85: # undef __predict_true
86: # undef __predict_false
1.1 root 87: # define __predict_true(exp) __builtin_expect((exp) != 0, 1)
88: # define __predict_false(exp) __builtin_expect((exp) != 0, 0)
1.1.1.16 root 89: #elif !defined(__predict_true)
1.1 root 90: # define __predict_true(exp) (exp)
91: # define __predict_false(exp) (exp)
92: #endif
93:
94: #if !defined(__unused)
95: #if defined(HAVE___ATTRIBUTE_UNUSED)
96: # define __unused __attribute__((__unused__))
97: #else
98: # define __unused
99: #endif
100: #endif
101:
1.1.1.4 root 102: #if defined(__clang__)
103: # define FALLTHROUGH [[clang::fallthrough]]
104: #elif defined(HAVE___ATTRIBUTE_FALLTHROUGH)
1.1 root 105: # define FALLTHROUGH __attribute__((__fallthrough__))
106: #else
107: # define FALLTHROUGH ((void)0)
108: #endif
109:
110: #if defined(HAVE___ATTRIBUTE_NO_SANITIZE)
111: # define NO_SANITIZE(x) __attribute__((no_sanitize(x)))
112: #else
113: # define NO_SANITIZE(x)
114: #endif
115:
1.1.1.3 root 116: // 64ビット数と2つの32ビット数を扱う共用体。
117: // 構造はまったく同じだが名前だけ場所に合わせてつけたい。
1.1.1.15 root 118: #if BYTE_ORDER == LITTLE_ENDIAN
1.1.1.3 root 119: #define DEF_UNION64(NAME, Q, H, L) \
120: union NAME { \
121: uint64 Q; \
122: struct { uint32 L, H; }; \
123: }
124: #else
125: #define DEF_UNION64(NAME, Q, H, L) \
126: union NAME { \
127: uint64 Q; \
128: struct { uint32 H, L; }; \
129: }
130: #endif
131:
132: DEF_UNION64(union64, q, h, l);
133:
1.1 root 134: #ifndef countof
135: #define countof(x) (sizeof(x) / sizeof(x[0]))
136: #endif
137:
1.1.1.21 root 138: #ifndef howmany
139: #define howmany(x, y) (((x)+((y)-1))/(y))
140: #endif
141:
1.1.1.5 root 142: #ifndef roundup
143: #define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
144: #endif
145:
1.1.1.15 root 146: #ifndef rounddown
147: #define rounddown(x, y) (((x)/(y))*(y))
148: #endif
149:
1.1.1.3 root 150: // メッセージ付きの assert。
1.1.1.5 root 151: // 本当は後ろに足したいのだがそれは無理なので、せめてそれっぽく1行にしてみる。
1.1.1.15 root 152: #if !defined(NDEBUG)
1.1.1.5 root 153: #define assertmsg(expr, ...) do { \
1.1.1.3 root 154: if (__predict_false(!(expr))) { \
1.1.1.5 root 155: fprintf(stderr, __VA_ARGS__); \
156: fprintf(stderr, ": "); \
1.1.1.3 root 157: assert(expr); \
158: } \
159: } while (0)
1.1.1.15 root 160: #else
161: #define assertmsg(expr, ...)
162: #endif
1.1.1.3 root 163:
1.1.1.21 root 164: // __func__ のようだけどクラス名と関数名だけを表示する。
165: // __PRETTY_FUNCTION__ が近いけど、あれは戻り値やら引数全部表示するので。
166: #define __method__ \
167: (get_classfunc_name(__PRETTY_FUNCTION__, __FUNCTION__).c_str())
168: extern std::string get_classfunc_name(const char *pretty, const char *func);
169:
1.1.1.17 root 170: // iconv() の第2引数の型は OS によって違う…
171: #if defined(HAVE_ICONV_CONST)
172: #define ICONV(cd, s, slen, d, dlen) iconv((cd), (s), (slen), (d), (dlen))
173: #else
174: #define ICONV(cd, s, slen, d, dlen) \
175: iconv((cd), const_cast<char **>(s), (slen), (d), (dlen))
176: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.