1 #include "rapidcheck/detail/Platform.h"
2
3 #ifndef _MSC_VER
4 #include <cxxabi.h>
5 #endif // _MSC_VER
6
7 #include <cstdlib>
8
9 namespace rc {
10 namespace detail {
11
12 #ifdef _MSC_VER
13
14 namespace {
15
replaceFirst(std::string & str,const std::string & find,const std::string & replacement)16 bool replaceFirst(std::string &str,
17 const std::string &find,
18 const std::string &replacement) {
19 const auto pos = str.find(find);
20 if (pos == std::string::npos) {
21 return false;
22 }
23
24 const auto it = begin(str) + pos;
25 str.replace(it, it + find.size(), replacement);
26 return true;
27 }
28
replaceAll(std::string & str,const std::string & find,const std::string & replacement)29 bool replaceAll(std::string &str,
30 const std::string &find,
31 const std::string &replacement) {
32 bool replacedAny = false;
33 while (const auto didReplace = replaceFirst(str, find, replacement)) {
34 replacedAny = replacedAny || didReplace;
35 }
36 return replacedAny;
37 }
38
39 } // namespace
40
demangle(const char * name)41 std::string demangle(const char *name) {
42 // Class names are given as "class MyClass" or "struct MyStruct" and we don't
43 // want that so we're gonna strip that away.
44 auto str = std::string(name);
45 replaceAll(str, "__int64", "long long");
46 replaceAll(str, "class ", "");
47 replaceAll(str, "struct ", "");
48 replaceAll(str, "enum ", "");
49 return str;
50 }
51
getEnvValue(const std::string & name)52 Maybe<std::string> getEnvValue(const std::string &name) {
53 char *buffer = nullptr;
54 _dupenv_s(&buffer, nullptr, name.c_str());
55 const auto ptr = std::unique_ptr<char, decltype(&std::free)>(buffer, &std::free);
56
57 if (buffer != nullptr) {
58 return std::string(buffer);
59 } else {
60 return Nothing;
61 }
62 }
63
64 #else // _MSC_VER
65
66 std::string demangle(const char *name) {
67 std::string demangled(name);
68 int status;
69 char *buf = abi::__cxa_demangle(name, nullptr, nullptr, &status);
70 if (status == 0) {
71 demangled = std::string(buf);
72 }
73 free(buf);
74 return demangled;
75 }
76
77 Maybe<std::string> getEnvValue(const std::string &name) {
78 const auto value = std::getenv(name.c_str());
79 if (value != nullptr) {
80 return std::string(value);
81 } else {
82 return Nothing;
83 }
84 }
85
86 #endif // _MSC_VER
87
88 } // namespace detail
89 } // namespace rc
90