120 lines
3.0 KiB
C
120 lines
3.0 KiB
C
#ifndef RT_VOYAGE_H
|
|
#define RT_VOYAGE_H
|
|
|
|
/* basic types and macros */
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#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
|