BareGit
#include <cstdarg>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <map>
#include <vector>
#include <unistd.h>

extern "C"
{
#include "config.h"
#include "integer.h"
#include "tradstdc.h"
#include "global.h"
#include "wintype.h"
}

extern "C"
{

int nhmain(int argc, char* argv[]);

using ShimCallback = void (*)(const char*, void*, const char*, ...);

void shim_graphics_set_callback(ShimCallback callback);

}

namespace
{

std::map<int, std::vector<anything>> menus;
bool map_was_drawn = false;

void set_int_return(void* return_ptr, int value)
{
    if(return_ptr != nullptr)
    {
        *static_cast<int*>(return_ptr) = value;
    }
}

void set_string_return(void* return_ptr, const char* value)
{
    if(return_ptr == nullptr)
    {
        return;
    }

    auto** destination = static_cast<char**>(return_ptr);
    *destination = const_cast<char*>(value);
}

void probe_callback(const char* name, void* return_ptr, const char* fmt, ...)
{
    if(name == nullptr)
    {
        return;
    }

    va_list arguments;
    va_start(arguments, fmt);
    if(std::strcmp(name, "shim_raw_print") == 0
       || std::strcmp(name, "shim_raw_print_bold") == 0)
    {
        const char* message = va_arg(arguments, const char*);
        std::fprintf(stderr, "NetHack: %s\n",
                     message == nullptr ? "(null)" : message);
    }
    else if(std::strcmp(name, "shim_start_menu") == 0)
    {
        int window = va_arg(arguments, int);
        (void) va_arg(arguments, unsigned long);
        menus[window].clear();
    }
    else if(std::strcmp(name, "shim_add_menu") == 0)
    {
        int window = va_arg(arguments, int);
        (void) va_arg(arguments, const void*);
        const auto* identifier = va_arg(arguments, const anything*);
        (void) va_arg(arguments, int);
        (void) va_arg(arguments, int);
        (void) va_arg(arguments, int);
        (void) va_arg(arguments, int);
        (void) va_arg(arguments, const char*);
        (void) va_arg(arguments, unsigned int);
        if(identifier != nullptr)
        {
            menus[window].push_back(*identifier);
        }
    }
    else if(std::strcmp(name, "shim_select_menu") == 0)
    {
        int window = va_arg(arguments, int);
        int how = va_arg(arguments, int);
        auto** menu_list = va_arg(arguments, menu_item**);
        const auto found = menus.find(window);
        if(how != 0 && menu_list != nullptr && found != menus.end()
           && !found->second.empty())
        {
            auto* selected = static_cast<menu_item*>(
                std::malloc(sizeof(menu_item)));
            if(selected != nullptr)
            {
                selected[0].item = found->second.front();
                selected[0].count = -1;
                selected[0].itemflags = 0;
                *menu_list = selected;
                va_end(arguments);
                set_int_return(return_ptr, 1);
                return;
            }
        }
        va_end(arguments);
        set_int_return(return_ptr, 0);
        return;
    }
    else if(std::strcmp(name, "shim_print_glyph") == 0)
    {
        map_was_drawn = true;
    }
    else if(map_was_drawn
            && (std::strcmp(name, "shim_nhgetch") == 0
                || std::strcmp(name, "shim_nh_poskey") == 0))
    {
        std::fprintf(stderr, "NetHack library startup reached the first key.\n");
        std::_Exit(0);
    }
    va_end(arguments);
    if(name == nullptr || return_ptr == nullptr)
    {
        return;
    }

    if(std::strcmp(name, "shim_nhgetch") == 0
       || std::strcmp(name, "shim_nh_poskey") == 0
       || std::strcmp(name, "shim_message_menu") == 0)
    {
        *static_cast<int*>(return_ptr) = 27;
    }
    else if(std::strcmp(name, "shim_yn_function") == 0)
    {
        *static_cast<char*>(return_ptr) = 27;
    }
    else if(std::strcmp(name, "shim_get_ext_cmd") == 0)
    {
        *static_cast<int*>(return_ptr) = -1;
    }
    else if(std::strcmp(name, "shim_select_menu") == 0)
    {
        *static_cast<int*>(return_ptr) = 0;
    }
    else if(std::strcmp(name, "shim_get_color_string") == 0)
    {
        set_string_return(return_ptr, "");
    }
}

} // namespace

int main(int argc, char* argv[])
{
#ifdef NETHACK_PROBE_RUNTIME_DIR
    if(chdir(NETHACK_PROBE_RUNTIME_DIR) != 0)
    {
        std::perror("chdir");
        return 1;
    }
#endif

    shim_graphics_set_callback(probe_callback);

    if(argc == 1)
    {
        char program[] = "nethack_engine_probe";
        char name_option[] = "-u";
        char name[] = "Agent";
        char* probe_argv[] = {program, name_option, name, nullptr};
        return nhmain(3, probe_argv);
    }

    return nhmain(argc, argv);
}