forked from Phobos-developers/SyringeEx
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSupport.h
More file actions
169 lines (137 loc) · 3.95 KB
/
Support.h
File metadata and controls
169 lines (137 loc) · 3.95 KB
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#pragma once
#define WIN32_LEAN_AND_MEAN
// WIN32_FAT_AND_STUPID
#include <stdexcept>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include <Windows.h>
struct invalid_command_arguments : std::exception
{
};
inline auto trim(std::string_view string) noexcept
{
auto const first = string.find_first_not_of(' ');
if (first != std::string_view::npos)
{
auto const last = string.find_last_not_of(' ');
string = string.substr(first, last - first + 1);
}
return string;
}
inline auto parse_command_line(const std::vector<std::string>& arguments)
{
static constexpr std::string_view ARGS_FLAG = "--args=";
struct argument_set
{
std::vector<std::string> syringe_arguments;
std::string executable_name;
std::string game_arguments;
};
if (arguments.empty())
throw invalid_command_arguments{};
argument_set ret;
// First non-flag argument becomes executable name
bool exe_found = false;
for (const auto& arg : arguments)
{
// executable name: first argument not starting with '-'
if (!exe_found && !arg.starts_with("-"))
{
exe_found = true;
ret.executable_name = arg;
continue;
}
// game arguments: --args="blob"
if (arg.starts_with(ARGS_FLAG))
{
// extract after --args=
std::string blob = arg.substr(ARGS_FLAG.size());
ret.game_arguments = blob;
continue;
}
// Syringe arguments
ret.syringe_arguments.push_back(arg);
}
if (!exe_found || ret.executable_name.empty())
throw invalid_command_arguments{};
return ret;
}
inline std::string replace(
std::string_view string, std::string_view const pattern,
std::string_view const substitute)
{
std::string ret;
auto pos = 0u;
while ((pos = string.find(pattern)) != std::string::npos)
{
ret += string.substr(0, pos);
string.remove_prefix(pos);
if (string.size() > 1)
{
ret += substitute;
string.remove_prefix(pattern.size());
}
}
ret += string;
return ret;
}
// returns something %.*s can format
inline auto printable(std::string_view const string) noexcept
{
return std::make_pair(string.size(), string.data());
}
inline auto printable(const std::vector<std::string>& arguments) noexcept
{
static thread_local std::string buffer;
buffer.clear();
// Join arguments with spaces
for (size_t i = 0; i < arguments.size(); ++i) {
buffer += arguments[i];
if (i + 1 < arguments.size())
buffer += ' ';
}
return std::make_pair(buffer.size(), buffer.data());
}
inline auto GetFormatMessage(DWORD const error)
{
LocalAllocHandle handle;
auto count = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPTSTR>(handle.set()), 0u, nullptr);
auto const message = static_cast<LPCTSTR>(handle.get());
while (count && isspace(static_cast<unsigned char>(message[count - 1])))
{
--count;
}
return std::string(message, count);
}
struct lasterror : std::exception
{
lasterror(DWORD const error)
: error(error)
{
}
lasterror(DWORD const error, std::string insert)
: error(error), insert(std::move(insert))
{
}
DWORD error{ 0 };
std::string message{ GetFormatMessage(error) };
std::string insert;
};
[[noreturn]] inline void throw_lasterror(DWORD error_code, std::string insert)
{
throw lasterror(error_code, std::move(insert));
}
[[noreturn]] inline void throw_lasterror_or(
DWORD alterative, std::string insert)
{
auto const error_code = GetLastError();
throw_lasterror(
error_code ? error_code : alterative, std::move(insert));
}