/driver/args.cpp

https://github.com/Syniurge/Calypso · C++ · 126 lines · 99 code · 16 blank · 11 comment · 8 complexity · 1ab69ee0cef2ab90ab0a225656d52300 MD5 · raw file

  1. //===-- args.cpp ----------------------------------------------------------===//
  2. //
  3. // LDC – the LLVM D compiler
  4. //
  5. // This file is distributed under the BSD-style LDC license. See the LICENSE
  6. // file for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "args.h"
  10. #include "llvm/Support/CommandLine.h"
  11. #include "llvm/Support/StringSaver.h"
  12. #include <cstdlib>
  13. #ifdef _WIN32
  14. #include "llvm/Support/ConvertUTF.h"
  15. #endif
  16. #if LDC_WINDOWS_WMAIN
  17. #define WIN32_LEAN_AND_MEAN
  18. #include <windows.h>
  19. #endif
  20. extern "C" {
  21. // in driver/main.d:
  22. int _Dmain(/*string[] args*/);
  23. // in druntime:
  24. int _d_run_main(int argc, const char **argv, int (*dMain)());
  25. #if LDC_WINDOWS_WMAIN
  26. int _d_wrun_main(int argc, const wchar_t **wargv, int (*dMain)());
  27. #endif
  28. }
  29. namespace args {
  30. static llvm::BumpPtrAllocator allocator;
  31. void getCommandLineArguments(int argc, const CArgChar **argv,
  32. llvm::SmallVectorImpl<const char *> &result) {
  33. #if LDC_WINDOWS_WMAIN
  34. // convert from UTF-16 to UTF-8
  35. result.reserve(argc);
  36. for (int i = 0; i < argc; ++i) {
  37. const wchar_t *warg = argv[i];
  38. const size_t wlen = wcslen(warg) + 1; // incl. terminating null
  39. const int len = WideCharToMultiByte(CP_UTF8, 0, warg, wlen, nullptr, 0,
  40. nullptr, nullptr);
  41. char *arg = allocator.Allocate<char>(len);
  42. WideCharToMultiByte(CP_UTF8, 0, warg, wlen, arg, len, nullptr, nullptr);
  43. result.push_back(arg);
  44. }
  45. #else
  46. #ifdef _WIN32
  47. #pragma message ("Using current code page instead of UTF-8 for command-line args")
  48. #endif
  49. result.insert(result.end(), argv, argv + argc);
  50. #endif
  51. }
  52. void expandResponseFiles(llvm::SmallVectorImpl<const char *> &args) {
  53. llvm::StringSaver saver(allocator);
  54. llvm::cl::ExpandResponseFiles(saver,
  55. #ifdef _WIN32
  56. llvm::cl::TokenizeWindowsCommandLine
  57. #else
  58. llvm::cl::TokenizeGNUCommandLine
  59. #endif
  60. ,
  61. args);
  62. }
  63. int forwardToDruntime(int argc, const CArgChar **argv) {
  64. #if LDC_WINDOWS_WMAIN
  65. return _d_wrun_main(argc, argv, &_Dmain);
  66. #else
  67. return _d_run_main(argc, argv, &_Dmain);
  68. #endif
  69. }
  70. bool isRunArg(const char *arg) {
  71. return strcmp(arg, "-run") == 0 || strcmp(arg, "--run") == 0;
  72. }
  73. } // namespace args
  74. namespace env {
  75. #ifdef _WIN32
  76. static wchar_t *wget(const char *name) {
  77. llvm::SmallVector<wchar_t, 32> wname;
  78. llvm::sys::windows::UTF8ToUTF16(name, wname);
  79. wname.push_back(0);
  80. return _wgetenv(wname.data());
  81. }
  82. #endif
  83. bool has(const char *name) {
  84. #ifdef _WIN32
  85. return wget(name) != nullptr;
  86. #else
  87. return getenv(name) != nullptr;
  88. #endif
  89. }
  90. #ifdef _WIN32
  91. bool has(const wchar_t *wname) { return _wgetenv(wname) != nullptr; }
  92. #endif
  93. std::string get(const char *name) {
  94. #ifdef _WIN32
  95. #if LDC_LLVM_VER >= 400
  96. using llvm::UTF16;
  97. #endif
  98. const wchar_t *wvalue = wget(name);
  99. std::string value;
  100. if (wvalue) {
  101. llvm::convertUTF16ToUTF8String(
  102. {reinterpret_cast<const UTF16 *>(wvalue), wcslen(wvalue)}, value);
  103. }
  104. return value;
  105. #else
  106. const char *value = getenv(name);
  107. return value ? value : "";
  108. #endif
  109. }
  110. }