您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

179 行
4.5 KiB

  1. namespace Slime {
  2. inline proc get_cwd() -> char* {
  3. const u32 buf_size = 2048;
  4. char* res = (char*)malloc(buf_size * sizeof(char));
  5. #ifdef _MSC_VER
  6. _getcwd(res, buf_size);
  7. #else
  8. getcwd(res, buf_size);
  9. #endif
  10. return res;
  11. }
  12. inline proc change_cwd(char* dir) -> void {
  13. #ifdef _MSC_VER
  14. _chdir(dir);
  15. #else
  16. chdir(dir);
  17. #endif
  18. }
  19. inline proc duplicate_c_string(const char* str) -> char* {
  20. #ifdef _MSC_VER
  21. return _strdup(str);
  22. #else
  23. return strdup(str);
  24. #endif
  25. }
  26. #ifdef _MSC_VER
  27. s32 vasprintf(char **strp, const char *fmt, va_list ap) {
  28. // _vscprintf tells you how big the buffer needs to be
  29. s32 len = _vscprintf(fmt, ap);
  30. if (len == -1) {
  31. return -1;
  32. }
  33. size_t size = (size_t)len + 1;
  34. char *str = (char*)malloc(size);
  35. if (!str) {
  36. return -1;
  37. }
  38. // _vsprintf_s is the "secure" version of vsprintf
  39. s32 r = vsprintf_s(str, len + 1, fmt, ap);
  40. if (r == -1) {
  41. free(str);
  42. return -1;
  43. }
  44. *strp = str;
  45. return r;
  46. }
  47. s32 asprintf(char **strp, const char *fmt, ...) {
  48. va_list ap;
  49. va_start(ap, fmt);
  50. s32 r = vasprintf(strp, fmt, ap);
  51. va_end(ap);
  52. return r;
  53. }
  54. #endif
  55. proc get_exe_dir() -> path_char* {
  56. #ifdef _MSC_VER
  57. DWORD last_error;
  58. DWORD result;
  59. DWORD path_size = MAX_PATH;
  60. path_char* path = (path_char*)malloc(sizeof(path_char)*path_size);
  61. while (true) {
  62. memset(path, 0, path_size);
  63. result = GetModuleFileName(0, path, path_size - 1);
  64. last_error = GetLastError();
  65. if (0 == result) {
  66. free(path);
  67. path = 0;
  68. break;
  69. }
  70. else if (result == path_size - 1) {
  71. free(path);
  72. /* May need to also check for ERROR_SUCCESS here if XP/2K */
  73. if (ERROR_INSUFFICIENT_BUFFER != last_error) {
  74. path = 0;
  75. break;
  76. }
  77. path_size = path_size * 2;
  78. path = (path_char*)malloc((sizeof(path_char)) * path_size);
  79. }
  80. else
  81. break;
  82. }
  83. if (!path) {
  84. fprintf(stderr, "Failure: %ld\n", last_error);
  85. return nullptr;
  86. }
  87. else {
  88. // remove the exe name, so we are only left with the path
  89. s32 index_in_path = -1;
  90. s32 last_backslash = -1;
  91. path_char c;
  92. while ((c = path[++index_in_path]) != '\0') {
  93. if (c == '\\')
  94. last_backslash = index_in_path;
  95. }
  96. // we are assuming there are some backslashes
  97. path[last_backslash+1] = '\0';
  98. return path;
  99. }
  100. #else
  101. ssize_t size = 512, i, n;
  102. char *path, *temp;
  103. while (1) {
  104. size_t used;
  105. path = (char*)malloc(size);
  106. if (!path) {
  107. errno = ENOMEM;
  108. return NULL;
  109. }
  110. used = readlink("/proc/self/exe", path, size);
  111. if (used == -1) {
  112. const s32 saved_errno = errno;
  113. free(path);
  114. errno = saved_errno;
  115. return NULL;
  116. } else
  117. if (used < 1) {
  118. free(path);
  119. errno = EIO;
  120. return NULL;
  121. }
  122. if ((size_t)used >= size) {
  123. free(path);
  124. size = (size | 2047) + 2049;
  125. continue;
  126. }
  127. size = (size_t)used;
  128. break;
  129. }
  130. /* Find final slash. */
  131. n = 0;
  132. for (i = 0; i < size; i++)
  133. if (path[i] == '/')
  134. n = i;
  135. /* Optimize allocated size,
  136. ensuring there is room for
  137. a final slash and a
  138. string-terminating '\0', */
  139. temp = path;
  140. path = (char*)realloc(temp, n + 2);
  141. if (!path) {
  142. free(temp);
  143. errno = ENOMEM;
  144. return NULL;
  145. }
  146. /* and properly trim and terminate the path string. */
  147. path[n+0] = '/';
  148. path[n+1] = '\0';
  149. return path;
  150. #endif
  151. }
  152. }