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