int path_getabsolute(lua_State* L) { const char* relative_to; char buffer[0x4000]; relative_to = NULL; if (lua_gettop(L) > 1 && !lua_isnil(L,2)) { relative_to = luaL_checkstring(L, 2); } if (lua_istable(L, 1)) { int i = 0; lua_newtable(L); lua_pushnil(L); while (lua_next(L, 1)) { const char* value = luaL_checkstring(L, -1); do_getabsolute(buffer, value, relative_to); lua_pop(L, 1); lua_pushstring(L, buffer); lua_rawseti(L, -3, ++i); } return 1; } else { const char* value = luaL_checkstring(L, 1); do_getabsolute(buffer, value, relative_to); lua_pushstring(L, buffer); return 1; } }
static const char* set_scripts_path(const char* relativePath) { char* path = (char*)malloc(PATH_MAX); do_getabsolute(path, relativePath, NULL); scripts_path = path; return scripts_path; }
int path_getrelative(lua_State* L) { int i, last, count; char src[0x4000]; char dst[0x4000]; const char* p1 = luaL_checkstring(L, 1); const char* p2 = luaL_checkstring(L, 2); /* normalize the paths */ do_getabsolute(src, p1, NULL); do_getabsolute(dst, p2, NULL); /* same directory? */ if (strcmp(src, dst) == 0) { lua_pushstring(L, "."); return 1; } /* dollar macro? Can't tell what the real path might be, so treat * as absolute. This enables paths like $(SDK_ROOT)/include to * work as expected. */ if (dst[0] == '$') { lua_pushstring(L, dst); return 1; } /* find the common leading directories */ strcat(src, "/"); strcat(dst, "/"); last = -1; i = 0; while (src[i] && dst[i] && src[i] == dst[i]) { if (src[i] == '/') { last = i; } ++i; } /* if I end up with just the root of the filesystem, either a single * slash (/) or a drive letter (c:) then return the absolute path. */ if (last <= 0 || (last == 2 && src[1] == ':')) { dst[strlen(dst) - 1] = '\0'; lua_pushstring(L, dst); return 1; } /* count remaining levels in src */ count = 0; for (i = last + 1; src[i] != '\0'; ++i) { if (src[i] == '/') { ++count; } } /* start my result by backing out that many levels */ src[0] = '\0'; for (i = 0; i < count; ++i) { strcat(src, "../"); } /* append what's left */ strcat(src, dst + last + 1); /* remove trailing slash and done */ src[strlen(src) - 1] = '\0'; lua_pushstring(L, src); return 1; }