Port path.getabsolute() from Lua to C
This commit is contained in:
parent
b25c12f2b6
commit
c94073fc7e
@ -32,51 +32,6 @@
|
||||
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.
|
||||
--
|
||||
|
@ -9,26 +9,32 @@
|
||||
int os_getcwd(lua_State* L)
|
||||
{
|
||||
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;
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
result = (GetCurrentDirectory(0x4000, buffer) != 0);
|
||||
if (result) {
|
||||
char* ch;
|
||||
for (ch = buffer; *ch != '\0'; ++ch)
|
||||
{
|
||||
if (*ch == '\\') *ch = '/';
|
||||
}
|
||||
}
|
||||
#else
|
||||
result = (getcwd(buffer, 0x4000) != 0);
|
||||
#endif
|
||||
|
||||
if (!result)
|
||||
return 0;
|
||||
|
||||
/* convert to platform-neutral directory separators */
|
||||
for (ch = buffer; *ch != '\0'; ++ch)
|
||||
{
|
||||
if (*ch == '\\') *ch = '/';
|
||||
}
|
||||
|
||||
lua_pushstring(L, buffer);
|
||||
return 1;
|
||||
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 */
|
||||
static const luaL_Reg path_functions[] = {
|
||||
{ "getabsolute", path_getabsolute },
|
||||
{ "isabsolute", path_isabsolute },
|
||||
{ "join", path_join },
|
||||
{ NULL, NULL }
|
||||
|
@ -48,11 +48,13 @@
|
||||
|
||||
/* Bootstrapping helper functions */
|
||||
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_isfile(const char* filename);
|
||||
|
||||
|
||||
/* Built-in functions */
|
||||
int path_getabsolute(lua_State* L);
|
||||
int path_isabsolute(lua_State* L);
|
||||
int path_join(lua_State* L);
|
||||
int os_chdir(lua_State* L);
|
||||
|
@ -1,7 +1,7 @@
|
||||
--
|
||||
-- tests/base/test_path.lua
|
||||
-- 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")
|
||||
@ -11,41 +11,59 @@
|
||||
-- path.getabsolute() tests
|
||||
--
|
||||
|
||||
function suite.getabsolute_ReturnsCorrectPath_OnMissingSubdir()
|
||||
local expected = path.translate(os.getcwd(), "/") .. "/a/b/c"
|
||||
function suite.getabsolute_worksWithMissingSubdirs()
|
||||
local expected = os.getcwd() .. "/a/b/c"
|
||||
test.isequal(expected, path.getabsolute("a/b/c"))
|
||||
end
|
||||
|
||||
function suite.getabsolute_RemovesDotDots_OnWindowsAbsolute()
|
||||
function suite.getabsolute_removesDotDots_onWindows()
|
||||
test.isequal("c:/ProjectB/bin", path.getabsolute("c:/ProjectA/../ProjectB/bin"))
|
||||
end
|
||||
|
||||
function suite.getabsolute_RemovesDotDots_OnPosixAbsolute()
|
||||
function suite.getabsolute_removesDotDots_OnPosix()
|
||||
test.isequal("/ProjectB/bin", path.getabsolute("/ProjectA/../ProjectB/bin"))
|
||||
end
|
||||
|
||||
function suite.getabsolute_OnTrailingSlash()
|
||||
local expected = path.translate(os.getcwd(), "/") .. "/a/b/c"
|
||||
test.isequal(expected, path.getabsolute("a/b/c/"))
|
||||
function suite.getabsolute_limitsDotDots_onWindows()
|
||||
test.isequal("c:/ProjectB/bin", path.getabsolute("c:/ProjectA/../../ProjectB/bin"))
|
||||
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"))
|
||||
end
|
||||
|
||||
function suite.getabsolute_OnMultipleEnvVar()
|
||||
function suite.getabsolute_onMultipleEnvVar()
|
||||
test.isequal("$(HOME)/$(USER)", path.getabsolute("$(HOME)/$(USER)"))
|
||||
end
|
||||
|
||||
function suite.getabsolute_OnTrailingEnvVar()
|
||||
local expected = path.translate(os.getcwd(), "/") .. "/home/$(USER)"
|
||||
test.isequal(expected, path.getabsolute("home/$(USER)"))
|
||||
function suite.getabsolute_onTrailingEnvVar()
|
||||
test.isequal("/home/$(USER)", path.getabsolute("/home/$(USER)"))
|
||||
end
|
||||
|
||||
function suite.getabsolute_OnLeadingEnvVarQuoted()
|
||||
function suite.getabsolute_onLeadingEnvVarQuoted()
|
||||
test.isequal('"$(HOME)/user"', path.getabsolute('"$(HOME)/user"'))
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user