|
- namespace Slime {
-
- inline proc get_cwd() -> char* {
- const u32 buf_size = 2048;
- char* res = (char*)malloc(buf_size * sizeof(char));
-
- #ifdef _MSC_VER
- _getcwd(res, buf_size);
- #else
- getcwd(res, buf_size);
- #endif
-
- return res;
- }
-
- inline proc change_cwd(char* dir) -> void {
- #ifdef _MSC_VER
- _chdir(dir);
- #else
- chdir(dir);
- #endif
- }
-
- inline proc duplicate_c_string(const char* str) -> char* {
- #ifdef _MSC_VER
- return _strdup(str);
- #else
- return strdup(str);
- #endif
- }
-
-
- #ifdef _MSC_VER
- s32 vasprintf(char **strp, const char *fmt, va_list ap) {
- // _vscprintf tells you how big the buffer needs to be
- s32 len = _vscprintf(fmt, ap);
- if (len == -1) {
- return -1;
- }
- size_t size = (size_t)len + 1;
- char *str = (char*)malloc(size);
- if (!str) {
- return -1;
- }
- // _vsprintf_s is the "secure" version of vsprintf
- s32 r = vsprintf_s(str, len + 1, fmt, ap);
- if (r == -1) {
- free(str);
- return -1;
- }
- *strp = str;
- return r;
- }
-
- s32 asprintf(char **strp, const char *fmt, ...) {
- va_list ap;
- va_start(ap, fmt);
- s32 r = vasprintf(strp, fmt, ap);
- va_end(ap);
- return r;
- }
- #endif
-
- proc get_exe_dir() -> path_char* {
- #ifdef _MSC_VER
- DWORD last_error;
- DWORD result;
- DWORD path_size = MAX_PATH;
- path_char* path = (path_char*)malloc(sizeof(path_char)*path_size);
-
- while (true) {
- memset(path, 0, path_size);
- result = GetModuleFileName(0, path, path_size - 1);
- last_error = GetLastError();
-
- if (0 == result) {
- free(path);
- path = 0;
- break;
- }
- else if (result == path_size - 1) {
- free(path);
- /* May need to also check for ERROR_SUCCESS here if XP/2K */
- if (ERROR_INSUFFICIENT_BUFFER != last_error) {
- path = 0;
- break;
- }
- path_size = path_size * 2;
- path = (path_char*)malloc((sizeof(path_char)) * path_size);
- }
- else
- break;
- }
-
- if (!path) {
- fprintf(stderr, "Failure: %ld\n", last_error);
- return nullptr;
- }
- else {
- // remove the exe name, so we are only left with the path
-
- s32 index_in_path = -1;
- s32 last_backslash = -1;
-
- path_char c;
- while ((c = path[++index_in_path]) != '\0') {
- if (c == '\\')
- last_backslash = index_in_path;
- }
-
- // we are assuming there are some backslashes
- path[last_backslash+1] = '\0';
-
- return path;
- }
- #else
- ssize_t size = 512, i, n;
- char *path, *temp;
-
- while (1) {
- size_t used;
-
- path = (char*)malloc(size);
- if (!path) {
- errno = ENOMEM;
- return NULL;
- }
-
- used = readlink("/proc/self/exe", path, size);
-
- if (used == -1) {
- const s32 saved_errno = errno;
- free(path);
- errno = saved_errno;
- return NULL;
- } else
- if (used < 1) {
- free(path);
- errno = EIO;
- return NULL;
- }
-
- if ((size_t)used >= size) {
- free(path);
- size = (size | 2047) + 2049;
- continue;
- }
-
- size = (size_t)used;
- break;
- }
-
- /* Find final slash. */
- n = 0;
- for (i = 0; i < size; i++)
- if (path[i] == '/')
- n = i;
-
- /* Optimize allocated size,
- ensuring there is room for
- a final slash and a
- string-terminating '\0', */
- temp = path;
- path = (char*)realloc(temp, n + 2);
- if (!path) {
- free(temp);
- errno = ENOMEM;
- return NULL;
- }
-
- /* and properly trim and terminate the path string. */
- path[n+0] = '/';
- path[n+1] = '\0';
-
- return path;
- #endif
- }
- }
|