-
Notifications
You must be signed in to change notification settings - Fork 28
/
Support.h
123 lines (97 loc) · 2.89 KB
/
Support.h
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
#pragma once
#define WIN32_LEAN_AND_MEAN
// WIN32_FAT_AND_STUPID
#include <stdexcept>
#include <string>
#include <string_view>
#include <utility>
#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 get_command_line(std::string_view arguments) {
struct argument_set {
std::string_view flags;
std::string_view executable;
std::string_view arguments;
};
try {
argument_set ret;
auto const end_flags = arguments.find('"');
ret.flags = trim(arguments.substr(0, end_flags));
if(end_flags != std::string_view::npos) {
arguments.remove_prefix(end_flags + 1);
auto const end_executable = arguments.find('"');
if(end_executable != std::string_view::npos) {
ret.executable = trim(arguments.substr(0, end_executable));
arguments.remove_prefix(end_executable + 1);
ret.arguments = trim(arguments);
return ret;
}
}
} catch(...) {
// swallow everything, throw new one
}
throw invalid_command_arguments{};
}
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 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));
}