--- nono/lib/header.h 2026/04/29 17:04:34 1.1.1.4 +++ nono/lib/header.h 2026/04/29 17:05:39 1.1.1.21 @@ -4,12 +4,11 @@ // Licensed under nono-license.txt // -#pragma once +// +// 基本ヘッダ +// -#define NONO_MAJOR_VER (0) -#define NONO_MINOR_VER (1) -#define NONO_PATCH_VER (0) -#define NONO_DATE "2020/07/19" +#pragma once #include "config-nono.h" #include @@ -27,7 +26,6 @@ #include #include #include -#include #include using uint8 = uint8_t; @@ -39,18 +37,17 @@ using int16 = int16_t; using int32 = int32_t; using int64 = int64_t; -#if defined(HAVE_ENDIAN_H) -#include -#elif defined(HAVE_SYS_ENDIAN_H) -#include -#else -#include "missing_endian.h" -#endif - #if defined(HAVE_BSD_BSD_H) #include #endif +#include "myendian.h" + +// For cppcheck... +#if !defined(__CONCAT) +#define __CONCAT(a, b) a ## b +#endif + #if !defined(__printflike) #if defined(HAVE___ATTRIBUTE_FORMAT) # define __printflike(a,b) __attribute__((__format__(__printf__, (a), (b)))) @@ -82,15 +79,18 @@ using int64 = int64_t; #endif #endif -#if !defined(__predict_true) +// FreeBSD(12.1) の __predict_true/false は定義がいまいちで使えない。 +// __builtin_expect() があることが分かればどの環境でも自前で定義できるので +// 既存定義は取り消す。 #if defined(HAVE___BUILTIN_EXPECT) +# undef __predict_true +# undef __predict_false # define __predict_true(exp) __builtin_expect((exp) != 0, 1) # define __predict_false(exp) __builtin_expect((exp) != 0, 0) -#else +#elif !defined(__predict_true) # define __predict_true(exp) (exp) # define __predict_false(exp) (exp) #endif -#endif #if !defined(__unused) #if defined(HAVE___ATTRIBUTE_UNUSED) @@ -116,7 +116,7 @@ using int64 = int64_t; // 64ビット数と2つの32ビット数を扱う共用体。 // 構造はまったく同じだが名前だけ場所に合わせてつけたい。 -#if _BYTE_ORDER == _LITTLE_ENDIAN +#if BYTE_ORDER == LITTLE_ENDIAN #define DEF_UNION64(NAME, Q, H, L) \ union NAME { \ uint64 Q; \ @@ -136,37 +136,42 @@ DEF_UNION64(union64, q, h, l); #define countof(x) (sizeof(x) / sizeof(x[0])) #endif +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif + +#ifndef roundup +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#endif + +#ifndef rounddown +#define rounddown(x, y) (((x)/(y))*(y)) +#endif + // メッセージ付きの assert。 -#define assertmsg(expr, fmt, ...) do { \ +// 本当は後ろに足したいのだがそれは無理なので、せめてそれっぽく1行にしてみる。 +#if !defined(NDEBUG) +#define assertmsg(expr, ...) do { \ if (__predict_false(!(expr))) { \ - fprintf(stderr, fmt "\n", __VA_ARGS__); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, ": "); \ assert(expr); \ } \ } while (0) +#else +#define assertmsg(expr, ...) +#endif + +// __func__ のようだけどクラス名と関数名だけを表示する。 +// __PRETTY_FUNCTION__ が近いけど、あれは戻り値やら引数全部表示するので。 +#define __method__ \ + (get_classfunc_name(__PRETTY_FUNCTION__, __FUNCTION__).c_str()) +extern std::string get_classfunc_name(const char *pretty, const char *func); -// 便利マクロ -#define kevent_set(k, e, n) kevent((k), (e), (n), NULL, 0, NULL) -#define kevent_poll(k, e, n, t) kevent((k), NULL, 0, (e), (n), (t)) - -// atomic_compare_exchange_strong() の短縮マクロ。 -// ライブラリ実装は第2引数の expected が値ではなくポインタなので一旦代入操作を -// 行わないといけないのと、第3引数の newval は型が uint8 だと int 即値が書けず -// (int8) でキャストしないといけない。 -// その上 atomic_compare_exchange_strong() が長い、と、いろいろ微妙なので、 -// その辺を短くするマクロを用意する。ただしこれでは expected 変数の型が -// 自動判別できないので、_8 と _32 を用意するところは妥協。 -// (static) inline 関数にすることも出来るけどそうするとここで ヘッダ -// を読み込まなければならなくなるため、マクロで実現する。 -#define atomic_cas_8(varp, expval, newval) ({ \ - uint8 expected = (expval); \ - atomic_compare_exchange_strong((varp), &expected, (uint8)(newval)); \ -}) -#define atomic_cas_32(varp, expval, newval) ({ \ - uint32 expected = (expval); \ - atomic_compare_exchange_strong((varp), &expected, (uint32)(newval)); \ -}) - -// ログ -#define PANIC(...) panic(__PRETTY_FUNCTION__, __VA_ARGS__) -[[noreturn]] extern void panic(const char *funcname, const char *fmt, ...) - __printflike(2, 3); +// iconv() の第2引数の型は OS によって違う… +#if defined(HAVE_ICONV_CONST) +#define ICONV(cd, s, slen, d, dlen) iconv((cd), (s), (slen), (d), (dlen)) +#else +#define ICONV(cd, s, slen, d, dlen) \ + iconv((cd), const_cast(s), (slen), (d), (dlen)) +#endif