mirror of
https://git.sr.ht/~cismonx/bookmarkfs
synced 2025-07-16 06:08:50 +00:00
183 lines
4.2 KiB
C
183 lines
4.2 KiB
C
/**
|
|
* bookmarkfs/src/xstd.h
|
|
* ----
|
|
*
|
|
* Copyright (C) 2024 CismonX <admin@cismon.net>
|
|
*
|
|
* This file is part of BookmarkFS.
|
|
*
|
|
* BookmarkFS is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* BookmarkFS is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with BookmarkFS. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef BOOKMARKFS_XSTD_H_
|
|
#define BOOKMARKFS_XSTD_H_
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "defs.h"
|
|
|
|
#ifdef HAVE___BUILTIN_EXPECT
|
|
# define likely(e) __builtin_expect(!!(e), 1)
|
|
# define unlikely(e) __builtin_expect(!!(e), 0)
|
|
#else
|
|
# define likely(e) (e)
|
|
# define unlikely(e) (e)
|
|
#endif /* defined(HAVE___BUILTIN_EXPECT) */
|
|
|
|
#ifdef BOOKMARKFS_DEBUG
|
|
# define xassert(e) if (unlikely(!(e))) xabort_(#e, FILE_NAME_, __LINE__)
|
|
#else
|
|
# define xassert(e) if (unlikely(!(e))) xabort_(FILE_NAME_, __LINE__)
|
|
#endif
|
|
|
|
#ifdef BOOKMARKFS_DEBUG
|
|
# define debug_assert(e) xassert(e)
|
|
# define unreachable() xassert(0)
|
|
#else /* !defined(BOOKMARKFS_DEBUG) */
|
|
# define debug_assert(e) if (!(e)) { unreachable(); }
|
|
# ifdef HAVE___BUILTIN_UNREACHABLE
|
|
# define unreachable() __builtin_unreachable()
|
|
# else
|
|
# define unreachable()
|
|
# endif
|
|
#endif /* defined(BOOKMARKFS_DEBUG) */
|
|
|
|
#define log_printf_(f, ...) \
|
|
fprintf(stderr, "%s:" f "\n", FILE_NAME_, __VA_ARGS__)
|
|
|
|
#ifdef BOOKMARKFS_DEBUG
|
|
# define log_printf(f, ...) log_printf_("%d: " f, __LINE__, __VA_ARGS__)
|
|
#else
|
|
# define log_printf(f, ...) log_printf_(" " f, __VA_ARGS__);
|
|
#endif
|
|
#define log_puts(s) log_printf("%s", s)
|
|
|
|
#ifdef BOOKMARKFS_DEBUG
|
|
# define debug_printf(f, ...) log_printf("[debug] " f, __VA_ARGS__)
|
|
# define debug_puts(s) debug_printf("%s", s)
|
|
#else
|
|
# define debug_printf(f, ...)
|
|
# define debug_puts(s)
|
|
#endif
|
|
|
|
#if defined(__FreeBSD__) || (defined(__linux__) && defined(_GNU_SOURCE))
|
|
# define xasprintf(strp, ...) xassert(0 <= asprintf(strp, __VA_ARGS__))
|
|
#else
|
|
# define xasprintf(strp, ...) \
|
|
do { \
|
|
int len_ = snprintf(NULL, 0, __VA_ARGS__); \
|
|
xassert(len_ >= 0); \
|
|
*(strp) = xmalloc(len_ + 1); \
|
|
xassert(len_ == sprintf(*(strp), __VA_ARGS__)); \
|
|
} while (0)
|
|
#endif
|
|
|
|
/**
|
|
* Prints a message to standard error, and then aborts.
|
|
*/
|
|
BOOKMARKFS_INTERNAL
|
|
FUNCATTR_COLD FUNCATTR_NORETURN
|
|
void
|
|
xabort_ (
|
|
#ifdef BOOKMARKFS_DEBUG
|
|
char const *assertion,
|
|
#endif
|
|
char const *name,
|
|
int line
|
|
);
|
|
|
|
/**
|
|
* Like calloc(), but never returns NULL.
|
|
*
|
|
* On failure, the calling process aborts.
|
|
*/
|
|
BOOKMARKFS_INTERNAL
|
|
FUNCATTR_MALLOC FUNCATTR_RETURNS_NONNULL
|
|
void *
|
|
xcalloc (
|
|
size_t nmemb,
|
|
size_t size
|
|
);
|
|
|
|
/**
|
|
* Like fsync(), but retries on EINTR, and aborts on EIO.
|
|
*/
|
|
BOOKMARKFS_INTERNAL
|
|
int
|
|
xfsync (
|
|
int fd
|
|
);
|
|
|
|
/**
|
|
* Like malloc(), but never returns NULL.
|
|
*
|
|
* On failure, the calling process aborts.
|
|
*/
|
|
BOOKMARKFS_INTERNAL
|
|
FUNCATTR_MALLOC FUNCATTR_RETURNS_NONNULL
|
|
void *
|
|
xmalloc (
|
|
size_t size
|
|
);
|
|
|
|
/**
|
|
* Like pipe2(), using pipe()+fcntl() on platforms without pipe2().
|
|
*
|
|
* The only supported flag is O_CLOEXEC.
|
|
*/
|
|
BOOKMARKFS_INTERNAL
|
|
int
|
|
xpipe2 (
|
|
int pipefd[2],
|
|
int flags
|
|
);
|
|
|
|
/**
|
|
* Like realloc(), but never returns NULL.
|
|
*
|
|
* On failure, the calling process aborts.
|
|
*/
|
|
BOOKMARKFS_INTERNAL
|
|
FUNCATTR_RETURNS_NONNULL
|
|
void *
|
|
xrealloc (
|
|
void *p,
|
|
size_t size
|
|
);
|
|
|
|
/**
|
|
* Like strerror(), but MT-Safe.
|
|
*
|
|
* NOTE: strerror() is MT-Safe in some implementations (e.g., glibc >= 2.32),
|
|
* but POSIX does not enforce that.
|
|
*/
|
|
BOOKMARKFS_INTERNAL
|
|
FUNCATTR_RETURNS_NONNULL
|
|
char const *
|
|
xstrerror (
|
|
int errnum
|
|
);
|
|
|
|
/**
|
|
* Like xstrerror(), but takes `errno` as error number,
|
|
* and saves its value to `err_ptr`.
|
|
*/
|
|
BOOKMARKFS_INTERNAL
|
|
FUNCATTR_RETURNS_NONNULL
|
|
char const *
|
|
xstrerror_save (
|
|
int *errnum_ptr
|
|
);
|
|
|
|
#endif /* !defined(BOOKMARKFS_XSTD_H_) */
|