aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
blob: 4b0aee48a0c0478b1412b07d3d68b4e78c0a37da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include "core/application.h"
#include "core/log.h"

#include "debugger/debugger.h"

#include <algorithm>
#include <charconv>
#include <cstdlib>
#include <filesystem>
#include <span>
#include <string_view>

namespace
{
    // dev aid: HSDBG_WINDOW=<w>x<h> sizes the window, and HSDBG_BREAK=<file>:<line>
    // plants a breakpoint and launches as soon as the target loads, so a capture
    // (HSDBG_CAPTURE) lands on a stopped target with every panel populated
    auto dev_window_size(Hsdbg::ApplicationSpec& spec) -> void
    {
        const char* text = std::getenv("HSDBG_WINDOW");
        if (text == nullptr)
            return;

        const std::string_view value(text);
        const size_t x = value.find('x');
        if (x == std::string_view::npos)
            return;

        std::from_chars(value.data(), value.data() + x, spec.width);
        std::from_chars(value.data() + x + 1, value.data() + value.size(), spec.height);
    }

    auto dev_break_and_launch(Hsdbg::Debugger& debugger) -> void
    {
        const char* text = std::getenv("HSDBG_BREAK");
        if (text == nullptr || !debugger.has_target())
            return;

        const std::string_view value(text);
        const size_t colon = value.rfind(':');
        if (colon == std::string_view::npos)
            return;

        uint32_t line = 0;
        std::from_chars(value.data() + colon + 1, value.data() + value.size(), line);

        // pick the target's own path for the file so it matches what lldb reports
        const std::string_view name = value.substr(0, colon);
        const std::span<const std::filesystem::path> files = debugger.source_files();
        const auto known = std::ranges::find_if(files, [&](const std::filesystem::path& candidate)
        {
            return candidate.filename() == name;
        });

        debugger.add_breakpoint(known != files.end() ? *known : std::filesystem::path(name), line);

        Hsdbg::LaunchSpec launch;
        launch.executable = debugger.target_path();
        if (const auto result = debugger.launch(launch); !result)
            Hsdbg::Log::error("{}", result.error());
    }
}

auto main(int argc, char** argv) -> int
{
    const std::span arguments(argv, static_cast<size_t>(argc));

    Hsdbg::ApplicationSpec spec;
    spec.name = "hsdbg";
    spec.width = 1600;
    spec.height = 900;
    dev_window_size(spec);

    Hsdbg::Application app(spec);

    if (arguments.size() > 1)
    {
        if (const auto result = app.debugger().load_target(arguments[1]); !result)
            Hsdbg::Log::error("{}", result.error());

        dev_break_and_launch(app.debugger());
    }

    app.run();

    return 0;
}