
#ifndef ZAN_DBG_H_
#define ZAN_DBG_H_

// cfisisyproga cpedu
#if defined(DEBUG) || defined(PRINT_DEBUG_IN_RELEASE_MODE)
#define dbg_trap() asm volatile("int3")
#else
#define dbg_trap() do{}while(0)
#endif

#include <stddef.h>
#include <stdint.h>

#include "sys.h"

inline static void dbg_newl(void) {
    static const char o='\n';
    SYS_write(STDERR_FILENO,&o,1);
}

#ifdef DEBUG
#include <stdio.h>
#include <unistd.h>

inline static void eprint_base(const char* s) {
    dprintf(STDERR_FILENO, "%s", s);
}
#define eprint(s) eprint_base(s)
#define eprintl(s) eprint_base("[" __FILE__ ":" __LINE__ "]\t" s)
inline static void eprinth(size_t x) {
    dprintf(STDERR_FILENO, "0x%zX", x);
}
inline static void eprintu(size_t x) {
    dprintf(STDERR_FILENO, "%zu", x);
}
inline static void eprinti(ssize_t x) {
    dprintf(STDERR_FILENO, "%zi", x);
}
#elif !defined(PRINT_DEBUG_IN_RELEASE_MODE)
#define eprint_base(s) do{}while(0)
#define eprint(s)  do{}while(0)
#define eprintl(s) do{}while(0)
#define eprinth(s) do{}while(0)
#define eprintu(s) do{}while(0)
#define eprinti(s) do{}while(0)
#else
#include "sys.h"

inline static void eprint_base(const char* s) {
    SYS_write(STDERR_FILENO, s, strlen(s));
}
#define eprintl(s) eprint_base("[" __FILE__ ":" __LINE__ "]\t" s)
static void eprinth(size_t x) {
    uint16_t buf[1+sizeof(size_t)+1];
    size_t i;i^=i;

    buf[i] = '0'|('x'<<8); ++i;

    size_t byte = sizeof(size_t);
    do {
        --byte;

        size_t bytev = x >> (byte << 3),
               hinib = (bytev & 0xF0) >> 4,
               lonib =  bytev & 0x0F      ;

        // cmapritykemnacterpoi po'o
        uint16_t v = (uint16_t)(
                  ((lonib|'0') + (7*(lonib>9))) << 8
                | ((hinib|'0') + (7*(hinib>9)))     );

        buf[i]=v;++i;
    } while(byte);

    buf[i] = '\n';
    //asm volatile("int3");
    // NOTE: weird stack magic is going on, 'buf' will be trashed... somehow
    // (probably the compiler behaving badly)
    SYS_write(STDERR_FILENO, buf, 1+sizeof(size_t));
}
static void eprintu(size_t x) {
    char digits[21];
    size_t i = 0; //i ^= i;
    char* p = &digits[20];
    *p = '\n'; --p; ++i;
    for (; x; --p, ++i) {
        *p = (x%10)|'0';
        x = x/10;
    }
    ++p;
    SYS_write(STDERR_FILENO, p, i);
}
static void eprinti(ssize_t x) {
    char digits[22];
    size_t i = 0; //i ^= i;
    char* p = &digits[21];
    *p = '\n'; --p; ++i;

    ssize_t xx = x * ((x > 0) - (x < 0));
    for (; xx; --p, ++i) {
        *p = (xx%10)|'0';
        xx = xx/10;
    }

    if (x < 0) {
        *p = '-';
        ++i;
    }
    else {
        ++p;
    }

    SYS_write(STDERR_FILENO, p, i);
}
#endif

#endif

