Skip to content

Commit 47af181

Browse files
add Platform enum
1 parent 774f87f commit 47af181

File tree

10 files changed

+137
-70
lines changed

10 files changed

+137
-70
lines changed

CMakeLists.txt

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,22 @@ if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "aarch64" OR "${IS_LINUX_ARMV}" GRE
6969
endif()
7070

7171
add_executable(bindiff src/BinDiff.cc)
72-
target_link_libraries(bindiff phosg)
73-
7472
add_executable(jsonformat src/JSONFormat.cc)
75-
target_link_libraries(jsonformat phosg)
76-
7773
add_executable(parse-data src/ParseData.cc)
78-
target_link_libraries(parse-data phosg)
79-
8074
add_executable(phosg-png-conv src/PhosgPNGConv.cc)
75+
76+
target_link_libraries(bindiff phosg)
77+
target_link_libraries(jsonformat phosg)
78+
target_link_libraries(parse-data phosg)
8179
target_link_libraries(phosg-png-conv phosg)
8280

81+
if (WIN32)
82+
target_link_libraries(bindiff -static -static-libgcc -static-libstdc++)
83+
target_link_libraries(jsonformat -static -static-libgcc -static-libstdc++)
84+
target_link_libraries(parse-data -static -static-libgcc -static-libstdc++)
85+
target_link_libraries(phosg-png-conv -static -static-libgcc -static-libstdc++)
86+
endif()
87+
8388

8489

8590
# Test definitions
@@ -91,10 +96,16 @@ enable_testing()
9196

9297
add_executable(ToolsTest src/ToolsTest.cc)
9398
target_link_libraries(ToolsTest phosg)
99+
if (WIN32)
100+
target_link_libraries(ToolsTest -static -static-libgcc -static-libstdc++)
101+
endif()
94102

95103
foreach(TestName IN ITEMS ArgumentsTest EncodingTest FilesystemTest HashTest ImageTest JSONTest KDTreeTest LRUMapTest LRUSetTest MathTest ProcessTest StringsTest TimeTest UnitTestTest)
96104
add_executable(${TestName} src/${TestName}.cc)
97105
target_link_libraries(${TestName} phosg)
106+
if (WIN32)
107+
target_link_libraries(${TestName} -static -static-libgcc -static-libstdc++)
108+
endif()
98109
add_test(NAME ${TestName} COMMAND ${TestName})
99110
endforeach()
100111

src/FilesystemTest.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ int main(int, char**) {
1818
save_file(filename, data);
1919
expect_eq("0123456789", load_file(filename));
2020

21-
expect_eq(data.size(), (size_t)stat(filename).st_size);
2221
#ifndef PHOSG_WINDOWS
22+
expect_eq(data.size(), (size_t)stat(filename).st_size);
2323
expect_eq(data.size(), (size_t)lstat(filename).st_size);
2424

2525
symlink(filename.c_str(), symlink_name.c_str());
@@ -30,8 +30,10 @@ int main(int, char**) {
3030

3131
{
3232
auto f = fopen_unique(filename, "r+b");
33+
#ifndef PHOSG_WINDOWS
3334
expect_eq(data.size(), (size_t)fstat(f.get()).st_size);
3435
expect_eq(data.size(), (size_t)fstat(fileno(f.get())).st_size);
36+
#endif
3537
fseek(f.get(), 5, SEEK_SET);
3638
fwrite(data.data(), 1, data.size(), f.get());
3739
}

src/Platform.hh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,45 @@
44

55
namespace phosg {
66

7+
enum class Platform {
8+
MACOS = 0,
9+
LINUX,
10+
WINDOWS,
11+
UNIX,
12+
POSIX,
13+
};
14+
715
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__CYGWIN__)
816
#define PHOSG_WINDOWS
17+
constexpr Platform PLATFORM = Platform::WINDOWS;
918

1019
#elif __APPLE__
1120
#define PHOSG_MACOS
21+
constexpr Platform PLATFORM = Platform::MACOS;
1222

1323
#elif __linux__
1424
#define PHOSG_LINUX
25+
constexpr Platform PLATFORM = Platform::LINUX;
1526

1627
#elif __unix__
1728
#define PHOSG_UNIX
29+
constexpr Platform PLATFORM = Platform::UNIX;
1830

1931
#elif defined(_POSIX_VERSION)
2032
#define PHOSG_POSIX
33+
constexpr Platform PLATFORM = Platform::POSIX;
2134

2235
#else
2336
#error "Unknown platform"
2437
#endif
2538

39+
constexpr inline bool is_windows() {
40+
return PLATFORM == Platform::WINDOWS;
41+
}
42+
constexpr inline bool is_macos() {
43+
return PLATFORM == Platform::MACOS;
44+
}
45+
2646
// Try to determine endianess from GCC defines first. If they aren't available,
2747
// use some constants to try to figure it out
2848
// clang-format off

src/Process.cc

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,38 @@ using namespace std;
3232

3333
namespace phosg {
3434

35+
#ifndef PHOSG_WINDOWS
36+
static bool atfork_handler_added = false;
37+
static pid_t cached_this_process_pid = 0;
38+
static uint64_t cached_this_process_start_time = 0;
39+
40+
static void clear_cached_pid_vars() {
41+
cached_this_process_pid = 0;
42+
cached_this_process_start_time = 0;
43+
// TODO: do pthread_atfork() handlers survive in the child process? if not,
44+
// we should set atfork_handler_added to false here
45+
}
46+
47+
static void maybe_add_atfork_handler() {
48+
if (!atfork_handler_added) {
49+
pthread_atfork(nullptr, nullptr, clear_cached_pid_vars);
50+
atfork_handler_added = true;
51+
}
52+
}
53+
#endif
54+
55+
pid_t getpid_cached() {
56+
#ifndef PHOSG_WINDOWS
57+
if (!cached_this_process_pid) {
58+
maybe_add_atfork_handler();
59+
cached_this_process_pid = getpid();
60+
}
61+
return cached_this_process_pid;
62+
#else
63+
return _getpid();
64+
#endif
65+
}
66+
3567
#ifndef PHOSG_WINDOWS
3668
unique_ptr<FILE, void (*)(FILE*)> popen_unique(const string& command, const string& mode) {
3769
unique_ptr<FILE, void (*)(FILE*)> f(
@@ -197,32 +229,6 @@ uint64_t start_time_for_pid(pid_t pid, bool allow_zombie) {
197229
#endif
198230
}
199231

200-
static bool atfork_handler_added = false;
201-
static pid_t cached_this_process_pid = 0;
202-
static uint64_t cached_this_process_start_time = 0;
203-
204-
static void clear_cached_pid_vars() {
205-
cached_this_process_pid = 0;
206-
cached_this_process_start_time = 0;
207-
// TODO: do pthread_atfork() handlers survive in the child process? if not,
208-
// we should set atfork_handler_added to false here
209-
}
210-
211-
static void maybe_add_atfork_handler() {
212-
if (!atfork_handler_added) {
213-
pthread_atfork(nullptr, nullptr, clear_cached_pid_vars);
214-
atfork_handler_added = true;
215-
}
216-
}
217-
218-
pid_t getpid_cached() {
219-
if (!cached_this_process_pid) {
220-
maybe_add_atfork_handler();
221-
cached_this_process_pid = getpid();
222-
}
223-
return cached_this_process_pid;
224-
}
225-
226232
uint64_t this_process_start_time() {
227233
if (!cached_this_process_start_time) {
228234
// don't need to call maybe_add_atfork_handler; getpid_cached will do it

src/Process.hh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
namespace phosg {
1515

16+
pid_t getpid_cached();
17+
1618
#ifndef PHOSG_WINDOWS
1719
std::unique_ptr<FILE, void (*)(FILE*)> popen_unique(const std::string& command, const std::string& mode);
1820

@@ -33,8 +35,6 @@ bool pid_is_zombie(pid_t pid);
3335
uint64_t start_time_for_pid(pid_t pid, bool allow_zombie = false);
3436
uint64_t this_process_start_time();
3537

36-
pid_t getpid_cached();
37-
3838
class Subprocess {
3939
public:
4040
Subprocess();

src/Strings.cc

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -143,17 +143,17 @@ uint8_t value_for_hex_char(char x) {
143143
template <>
144144
LogLevel enum_for_name<LogLevel>(const char* name) {
145145
if (!strcmp(name, "USE_DEFAULT")) {
146-
return LogLevel::USE_DEFAULT;
146+
return LogLevel::L_USE_DEFAULT;
147147
} else if (!strcmp(name, "DEBUG")) {
148-
return LogLevel::DEBUG;
148+
return LogLevel::L_DEBUG;
149149
} else if (!strcmp(name, "INFO")) {
150-
return LogLevel::INFO;
150+
return LogLevel::L_INFO;
151151
} else if (!strcmp(name, "WARNING")) {
152-
return LogLevel::WARNING;
152+
return LogLevel::L_WARNING;
153153
} else if (!strcmp(name, "ERROR")) {
154-
return LogLevel::ERROR;
154+
return LogLevel::L_ERROR;
155155
} else if (!strcmp(name, "DISABLED")) {
156-
return LogLevel::DISABLED;
156+
return LogLevel::L_DISABLED;
157157
} else {
158158
throw invalid_argument("invalid LogLevel name");
159159
}
@@ -162,24 +162,24 @@ LogLevel enum_for_name<LogLevel>(const char* name) {
162162
template <>
163163
const char* name_for_enum<LogLevel>(LogLevel level) {
164164
switch (level) {
165-
case LogLevel::USE_DEFAULT:
165+
case LogLevel::L_USE_DEFAULT:
166166
return "USE_DEFAULT";
167-
case LogLevel::DEBUG:
167+
case LogLevel::L_DEBUG:
168168
return "DEBUG";
169-
case LogLevel::INFO:
169+
case LogLevel::L_INFO:
170170
return "INFO";
171-
case LogLevel::WARNING:
171+
case LogLevel::L_WARNING:
172172
return "WARNING";
173-
case LogLevel::ERROR:
173+
case LogLevel::L_ERROR:
174174
return "ERROR";
175-
case LogLevel::DISABLED:
175+
case LogLevel::L_DISABLED:
176176
return "DISABLED";
177177
default:
178178
throw invalid_argument("invalid LogLevel value");
179179
}
180180
}
181181

182-
static LogLevel current_log_level = LogLevel::INFO;
182+
static LogLevel current_log_level = LogLevel::L_INFO;
183183

184184
LogLevel log_level() {
185185
return current_log_level;
@@ -200,7 +200,11 @@ void print_log_prefix(FILE* stream, LogLevel level) {
200200
char time_buffer[32];
201201
time_t now_secs = time(nullptr);
202202
struct tm now_tm;
203+
#ifndef PHOSG_WINDOWS
203204
localtime_r(&now_secs, &now_tm);
205+
#else
206+
localtime_s(&now_tm, &now_secs);
207+
#endif
204208
strftime(time_buffer, sizeof(time_buffer), "%Y-%m-%d %H:%M:%S", &now_tm);
205209
char level_char = log_level_chars.at(static_cast<int>(level));
206210
fwrite_fmt(stream, "{:c} {} {} - ", level_char, getpid_cached(), time_buffer);
@@ -211,7 +215,7 @@ PrefixedLogger::PrefixedLogger(const string& prefix, LogLevel min_level)
211215
min_level(min_level) {}
212216

213217
PrefixedLogger PrefixedLogger::sub(const std::string& prefix, LogLevel min_level) const {
214-
return PrefixedLogger(this->prefix + prefix, min_level == LogLevel::USE_DEFAULT ? this->min_level : min_level);
218+
return PrefixedLogger(this->prefix + prefix, min_level == LogLevel::L_USE_DEFAULT ? this->min_level : min_level);
215219
}
216220

217221
vector<string> split(const string& s, char delim, size_t max_splits) {
@@ -406,7 +410,11 @@ size_t skip_word(const char* s, size_t offset) {
406410

407411
string string_for_error(int error) {
408412
char buffer[1024] = "Unknown error";
413+
#ifndef PHOSG_WINDOWS
409414
strerror_r(error, buffer, sizeof(buffer));
415+
#else
416+
strerror_s(buffer, sizeof(buffer), error);
417+
#endif
410418
return std::format("{} ({})", error, buffer);
411419
}
412420

src/Strings.hh

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@
1515
#include "Filesystem.hh"
1616
#include "Platform.hh"
1717

18+
#ifdef PHOSG_WINDOWS
19+
// Apparently Windows doesn't have iovec; we define it outside of the phosg
20+
// namespace so code that uses it won't have to special-case Windows or use
21+
// `using iovec = phosg::iovec'.
22+
struct iovec {
23+
void* iov_base;
24+
size_t iov_len;
25+
};
26+
#endif
27+
1828
namespace phosg {
1929

2030
template <typename... ArgTs>
@@ -120,13 +130,14 @@ inline std::string escape_controls_utf8(const std::string& s) {
120130

121131
uint8_t value_for_hex_char(char x);
122132

133+
// windows.h apparently #defines ERROR, hence the prefixes here :|
123134
enum class LogLevel : int {
124-
USE_DEFAULT = -1,
125-
DEBUG = 0,
126-
INFO = 1,
127-
WARNING = 2,
128-
ERROR = 3,
129-
DISABLED = 4,
135+
L_USE_DEFAULT = -1,
136+
L_DEBUG = 0,
137+
L_INFO = 1,
138+
L_WARNING = 2,
139+
L_ERROR = 3,
140+
L_DISABLED = 4,
130141
};
131142

132143
template <>
@@ -160,31 +171,31 @@ bool log_f(std::format_string<ArgTs...> fmt, ArgTs&&... args) {
160171

161172
template <typename... ArgTs>
162173
bool log_debug_f(std::format_string<ArgTs...> fmt, ArgTs&&... args) {
163-
return log_f<LogLevel::DEBUG>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
174+
return log_f<LogLevel::L_DEBUG>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
164175
}
165176
template <typename... ArgTs>
166177
bool log_info_f(std::format_string<ArgTs...> fmt, ArgTs&&... args) {
167-
return log_f<LogLevel::INFO>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
178+
return log_f<LogLevel::L_INFO>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
168179
}
169180
template <typename... ArgTs>
170181
bool log_warning_f(std::format_string<ArgTs...> fmt, ArgTs&&... args) {
171-
return log_f<LogLevel::WARNING>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
182+
return log_f<LogLevel::L_WARNING>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
172183
}
173184
template <typename... ArgTs>
174185
bool log_error_f(std::format_string<ArgTs...> fmt, ArgTs&&... args) {
175-
return log_f<LogLevel::ERROR>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
186+
return log_f<LogLevel::L_ERROR>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
176187
}
177188

178189
struct PrefixedLogger {
179190
std::string prefix;
180191
LogLevel min_level;
181192

182-
explicit PrefixedLogger(const std::string& prefix, LogLevel min_level = LogLevel::USE_DEFAULT);
193+
explicit PrefixedLogger(const std::string& prefix, LogLevel min_level = LogLevel::L_USE_DEFAULT);
183194

184-
PrefixedLogger sub(const std::string& prefix, LogLevel min_level = LogLevel::USE_DEFAULT) const;
195+
PrefixedLogger sub(const std::string& prefix, LogLevel min_level = LogLevel::L_USE_DEFAULT) const;
185196

186197
inline LogLevel effective_level() const {
187-
return this->min_level == LogLevel::USE_DEFAULT ? log_level() : this->min_level;
198+
return this->min_level == LogLevel::L_USE_DEFAULT ? log_level() : this->min_level;
188199
}
189200

190201
inline bool should_log(LogLevel incoming_level) const {
@@ -205,19 +216,19 @@ struct PrefixedLogger {
205216

206217
template <typename... ArgTs>
207218
bool debug_f(std::format_string<ArgTs...> fmt, ArgTs&&... args) const {
208-
return this->log_f<LogLevel::DEBUG>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
219+
return this->log_f<LogLevel::L_DEBUG>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
209220
}
210221
template <typename... ArgTs>
211222
bool info_f(std::format_string<ArgTs...> fmt, ArgTs&&... args) const {
212-
return this->log_f<LogLevel::INFO>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
223+
return this->log_f<LogLevel::L_INFO>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
213224
}
214225
template <typename... ArgTs>
215226
bool warning_f(std::format_string<ArgTs...> fmt, ArgTs&&... args) const {
216-
return this->log_f<LogLevel::WARNING>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
227+
return this->log_f<LogLevel::L_WARNING>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
217228
}
218229
template <typename... ArgTs>
219230
bool error_f(std::format_string<ArgTs...> fmt, ArgTs&&... args) const {
220-
return this->log_f<LogLevel::ERROR>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
231+
return this->log_f<LogLevel::L_ERROR>(std::forward<std::format_string<ArgTs...>>(fmt), std::forward<ArgTs>(args)...);
221232
}
222233
};
223234

0 commit comments

Comments
 (0)