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