Created
June 8, 2026 00:58
-
-
Save Chubek/4d9f885f1189ded7a8693cf18d1247a6 to your computer and use it in GitHub Desktop.
Hedley API Boilerplate
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * @file myapihed_api.h | |
| * @brief Portable API macros for the MYAPIHED library, built on top of hedley.h | |
| */ | |
| #ifndef MYAPIHED_API_H | |
| #define MYAPIHED_API_H | |
| #include "hedley.h" | |
| /* ========================================================================= | |
| * VERSION | |
| * ========================================================================= */ | |
| #define MYAPIHED_VERSION_MAJOR 1 | |
| #define MYAPIHED_VERSION_MINOR 0 | |
| #define MYAPIHED_VERSION_PATCH 0 | |
| /** | |
| * Numeric version: encoded as (major * 10000) + (minor * 100) + patch | |
| * e.g. 1.2.3 -> 10203 | |
| * 2.14.7 -> 21407 | |
| */ | |
| #define MYAPIHED_VERSION_NUM \ | |
| ((MYAPIHED_VERSION_MAJOR * 10000) + (MYAPIHED_VERSION_MINOR * 100) \ | |
| + (MYAPIHED_VERSION_PATCH)) | |
| /** String version, e.g. "1.0.0" */ | |
| #define MYAPIHED_STRINGIFY_(x) #x | |
| #define MYAPIHED_STRINGIFY(x) MYAPIHED_STRINGIFY_ (x) | |
| #define MYAPIHED_VERSION_STR \ | |
| MYAPIHED_STRINGIFY (MYAPIHED_VERSION_MAJOR) \ | |
| "." MYAPIHED_STRINGIFY (MYAPIHED_VERSION_MINOR) "." MYAPIHED_STRINGIFY ( \ | |
| MYAPIHED_VERSION_PATCH) | |
| /** Human-readable "about" string */ | |
| #define MYAPIHED_ABOUT \ | |
| "MYAPIHED Library v" MYAPIHED_VERSION_STR \ | |
| " -- Copyright (C) 2026 MYAPIHED Authors. All rights reserved." | |
| /* ========================================================================= | |
| * SYMBOL VISIBILITY (hedley.h lines 1641-1676) | |
| * | |
| * Define MYAPIHED_BUILD when compiling the library itself. | |
| * Consumers only include this header; they must NOT define MYAPIHED_BUILD. | |
| * ========================================================================= */ | |
| /** Public API symbol – exported when building, imported when consuming. */ | |
| #if defined(MYAPIHED_BUILD) | |
| #define MYAPIHED_API \ | |
| HEDLEY_PUBLIC /* __declspec(dllexport) / visibility("default") */ | |
| #else | |
| #define MYAPIHED_API \ | |
| HEDLEY_IMPORT /* __declspec(dllimport) / extern */ | |
| #endif | |
| /** | |
| * Private symbol – hidden from the shared-library ABI. | |
| * Use on internal helper functions that must never be called by consumers. | |
| * (hedley.h: HEDLEY_PRIVATE -> visibility("hidden") on ELF, empty on MSVC) | |
| */ | |
| #define MYAPIHED_PRIVATE HEDLEY_PRIVATE | |
| /** | |
| * For functions that are provided only in a shared library and MUST be | |
| * loaded at runtime via dlopen/LoadLibrary + dlsym/GetProcAddress. | |
| * Marks the declaration as an import so that no static-link stub is emitted. | |
| */ | |
| #define MYAPIHED_DYNLIB HEDLEY_IMPORT | |
| /* ========================================================================= | |
| * INLINING (hedley.h lines 1555-1638) | |
| * ========================================================================= */ | |
| /** Force inlining: __attribute__((always_inline)) / __forceinline */ | |
| #define MYAPIHED_ALWAYS_INLINE HEDLEY_ALWAYS_INLINE | |
| /** Prevent inlining: __attribute__((noinline)) / __declspec(noinline) */ | |
| #define MYAPIHED_NEVER_INLINE HEDLEY_NEVER_INLINE | |
| /* ========================================================================= | |
| * FUNCTION ATTRIBUTES (hedley.h lines 1399-1497) | |
| * ========================================================================= */ | |
| /** | |
| * Pure function: return value depends only on arguments + global state; | |
| * no observable side effects. Enables CSE and other optimisations. | |
| * (hedley.h: __attribute__((pure))) | |
| */ | |
| #define MYAPIHED_PURE HEDLEY_PURE | |
| /** | |
| * Const function: return value depends ONLY on arguments (no globals read); | |
| * strictly stronger than PURE. | |
| * (hedley.h: __attribute__((const)) or alias to HEDLEY_PURE) | |
| */ | |
| #define MYAPIHED_CONST HEDLEY_CONST | |
| /** | |
| * Malloc-like: returned pointer does not alias any existing object. | |
| * (hedley.h: __attribute__((malloc)) / __declspec(restrict)) | |
| * | |
| * Usage: | |
| * MYAPIHED_API MYAPIHED_MALLOC(size) | |
| * void *myapihed_alloc(size_t size); | |
| * | |
| * The parameter name 'n' is kept as a documentation convention; it is | |
| * not evaluated – only the annotation matters to the compiler. | |
| */ | |
| #define MYAPIHED_MALLOC(n) HEDLEY_MALLOC /* n = size (documentation only) */ | |
| /* ========================================================================= | |
| * BRANCH PREDICTION HINTS (hedley.h lines 1336-1393) | |
| * ========================================================================= */ | |
| /** Hint that the expression is TRUE in the common case. */ | |
| #define MYAPIHED_LIKELY(expr) HEDLEY_LIKELY (expr) | |
| /** Hint that the expression is FALSE in the common case. */ | |
| #define MYAPIHED_UNLIKELY(expr) HEDLEY_UNLIKELY (expr) | |
| /* ========================================================================= | |
| * HOT / COLD (not in this hedley.h build; defined here in Hedley style) | |
| * ========================================================================= */ | |
| #if !defined(MYAPIHED_HOT) | |
| #if HEDLEY_HAS_ATTRIBUTE(hot) || HEDLEY_GCC_VERSION_CHECK(4, 3, 0) | |
| #define MYAPIHED_HOT __attribute__ ((__hot__)) | |
| #else | |
| #define MYAPIHED_HOT | |
| #endif | |
| #endif | |
| #if !defined(MYAPIHED_COLD) | |
| #if HEDLEY_HAS_ATTRIBUTE(cold) || HEDLEY_GCC_VERSION_CHECK(4, 3, 0) | |
| #define MYAPIHED_COLD __attribute__ ((__cold__)) | |
| #else | |
| #define MYAPIHED_COLD | |
| #endif | |
| #endif | |
| /* ========================================================================= | |
| * PRINTF FORMAT CHECKING (hedley.h lines 1289-1318) | |
| * | |
| * Usage: | |
| * MYAPIHED_API MYAPIHED_PRINTF(1, 2) | |
| * void myapihed_log(const char *fmt, ...); | |
| * | |
| * fmt_idx – 1-based index of the format-string argument | |
| * first_arg – 1-based index of the first variadic argument | |
| * (use 0 for vprintf-style functions) | |
| * ========================================================================= */ | |
| #define MYAPIHED_PRINTF(fmt_idx, first_arg) \ | |
| HEDLEY_PRINTF_FORMAT (fmt_idx, first_arg) | |
| /* ========================================================================= | |
| * NO-RETURN (hedley.h lines 1145-1186) | |
| * | |
| * Mark functions that never return (abort, longjmp wrappers, etc.) | |
| * Compiler uses this to suppress "missing return" warnings on callers. | |
| * ========================================================================= */ | |
| #define MYAPIHED_NORETURN HEDLEY_NO_RETURN | |
| /* ========================================================================= | |
| * PLUGIN METADATA MACROS | |
| * | |
| * These are purely declarative metadata tags embedded inside plugin | |
| * translation units. They follow the same convention used by projects | |
| * such as GStreamer, LADSPA, LV2, and Audacity: | |
| * | |
| * • Each macro expands to a static const char[] so the information | |
| * survives in the object file and can be queried with `strings` or | |
| * a dedicated loader. | |
| * • MYAPIHED_PLUGIN_AUTHOR / MYAPIHED_PLUGIN_MAINTAINER may appear more | |
| * than once in the same translation unit. | |
| * • MYAPIHED_PLUGIN_CALL_ON_INIT / MYAPIHED_PLUGIN_CALL_ON_EXIT register | |
| * constructor/destructor callbacks using __attribute__((constructor)) | |
| * on GCC/Clang or #pragma init_seg on MSVC. | |
| * ========================================================================= */ | |
| /** Plugin canonical name, e.g. MYAPIHED_PLUGIN_NAME("my-effect") */ | |
| #define MYAPIHED_PLUGIN_NAME(n) \ | |
| static const char \ | |
| _myapihed_plugin_name[] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ( \ | |
| (unused)) \ | |
| = "" n "" | |
| /** Plugin version string, e.g. MYAPIHED_PLUGIN_VERSION("1.2.3") */ | |
| #define MYAPIHED_PLUGIN_VERSION(v) \ | |
| static const char \ | |
| _myapihed_plugin_version[] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ( \ | |
| (unused)) \ | |
| = "" v "" | |
| /** SPDX license identifier, e.g. MYAPIHED_PLUGIN_LICENSE("MIT") */ | |
| #define MYAPIHED_PLUGIN_LICENSE(l) \ | |
| static const char \ | |
| _myapihed_plugin_license[] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ( \ | |
| (unused)) \ | |
| = "" l "" | |
| /** Short description, e.g. MYAPIHED_PLUGIN_DESC("Adds reverb to audio") */ | |
| #define MYAPIHED_PLUGIN_DESC(d) \ | |
| static const char \ | |
| _myapihed_plugin_desc[] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ( \ | |
| (unused)) \ | |
| = "" d "" | |
| /** Homepage / repository URL, e.g. | |
| * MYAPIHED_PLUGIN_HOMEPAGE("https://example.com") */ | |
| #define MYAPIHED_PLUGIN_HOMEPAGE(u) \ | |
| static const char \ | |
| _myapihed_plugin_homepage[] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ( \ | |
| (unused)) \ | |
| = "" u "" | |
| /* | |
| * For MAINTAINER and AUTHOR we use a __COUNTER__-based unique symbol so the | |
| * macro can be repeated multiple times in the same translation unit without | |
| * triggering duplicate-symbol errors. | |
| * | |
| * __COUNTER__ is supported by GCC >= 4.3, Clang, MSVC >= 2005, and ICC. | |
| * On compilers without it we fall back to __LINE__ (still allows multiple | |
| * authors as long as they are on different lines, which is the normal case). | |
| *l/ | |
| #if defined(__COUNTER__) | |
| #define MYAPIHED_PLUGIN_UNIQUE_ __COUNTER__ | |
| #else | |
| #define MYAPIHED_PLUGIN_UNIQUE_ __LINE__ | |
| #endif | |
| /* Internal paste helpers */ | |
| #define MYAPIHED_PASTE__(a, b) a##b | |
| #define MYAPIHED_PASTE_(a, b) MYAPIHED_PASTE__ (a, b) | |
| /** | |
| * Maintainer record. May appear once or more. | |
| * MYAPIHED_PLUGIN_MAINTAINER("Alice Smith", "alice@example.com") | |
| */ | |
| #define MYAPIHED_PLUGIN_MAINTAINER(n, e) \ | |
| static const char MYAPIHED_PASTE_ (_myapihed_plugin_maintainer_, \ | |
| MYAPIHED_PLUGIN_UNIQUE_) \ | |
| [] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ((unused)) \ | |
| = "maintainer:" n " <" e ">" | |
| /** | |
| * Author record. May appear multiple times. | |
| * MYAPIHED_PLUGIN_AUTHOR("Bob Jones", "bob@example.com") | |
| * MYAPIHED_PLUGIN_AUTHOR("Carol Wu", "carol@example.com") | |
| */ | |
| #define MYAPIHED_PLUGIN_AUTHOR(a, e) \ | |
| static const char MYAPIHED_PASTE_ (_myapihed_plugin_author_, \ | |
| MYAPIHED_PLUGIN_UNIQUE_) \ | |
| [] HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ ((unused)) \ | |
| = "author:" a " <" e ">" | |
| /* ------------------------------------------------------------------------- | |
| * Constructor / destructor callbacks | |
| * ------------------------------------------------------------------------- */ | |
| #if defined(_MSC_VER) | |
| /* | |
| * MSVC: use CRT init-seg hooks. | |
| * The function is placed in the .CRT$XCU (constructor) or .CRT$XPU | |
| * (pre-termination) segment and called automatically by the CRT. | |
| */ | |
| #pragma section(".CRT$XCU", read) | |
| #pragma section(".CRT$XPU", read) | |
| #define MYAPIHED_PLUGIN_CALL_ON_INIT(fn) \ | |
| static void fn (void); \ | |
| __declspec (allocate (".CRT$XCU")) static void ( \ | |
| *MYAPIHED_PASTE_ (_myapihed_init_ptr_, __COUNTER__)) (void) \ | |
| = (fn); \ | |
| static void fn (void) | |
| #define MYAPIHED_PLUGIN_CALL_ON_EXIT(fn) \ | |
| static void fn (void); \ | |
| __declspec (allocate (".CRT$XPU")) static void ( \ | |
| *MYAPIHED_PASTE_ (_myapihed_exit_ptr_, __COUNTER__)) (void) \ | |
| = (fn); \ | |
| static void fn (void) | |
| #elif defined(__GNUC__) || defined(__clang__) | |
| /* | |
| * GCC / Clang: __attribute__((constructor)) / __attribute__((destructor)) | |
| * Priority 101 leaves room below 100 for C++ static objects. | |
| */ | |
| #define MYAPIHED_PLUGIN_CALL_ON_INIT(fn) \ | |
| __attribute__ ((__constructor__ (101))) static void fn (void) | |
| #define MYAPIHED_PLUGIN_CALL_ON_EXIT(fn) \ | |
| __attribute__ ((__destructor__ (101))) static void fn (void) | |
| #else | |
| /* Unknown toolchain: best-effort via _init / _fini weak symbols. */ | |
| #define MYAPIHED_PLUGIN_CALL_ON_INIT(fn) static void fn (void) | |
| #define MYAPIHED_PLUGIN_CALL_ON_EXIT(fn) static void fn (void) | |
| #warning "MYAPIHED: automatic plugin init/exit not supported on this compiler." | |
| #endif | |
| #if __cplusplus | |
| #define MYAPIHED_XDECL(l) extern #l | |
| #define MYAPIHED_XDECL_BEGIN(l) \ | |
| extern #l \ | |
| { | |
| #define MYAPIHED_XDECL_END() } | |
| #else | |
| #define MYAPIHED_XDECL(l) | |
| #define MYAPIHED_XDECL_BEGIN(l) | |
| #define MYAPIHED_XDECL_END(l) | |
| #endif | |
| #endif /* MYAPIHED_API_H */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment