#pragma once

#ifdef __cplusplus
#include <cstdarg>
#include <cstdio>
#include <cstring>
#include <cstddef>
#else
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#endif

#ifndef RTAPI_BEGIN_DECLS
#ifdef __cplusplus
#define RTAPI_BEGIN_DECLS extern "C" {
#define RTAPI_END_DECLS }
#else
#define RTAPI_BEGIN_DECLS
#define RTAPI_END_DECLS
#endif
#endif

#ifndef RTAPI_NAME_LEN
#define RTAPI_NAME_LEN 31
#endif

#ifndef EXPORT_SYMBOL
#define EXPORT_SYMBOL(symbol)
#endif

#ifndef EXPORT_SYMBOL_GPL
#define EXPORT_SYMBOL_GPL(symbol)
#endif

#ifndef MODULE_LICENSE
#define MODULE_LICENSE(value)
#endif

#ifndef MODULE_AUTHOR
#define MODULE_AUTHOR(value)
#endif

#ifndef MODULE_DESCRIPTION
#define MODULE_DESCRIPTION(value)
#endif

#ifndef MODULE_SUPPORTED_DEVICE
#define MODULE_SUPPORTED_DEVICE(value)
#endif

#ifndef MODULE_DEVICE_TABLE
#define MODULE_DEVICE_TABLE(type, name)
#endif

#ifndef MODULE_INFO
#define MODULE_INFO(tag, value)
#endif

#ifndef RTAPI_MP_INT
#define RTAPI_MP_INT(var, descr)
#endif

#ifndef RTAPI_MP_LONG
#define RTAPI_MP_LONG(var, descr)
#endif

#ifndef RTAPI_MP_STRING
#define RTAPI_MP_STRING(var, descr)
#endif

#ifndef RTAPI_MP_ARRAY_INT
#define RTAPI_MP_ARRAY_INT(var, num, descr)
#endif

#ifndef RTAPI_MP_ARRAY_LONG
#define RTAPI_MP_ARRAY_LONG(var, num, descr)
#endif

#ifndef RTAPI_MP_ARRAY_STRING
#define RTAPI_MP_ARRAY_STRING(var, num, descr)
#endif

typedef enum {
    RTAPI_MSG_NONE = 0,
    RTAPI_MSG_ERR,
    RTAPI_MSG_WARN,
    RTAPI_MSG_INFO,
    RTAPI_MSG_DBG,
    RTAPI_MSG_ALL
} msg_level_t;

RTAPI_BEGIN_DECLS

static inline int rtapi_snprintf(char *buf, unsigned long size, const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    int rc = vsnprintf(buf, (size_t)size, fmt, ap);
    va_end(ap);
    return rc;
}

static inline int rtapi_vsnprintf(char *buf, unsigned long size, const char *fmt, va_list ap) {
    return vsnprintf(buf, (size_t)size, fmt, ap);
}

static inline void rtapi_print(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
}

static inline void rtapi_print_msg(msg_level_t, const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
}

static inline int rtapi_set_msg_level(int) {
    return 0;
}

static inline int rtapi_get_msg_level(void) {
    return RTAPI_MSG_ALL;
}

RTAPI_END_DECLS
