#ifndef RT_VOYAGE_H #define RT_VOYAGE_H /* basic types and macros */ #include #include #if defined(_MSC_VER) && !defined(RT_STATIC_LIB) #define RT_DLLEXPORT __declspec(dllexport) #else #define RT_DLLEXPORT #endif #if defined(_MSC_VER) #define RT_INLINE __forceinline #elif defined(__GNUC__) || defined(__clang__) #define RT_INLINE inline __attribute__((always_inline)) #endif #define RT_UNUSED(x) ((void)sizeof((x))) #define RT_ARRAY_COUNT(x) (sizeof((x)) / sizeof((x)[0])) #define RT_KB(n) ((n)*1024U) #define RT_MB(n) ((n)*1024U * 1024U) #define RT_GB(n) ((n)*1024U * 1024U * 1024U) typedef unsigned int rt_result; /* Default result codes */ enum { RT_SUCCESS = 0, RT_OUT_OF_MEMORY = 1, RT_CUSTOM_ERROR_START, RT_UNKNOWN_ERROR = (rt_result)-1, }; typedef struct { const char *start; unsigned int length; } rt_text_span; /* Returns results like strcmp(): * - If the first differing character is smaller in span than in cmp: < 0 * - If span and cmp are equal: 0 * - If the first differing character is greater in span than in cmp: > 0 * - If span.length is smaller than strlen(cmp): -1 * - If span.length is greater than strlen(cmp): 1 */ RT_DLLEXPORT int rtCompareSpanToString(rt_text_span span, const char *cmp); RT_DLLEXPORT void rtReportError(const char *subsystem, const char *fmt, ...); RT_DLLEXPORT void rtLog(const char *subsystem, const char *fmt, ...); enum { RT_INVALID_UNICODE = RT_CUSTOM_ERROR_START, RT_INSUFFICIENT_BUFFER, }; /* Returns RT_SUCCESS if the string was successfully converted, * RT_INVALID_UNICODE if invalid unicode characters were encountered or * RT_INSUFFICIENT_BUFFER if the provided output buffer is too small */ RT_DLLEXPORT rt_result rtUTF8ToWStr(const char *utf8, wchar_t *wstr, size_t len); /* Returns RT_SUCCESS if the string was successfully converted, * RT_INVALID_UNICODE if invalid unicode characters were encountered or * RT_INSUFFICIENT_BUFFER if the provided output buffer is too small */ RT_DLLEXPORT rt_result rtWStrToUTF8(const wchar_t *wstr, char *utf8, size_t len); /* Relative pointer */ typedef struct { int32_t off; } rt_relptr; static RT_INLINE void *rtResolveRelptr(rt_relptr *ptr) { if (ptr->off != 0) { char *p = (char *)ptr; return (void *)(p + (ptrdiff_t)ptr->off); } else { return NULL; } } static RT_INLINE void rtSetRelptr(rt_relptr *ptr, void *target) { if (target) { char *p = (char *)ptr, *t = (char *)target; ptrdiff_t d = t - p; ptr->off = (int32_t)d; } else { ptr->off = 0; } } /* Bitfiddling functions */ /* Portable solution, On x64 using clzl is probably faster. */ static RT_INLINE uint32_t rtNextPowerOfTwo32(uint32_t v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } /* Runtime init. Initializes basic systems. * You need to call this, even if you build a CLI only app. */ RT_DLLEXPORT rt_result rtInitRuntime(void); RT_DLLEXPORT void rtShutdownRuntime(void); #endif