Improve path.getabsolute
- Allow optional second "relative to" argument to use as base for conversion - Fix handling of paths like: $ORIGIN/../lib
This commit is contained in:
parent
d7ff3629ed
commit
1e24b4790b
31
src/host/path_getabsolute.c
Normal file → Executable file
31
src/host/path_getabsolute.c
Normal file → Executable file
@ -8,15 +8,21 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
static void getabsolute(char* result, const char* value)
|
static void getabsolute(char* result, const char* value, const char* relative_to)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char* ch;
|
char* ch;
|
||||||
|
char* prev;
|
||||||
char buffer[0x4000] = { '\0' };
|
char buffer[0x4000] = { '\0' };
|
||||||
|
|
||||||
/* if the path is not already absolute, base it on working dir */
|
/* if the path is not already absolute, base it on working dir */
|
||||||
if (!do_isabsolute(value)) {
|
if (!do_isabsolute(value)) {
|
||||||
do_getcwd(buffer, 0x4000);
|
if (relative_to) {
|
||||||
|
strcpy(buffer, relative_to);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
do_getcwd(buffer, 0x4000);
|
||||||
|
}
|
||||||
strcat(buffer, "/");
|
strcat(buffer, "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,10 +36,11 @@ static void getabsolute(char* result, const char* value)
|
|||||||
strcat(result, "/");
|
strcat(result, "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prev = NULL;
|
||||||
ch = strtok(buffer, "/");
|
ch = strtok(buffer, "/");
|
||||||
while (ch) {
|
while (ch) {
|
||||||
/* remove ".." */
|
/* remove ".." where I can */
|
||||||
if (strcmp(ch, "..") == 0) {
|
if (strcmp(ch, "..") == 0 && (prev == NULL || (prev[0] != '$' && strcmp(prev, "..") != 0))) {
|
||||||
i = strlen(result) - 2;
|
i = strlen(result) - 2;
|
||||||
while (i >= 0 && result[i] != '/') {
|
while (i >= 0 && result[i] != '/') {
|
||||||
--i;
|
--i;
|
||||||
@ -41,6 +48,7 @@ static void getabsolute(char* result, const char* value)
|
|||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
result[i + 1] = '\0';
|
result[i + 1] = '\0';
|
||||||
}
|
}
|
||||||
|
ch = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allow everything except "." */
|
/* allow everything except "." */
|
||||||
@ -49,6 +57,7 @@ static void getabsolute(char* result, const char* value)
|
|||||||
strcat(result, "/");
|
strcat(result, "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prev = ch;
|
||||||
ch = strtok(NULL, "/");
|
ch = strtok(NULL, "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,26 +71,32 @@ static void getabsolute(char* result, const char* value)
|
|||||||
|
|
||||||
int path_getabsolute(lua_State* L)
|
int path_getabsolute(lua_State* L)
|
||||||
{
|
{
|
||||||
|
const char* relative_to;
|
||||||
char buffer[0x4000];
|
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)) {
|
if (lua_istable(L, 1)) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
while (lua_next(L, 1)) {
|
while (lua_next(L, 1)) {
|
||||||
const char* value = luaL_checkstring(L, 4);
|
const char* value = luaL_checkstring(L, -1);
|
||||||
getabsolute(buffer, value);
|
getabsolute(buffer, value, relative_to);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
lua_pushnumber(L, ++i);
|
lua_pushnumber(L, ++i);
|
||||||
lua_pushstring(L, buffer);
|
lua_pushstring(L, buffer);
|
||||||
lua_settable(L, 2);
|
lua_settable(L, -4);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const char* value = luaL_checkstring(L, 1);
|
const char* value = luaL_checkstring(L, 1);
|
||||||
getabsolute(buffer, value);
|
getabsolute(buffer, value, relative_to);
|
||||||
lua_pushstring(L, buffer);
|
lua_pushstring(L, buffer);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
25
tests/base/test_path.lua
Normal file → Executable file
25
tests/base/test_path.lua
Normal file → Executable file
@ -64,6 +64,31 @@
|
|||||||
test.isequal({ "/a/b", "/c/d" }, path.getabsolute({ "/a/b", "/c/d" }))
|
test.isequal({ "/a/b", "/c/d" }, path.getabsolute({ "/a/b", "/c/d" }))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function suite.getabsolute_withRelativeTo()
|
||||||
|
local relto = path.getdirectory(os.getcwd())
|
||||||
|
local expected = relto .. "/a/b/c"
|
||||||
|
test.isequal(expected, path.getabsolute("a/b/c", relto))
|
||||||
|
end
|
||||||
|
|
||||||
|
function suite.getabsolute_withRelativeTo_withTrailingSlashes()
|
||||||
|
local relto = path.getdirectory(os.getcwd())
|
||||||
|
local expected = relto .. "/a/b/c"
|
||||||
|
test.isequal(expected, path.getabsolute("a/b/c", relto .. "/"))
|
||||||
|
end
|
||||||
|
|
||||||
|
function suite.getabsolute_acceptsTables_withRelativeTo()
|
||||||
|
local relto = path.getdirectory(os.getcwd())
|
||||||
|
test.isequal({ relto .. "/a/b", relto .. "/c/d" }, path.getabsolute({ "a/b", "c/d" }, relto))
|
||||||
|
end
|
||||||
|
|
||||||
|
function suite.getabsolute_leavesDotDot_onShellVar()
|
||||||
|
test.isequal("$ORIGIN/../libs", path.getabsolute("$ORIGIN/../libs"))
|
||||||
|
end
|
||||||
|
|
||||||
|
function suite.getabsolute_leavesDotDot2_onShellVar()
|
||||||
|
test.isequal("$ORIGIN/../../libs", path.getabsolute("$ORIGIN/../../libs"))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- path.getbasename() tests
|
-- path.getbasename() tests
|
||||||
|
Loading…
Reference in New Issue
Block a user