Port path.getabsolute() from Lua to C
This commit is contained in:
parent
b25c12f2b6
commit
c94073fc7e
@ -32,51 +32,6 @@
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Get the absolute file path from a relative path. The requested
|
|
||||||
-- file path doesn't actually need to exist.
|
|
||||||
--
|
|
||||||
|
|
||||||
function path.getabsolute(p)
|
|
||||||
if type(p) == "table" then
|
|
||||||
local result = {}
|
|
||||||
for _, value in ipairs(p) do
|
|
||||||
table.insert(result, path.getabsolute(value))
|
|
||||||
end
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
|
|
||||||
-- normalize the target path
|
|
||||||
p = path.translate(p, "/")
|
|
||||||
if (p == "") then p = "." end
|
|
||||||
|
|
||||||
-- if the directory is already absolute I don't need to do anything
|
|
||||||
local result = iif (path.isabsolute(p), nil, os.getcwd())
|
|
||||||
|
|
||||||
-- split up the supplied relative path and tackle it bit by bit
|
|
||||||
for n, part in ipairs(p:explode("/", true)) do
|
|
||||||
if (part == "" and n == 1) then
|
|
||||||
result = "/"
|
|
||||||
elseif (part == "..") then
|
|
||||||
result = path.getdirectory(result)
|
|
||||||
elseif (part ~= ".") then
|
|
||||||
-- Environment variables embedded in the path need to be treated
|
|
||||||
-- as relative paths; path.join() makes them absolute
|
|
||||||
if (part:startswith("$") and n > 1) then
|
|
||||||
result = result .. "/" .. part
|
|
||||||
else
|
|
||||||
result = path.join(result, part)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- if I end up with a trailing slash remove it
|
|
||||||
result = iif(result:endswith("/"), result:sub(1, -2), result)
|
|
||||||
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Retrieve the filename portion of a path, without any extension.
|
-- Retrieve the filename portion of a path, without any extension.
|
||||||
--
|
--
|
||||||
|
@ -9,26 +9,32 @@
|
|||||||
int os_getcwd(lua_State* L)
|
int os_getcwd(lua_State* L)
|
||||||
{
|
{
|
||||||
char buffer[0x4000];
|
char buffer[0x4000];
|
||||||
char* ch;
|
if (do_getcwd(buffer, 0x4000)) {
|
||||||
|
lua_pushstring(L, buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int do_getcwd(char* buffer, size_t size)
|
||||||
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS
|
||||||
result = (GetCurrentDirectory(0x4000, buffer) != 0);
|
result = (GetCurrentDirectory(0x4000, buffer) != 0);
|
||||||
#else
|
if (result) {
|
||||||
result = (getcwd(buffer, 0x4000) != 0);
|
char* ch;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* convert to platform-neutral directory separators */
|
|
||||||
for (ch = buffer; *ch != '\0'; ++ch)
|
for (ch = buffer; *ch != '\0'; ++ch)
|
||||||
{
|
{
|
||||||
if (*ch == '\\') *ch = '/';
|
if (*ch == '\\') *ch = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushstring(L, buffer);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
result = (getcwd(buffer, 0x4000) != 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
92
src/host/path_getabsolute.c
Normal file
92
src/host/path_getabsolute.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* \file path_getabsolute.c
|
||||||
|
* \brief Returns an absolute version of a relative path.
|
||||||
|
* \author Copyright (c) 2002-2013 Jason Perkins and the Premake project
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "premake.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
static void getabsolute(char* result, const char* value)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char* ch;
|
||||||
|
char buffer[0x4000] = { '\0' };
|
||||||
|
|
||||||
|
/* if the path is not already absolute, base it on working dir */
|
||||||
|
if (!do_isabsolute(value)) {
|
||||||
|
do_getcwd(buffer, 0x4000);
|
||||||
|
strcat(buffer, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* normalize the path */
|
||||||
|
strcat(buffer, value);
|
||||||
|
for (ch = buffer; *ch != '\0'; ++ch) {
|
||||||
|
if (*ch == '\\') {
|
||||||
|
*ch = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process it part by part */
|
||||||
|
result[0] = '\0';
|
||||||
|
if (buffer[0] == '/') {
|
||||||
|
strcat(result, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
ch = strtok(buffer, "/");
|
||||||
|
while (ch) {
|
||||||
|
/* remove ".." */
|
||||||
|
if (strcmp(ch, "..") == 0) {
|
||||||
|
i = strlen(result) - 2;
|
||||||
|
while (i >= 0 && result[i] != '/') {
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
if (i >= 0) {
|
||||||
|
result[i + 1] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allow everything except "." */
|
||||||
|
else if (strcmp(ch, ".") != 0) {
|
||||||
|
strcat(result, ch);
|
||||||
|
strcat(result, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
ch = strtok(NULL, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove trailing slash */
|
||||||
|
i = strlen(result) - 1;
|
||||||
|
if (result[i] == '/') {
|
||||||
|
result[i] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int path_getabsolute(lua_State* L)
|
||||||
|
{
|
||||||
|
char buffer[0x4000];
|
||||||
|
|
||||||
|
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, 4);
|
||||||
|
getabsolute(buffer, value);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_pushnumber(L, ++i);
|
||||||
|
lua_pushstring(L, buffer);
|
||||||
|
lua_settable(L, 2);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const char* value = luaL_checkstring(L, 1);
|
||||||
|
getabsolute(buffer, value);
|
||||||
|
lua_pushstring(L, buffer);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
@ -35,6 +35,7 @@ extern const char* builtin_scripts[];
|
|||||||
|
|
||||||
/* Built-in functions */
|
/* Built-in functions */
|
||||||
static const luaL_Reg path_functions[] = {
|
static const luaL_Reg path_functions[] = {
|
||||||
|
{ "getabsolute", path_getabsolute },
|
||||||
{ "isabsolute", path_isabsolute },
|
{ "isabsolute", path_isabsolute },
|
||||||
{ "join", path_join },
|
{ "join", path_join },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
|
@ -48,11 +48,13 @@
|
|||||||
|
|
||||||
/* Bootstrapping helper functions */
|
/* Bootstrapping helper functions */
|
||||||
unsigned long do_hash(const char* str, int seed);
|
unsigned long do_hash(const char* str, int seed);
|
||||||
|
int do_getcwd(char* buffer, size_t size);
|
||||||
int do_isabsolute(const char* path);
|
int do_isabsolute(const char* path);
|
||||||
int do_isfile(const char* filename);
|
int do_isfile(const char* filename);
|
||||||
|
|
||||||
|
|
||||||
/* Built-in functions */
|
/* Built-in functions */
|
||||||
|
int path_getabsolute(lua_State* L);
|
||||||
int path_isabsolute(lua_State* L);
|
int path_isabsolute(lua_State* L);
|
||||||
int path_join(lua_State* L);
|
int path_join(lua_State* L);
|
||||||
int os_chdir(lua_State* L);
|
int os_chdir(lua_State* L);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
--
|
--
|
||||||
-- tests/base/test_path.lua
|
-- tests/base/test_path.lua
|
||||||
-- Automated test suite for the action list.
|
-- Automated test suite for the action list.
|
||||||
-- Copyright (c) 2008-2010 Jason Perkins and the Premake project
|
-- Copyright (c) 2008-2013 Jason Perkins and the Premake project
|
||||||
--
|
--
|
||||||
|
|
||||||
local suite = test.declare("path")
|
local suite = test.declare("path")
|
||||||
@ -11,41 +11,59 @@
|
|||||||
-- path.getabsolute() tests
|
-- path.getabsolute() tests
|
||||||
--
|
--
|
||||||
|
|
||||||
function suite.getabsolute_ReturnsCorrectPath_OnMissingSubdir()
|
function suite.getabsolute_worksWithMissingSubdirs()
|
||||||
local expected = path.translate(os.getcwd(), "/") .. "/a/b/c"
|
local expected = os.getcwd() .. "/a/b/c"
|
||||||
test.isequal(expected, path.getabsolute("a/b/c"))
|
test.isequal(expected, path.getabsolute("a/b/c"))
|
||||||
end
|
end
|
||||||
|
|
||||||
function suite.getabsolute_RemovesDotDots_OnWindowsAbsolute()
|
function suite.getabsolute_removesDotDots_onWindows()
|
||||||
test.isequal("c:/ProjectB/bin", path.getabsolute("c:/ProjectA/../ProjectB/bin"))
|
test.isequal("c:/ProjectB/bin", path.getabsolute("c:/ProjectA/../ProjectB/bin"))
|
||||||
end
|
end
|
||||||
|
|
||||||
function suite.getabsolute_RemovesDotDots_OnPosixAbsolute()
|
function suite.getabsolute_removesDotDots_OnPosix()
|
||||||
test.isequal("/ProjectB/bin", path.getabsolute("/ProjectA/../ProjectB/bin"))
|
test.isequal("/ProjectB/bin", path.getabsolute("/ProjectA/../ProjectB/bin"))
|
||||||
end
|
end
|
||||||
|
|
||||||
function suite.getabsolute_OnTrailingSlash()
|
function suite.getabsolute_limitsDotDots_onWindows()
|
||||||
local expected = path.translate(os.getcwd(), "/") .. "/a/b/c"
|
test.isequal("c:/ProjectB/bin", path.getabsolute("c:/ProjectA/../../ProjectB/bin"))
|
||||||
test.isequal(expected, path.getabsolute("a/b/c/"))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function suite.getabsolute_OnLeadingEnvVar()
|
function suite.getabsolute_limitsDotDots_OnPosix()
|
||||||
|
test.isequal("/ProjectB/bin", path.getabsolute("/ProjectA/../../ProjectB/bin"))
|
||||||
|
end
|
||||||
|
|
||||||
|
function suite.getabsolute_removesDot()
|
||||||
|
test.isequal("/ProjectA/ProjectB/bin", path.getabsolute("/ProjectA/./ProjectB/bin"))
|
||||||
|
end
|
||||||
|
|
||||||
|
function suite.getabsolute_removesTrailingSlash()
|
||||||
|
test.isequal("/a/b/c", path.getabsolute("/a/b/c/"))
|
||||||
|
end
|
||||||
|
|
||||||
|
function suite.getabsolute_onLeadingEnvVar()
|
||||||
test.isequal("$(HOME)/user", path.getabsolute("$(HOME)/user"))
|
test.isequal("$(HOME)/user", path.getabsolute("$(HOME)/user"))
|
||||||
end
|
end
|
||||||
|
|
||||||
function suite.getabsolute_OnMultipleEnvVar()
|
function suite.getabsolute_onMultipleEnvVar()
|
||||||
test.isequal("$(HOME)/$(USER)", path.getabsolute("$(HOME)/$(USER)"))
|
test.isequal("$(HOME)/$(USER)", path.getabsolute("$(HOME)/$(USER)"))
|
||||||
end
|
end
|
||||||
|
|
||||||
function suite.getabsolute_OnTrailingEnvVar()
|
function suite.getabsolute_onTrailingEnvVar()
|
||||||
local expected = path.translate(os.getcwd(), "/") .. "/home/$(USER)"
|
test.isequal("/home/$(USER)", path.getabsolute("/home/$(USER)"))
|
||||||
test.isequal(expected, path.getabsolute("home/$(USER)"))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function suite.getabsolute_OnLeadingEnvVarQuoted()
|
function suite.getabsolute_onLeadingEnvVarQuoted()
|
||||||
test.isequal('"$(HOME)/user"', path.getabsolute('"$(HOME)/user"'))
|
test.isequal('"$(HOME)/user"', path.getabsolute('"$(HOME)/user"'))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function suite.getabsolute_normalizesPaths()
|
||||||
|
test.isequal("c:/ProjectB/bin", path.getabsolute("c:\\ProjectB\\bin"))
|
||||||
|
end
|
||||||
|
|
||||||
|
function suite.getabsolute_acceptsTables()
|
||||||
|
test.isequal({ "/a/b", "/c/d" }, path.getabsolute({ "/a/b", "/c/d" }))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- path.getbasename() tests
|
-- path.getbasename() tests
|
||||||
|
Loading…
Reference in New Issue
Block a user