aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh7
-rw-r--r--lpm.c96
-rw-r--r--lpm.lua154
3 files changed, 68 insertions, 189 deletions
diff --git a/build.sh b/build.sh
index 0ebd9cc..e2171fe 100755
--- a/build.sh
+++ b/build.sh
@@ -12,6 +12,7 @@ LDFLAGS="$LDFLAGS -lm -pthread -static-libgcc"
[[ $OSTYPE == 'msys'* || $CC == *'mingw'* ]] && SSL_CONFIGURE="mingw64"
# Build supporting libraries, libgit2, libz, libssl (with libcrypto), libpcre
+[[ "$@" != *"-lz"* ]] && CFLAGS="$CFLAGS -Ilib/zlib" && SRCS="$SRCS lib/zlib/*.c"
if [[ "$@" != *"-lz"* ]]; then
[ ! -e "lib/zlib" ] && echo "Make sure you've cloned submodules. (git submodule update --init --depth=1)" && exit -1
[ ! -e "lib/zlib/build" ] && cd lib/zlib && mkdir build && cd build && ../configure --prefix=`pwd`/../../prefix && $MAKE -j $JOBS && $MAKE install && cd ../../../
@@ -22,11 +23,11 @@ if [[ "$@" != *"-lssl"* && "$@" != *"-lcrypto"* ]]; then
LDFLAGS="$LDFLAGS -Llib/libz/build" && CFLAGS="$CFLAGS -Ilib/prefix/include" && LDFLAGS="$LDFLAGS -Llib/prefix/lib -Llib/prefix/lib64 -l:libssl.a -l:libcrypto.a"
fi
if [[ "$@" != *"-lgit2"* ]]; then
- [ ! -e "lib/libgit2/build" ] && cd lib/libgit2 && mkdir build && cd build && cmake .. $GIT2_CONFIGURE -DCMAKE_PREFIX_PATH=`pwd`/../../prefix -DCMAKE_INSTALL_PREFIX=`pwd`/../../prefix -DOPENSSL_ROOT_DIR=`pwd`/../../prefix -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_CLI=OFF -DREGEX_BACKEND=builtin -DUSE_SSH=OFF && $MAKE -j $JOBS && $MAKE install && cd ../../../
+ [ ! -e "lib/libgit2/build" ] && cd lib/libgit2 && mkdir build && cd build && cmake .. -G="Unix Makefiles" $GIT2_CONFIGURE -DCMAKE_PREFIX_PATH=`pwd`/../../prefix -DCMAKE_INSTALL_PREFIX=`pwd`/../../prefix -DOPENSSL_ROOT_DIR=`pwd`/../../prefix -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_CLI=OFF -DREGEX_BACKEND=builtin -DUSE_SSH=OFF && $MAKE -j $JOBS && $MAKE install && cd ../../../
LDFLAGS="-Llib/libgit2/build -l:libgit2.a $LDFLAGS -Llib/prefix/lib -Llib/prefix/lib64" && CFLAGS="$CFLAGS -Ilib/prefix/include"
fi
if [[ "$@" != *"-lcurl"* ]]; then
- [ ! -e "lib/curl/build" ] && cd lib/curl && mkdir build && cd build && cmake .. $CURL_CONFIGURE -DCURL_USE_LIBPSL=OFF -DCURL_DISABLE_LDAPS=ON -DUSE_OPENSSL=ON -DCURL_DISABLE_LDAP=ON -DCMAKE_INSTALL_PREFIX=`pwd`/../../prefix -DUSE_LIBIDN2=OFF -DENABLE_UNICODE=OFF -DBUILD_CURL_EXE=OFF -DCURL_USE_LIBSSH2=OFF -DOPENSSL_ROOT_DIR=`pwd`/../../prefix -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_LIBDIR=lib && $MAKE -j $JOBS && $MAKE install && cd ../../../
+ [ ! -e "lib/curl/build" ] && cd lib/curl && mkdir build && cd build && cmake .. -G="Unix Makefiles" $CURL_CONFIGURE -DCURL_USE_LIBPSL=OFF -DCURL_DISABLE_LDAPS=ON -DUSE_OPENSSL=ON -DCURL_DISABLE_LDAP=ON -DCMAKE_INSTALL_PREFIX=`pwd`/../../prefix -DUSE_LIBIDN2=OFF -DENABLE_UNICODE=OFF -DBUILD_CURL_EXE=OFF -DCURL_USE_LIBSSH2=OFF -DOPENSSL_ROOT_DIR=`pwd`/../../prefix -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_LIBDIR=lib && $MAKE -j $JOBS && $MAKE install && cd ../../../
LDFLAGS="-Llib/curl/build -Llib/prefix/lib -l:libcurl.a $LDFLAGS" && CFLAGS="$CFLAGS -Ilib/prefix/include -DCURL_STATICLIB"
fi
[[ "$@" != *"-llua"* ]] && CFLAGS="$CFLAGS -Ilib/lua -DMAKE_LIB=1" && SRCS="$SRCS lib/lua/onelua.c"
@@ -35,7 +36,7 @@ fi
xxd -i lpm.lua > lpm.lua.c
[[ $OSTYPE != 'msys'* && $CC != *'mingw'* && $CC != "emcc" ]] && LDFLAGS=" $LDFLAGS -ldl -pthread"
-[[ $OSTYPE == 'msys'* || $CC == *'mingw'* ]] && LDFLAGS="$LDFLAGS -lws2_32 -lz -lwinhttp -lole32 -lcrypt32 -lrpcrt4"
+[[ $OSTYPE == 'msys'* || $CC == *'mingw'* ]] && LDFLAGS="$LDFLAGS -lbcrypt -lws2_32 -lz -lwinhttp -lole32 -lcrypt32 -lrpcrt4"
[[ " $@" != *" -g"* && " $@" != *" -O"* ]] && CFLAGS="$CFLAGS -O3" && LDFLAGS="$LDFLAGS -s"
$CC $CFLAGS $SRCS $@ -o $BIN $LDFLAGS
diff --git a/lpm.c b/lpm.c
index d8e0376..8e01957 100644
--- a/lpm.c
+++ b/lpm.c
@@ -76,9 +76,7 @@ int lpm_chmod(lua_State* L) {
}
/** BEGIN STOLEN LITE CODE **/
-
#if _WIN32
-#define UTFCONV_ERROR_INVALID_CONVERSION "Input contains invalid byte sequences."
static LPWSTR utfconv_utf8towc(const char *str) {
LPWSTR output;
int len;
@@ -131,30 +129,19 @@ static int lpm_ls(lua_State *L) {
#ifdef _WIN32
lua_settop(L, 1);
- if (path[0] == 0 || strchr("\\/", path[strlen(path) - 1]) != NULL)
- lua_pushstring(L, "*");
- else
- lua_pushstring(L, "/*");
-
+ lua_pushstring(L, path[0] == 0 || strchr("\\/", path[strlen(path) - 1]) != NULL ? "*" : "/*");
lua_concat(L, 2);
path = lua_tostring(L, -1);
LPWSTR wpath = utfconv_utf8towc(path);
- if (wpath == NULL) {
- lua_pushnil(L);
- lua_pushstring(L, UTFCONV_ERROR_INVALID_CONVERSION);
- return 2;
- }
-
+ if (wpath == NULL)
+ return luaL_error(L, "can't ls %s: invalid utf8 character conversion", path);
+
WIN32_FIND_DATAW fd;
HANDLE find_handle = FindFirstFileExW(wpath, FindExInfoBasic, &fd, FindExSearchNameMatch, NULL, 0);
free(wpath);
- if (find_handle == INVALID_HANDLE_VALUE) {
- lua_pushnil(L);
- lua_pushinteger(L, GetLastError());
- return 2;
- }
-
+ if (find_handle == INVALID_HANDLE_VALUE)
+ return luaL_error(L, "can't ls %s: %d", path, GetLastError());
char mbpath[MAX_PATH * 4]; // utf-8 spans 4 bytes at most
int len, i = 1;
lua_newtable(L);
@@ -170,23 +157,15 @@ static int lpm_ls(lua_State *L) {
lua_rawseti(L, -2, i++);
} while (FindNextFileW(find_handle, &fd));
- if (GetLastError() != ERROR_NO_MORE_FILES) {
- lua_pushnil(L);
- lua_pushinteger(L, GetLastError());
- FindClose(find_handle);
- return 2;
- }
-
+ int err = GetLastError();
FindClose(find_handle);
+ if (err != ERROR_NO_MORE_FILES)
+ return luaL_error(L, "can't ls %s: %d", path, GetLastError());
return 1;
#else
DIR *dir = opendir(path);
- if (!dir) {
- lua_pushnil(L);
- lua_pushstring(L, strerror(errno));
- return 2;
- }
-
+ if (!dir)
+ return luaL_error(L, "can't ls %s: %d", path, strerror(errno));
lua_newtable(L);
int i = 1;
struct dirent *entry;
@@ -197,7 +176,6 @@ static int lpm_ls(lua_State *L) {
lua_rawseti(L, -2, i);
i++;
}
-
closedir(dir);
return 1;
#endif
@@ -210,52 +188,29 @@ static int lpm_rmdir(lua_State *L) {
LPWSTR wpath = utfconv_utf8towc(path);
int deleted = RemoveDirectoryW(wpath);
free(wpath);
- if (deleted > 0) {
- lua_pushboolean(L, 1);
- } else {
- lua_pushboolean(L, 0);
- lua_pushinteger(L, GetLastError());
- return 2;
- }
+ if (!deleted) {
+ return luaL_error(L, "can't rmdir %s: %d", path, GetLastError());
#else
- int deleted = remove(path);
- if(deleted < 0) {
- lua_pushboolean(L, 0);
- lua_pushstring(L, strerror(errno));
-
- return 2;
- } else {
- lua_pushboolean(L, 1);
- }
+ if (remove(path))
+ return luaL_error(L, "can't rmdir %s: %s", path, strerror(errno));
#endif
-
- return 1;
+ return 0;
}
static int lpm_mkdir(lua_State *L) {
const char *path = luaL_checkstring(L, 1);
-
#ifdef _WIN32
LPWSTR wpath = utfconv_utf8towc(path);
- if (wpath == NULL) {
- lua_pushboolean(L, 0);
- lua_pushstring(L, UTFCONV_ERROR_INVALID_CONVERSION);
- return 2;
- }
-
+ if (wpath == NULL)
+ return luaL_error(L, "can't mkdir %s: invalid utf8 character conversion", path);
int err = _wmkdir(wpath);
free(wpath);
#else
int err = mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
#endif
- if (err < 0) {
- lua_pushboolean(L, 0);
- lua_pushstring(L, strerror(errno));
- return 2;
- }
-
- lua_pushboolean(L, 1);
- return 1;
+ if (err < 0)
+ return luaL_error(L, "can't mkdir %s: %s", path, strerror(errno));
+ return 0;
}
static int lpm_stat(lua_State *L) {
@@ -264,18 +219,15 @@ static int lpm_stat(lua_State *L) {
#ifdef _WIN32
struct _stat s;
LPWSTR wpath = utfconv_utf8towc(path);
- if (wpath == NULL) {
- lua_pushnil(L);
- lua_pushstring(L, UTFCONV_ERROR_INVALID_CONVERSION);
- return 2;
- }
+ if (wpath == NULL)
+ return luaL_error(L, "can't stat %s: invalid utf8 character conversion", path);
int err = _wstat(wpath, &s);
free(wpath);
#else
struct stat s;
int err = lstat(path, &s);
#endif
- if (err < 0) {
+ if (err) {
lua_pushnil(L);
lua_pushstring(L, strerror(errno));
return 2;
diff --git a/lpm.lua b/lpm.lua
index 734eb48..8d19391 100644
--- a/lpm.lua
+++ b/lpm.lua
@@ -353,10 +353,15 @@ function json.decode(str)
end
-- End JSON library.
+local HOME, USERDIR, CACHEDIR, JSON, VERBOSE, MOD_VERSION, QUIET, FORCE, AUTO_PULL_REMOTES, ARCH, ASSUME_YES, NO_INSTALL_OPTIONAL, TMPDIR, repositories, lite_xls, system_bottle
local common = {}
-
-
+function common.merge(dst, src) for k, v in pairs(src) do dst[k] = v end return dst end
+function common.map(l, p) local t = {} for i, v in ipairs(l) do table.insert(t, p(v)) end return t end
+function common.flat_map(l, p) local t = {} for i, v in ipairs(l) do local r = p(v) for k, w in ipairs(r) do table.insert(t, w) end end return t end
+function common.grep(l, p) local t = {} for i, v in ipairs(l) do if p(v) then table.insert(t, v) end end return t end
+function common.slice(t, i, l) local n = {} for j = i, l ~= nil and (i - l) or #t do table.insert(n, t[j]) end return n end
+function common.join(j, l) local s = "" for i, v in ipairs(l) do if i > 1 then s = s .. j .. v else s = v end end return s end
function common.split(splitter, str)
local o = 1
local res = {}
@@ -369,94 +374,26 @@ function common.split(splitter, str)
return table.unpack(res)
end
-function common.dirname(path)
- local s = path:reverse():find(PATHSEP)
- if not s then return path end
- return path:sub(1, #path - s)
-end
-
+function common.dirname(path) local s = path:reverse():find("[/\\]") if not s then return path end return path:sub(1, #path - s) end
+function common.basename(path) local s = path:reverse():find("[/\\]") if not s then return path end return path:sub(#path - s + 2) end
+function common.path(exec) return common.grep(common.map({ common.split(":", os.getenv("PATH")) }, function(e) return e .. PATHSEP .. exec end), function(e) return system.stat(e) end)[1] end
function common.rmrf(root)
- if not root or root == "" then return end
- local info = system.stat(root)
+ local info = root and root ~= "" and system.stat(root)
if not info then return end
if info.type == "file" or info.symlink then return os.remove(root) end
for i,v in ipairs(system.ls(root)) do common.rmrf(root .. PATHSEP .. v) end
system.rmdir(root)
end
-
function common.mkdirp(path)
local stat = system.stat(path)
if stat and stat.type == "dir" then return true end
if stat and stat.type == "file" then error("path " .. path .. " exists") end
- system.mkdir(path)
- local subdirs = {}
- while path and path ~= "" do
- local updir, basedir = path:match("(.*)[/\\](.+)$")
- table.insert(subdirs, 1, basedir or path)
- path = updir
- end
- for _, dirname in ipairs(subdirs) do
- path = path and path .. PATHSEP .. dirname or dirname
- system.mkdir(path)
+ local target
+ for _, dirname in ipairs({ common.split("[/\\]", path) }) do
+ target = target and target .. PATHSEP .. dirname or dirname
+ if target ~= "" and not system.stat(target) then system.mkdir(target) end
end
end
-
-
-function common.basename(path)
- local s = path:reverse():find("[/\\]")
- if not s then return path end
- return path:sub(#path - s + 2)
-end
-
-
-
-function common.merge(src, merge)
- for k, v in pairs(merge) do src[k] = v end
- return src
-end
-
-
-function common.map(list, predicate)
- local t = {}
- for i, v in ipairs(list) do table.insert(t, predicate(v)) end
- return t
-end
-
-
-function common.grep(list, predicate)
- local t = {}
- for i, v in ipairs(list) do if predicate(v) then table.insert(t, v) end end
- return t
-end
-
-
-function common.join(joiner, list)
- local s = ""
- for i, v in ipairs(list) do if i > 1 then s = s .. joiner .. v else s = v end end
- return s
-end
-
-function common.split(splitter, str)
- local o = 1
- local res = {}
- while true do
- local s, e = str:find(splitter, o)
- table.insert(res, str:sub(o, s and (s - 1) or #str))
- if not s then break end
- o = e + 1
- end
- return table.unpack(res)
-end
-
-
-function common.slice(t, i, l)
- local n = {}
- for j = i, l ~= nil and (i - l) or #t do
- table.insert(n, t[j])
- end
- return n
-end
-
function common.copy(src, dst)
local src_stat, dst_stat = system.stat(src), system.stat(dst)
if not src_stat then error("can't find " .. src) end
@@ -468,28 +405,30 @@ function common.copy(src, dst)
local src_io, err1 = io.open(src, "rb")
if err1 then error("can't open for reading " .. src .. ": " .. err1) end
local dst_io, err2 = io.open(dst, "wb")
- if err2 then error("can't open for writing " .. src .. ": " .. err2) end
+ if err2 then error("can't open for writing " .. dst .. ": " .. err2) end
while true do
local chunk = src_io:read(16*1024)
if not chunk then break end
dst_io:write(chunk)
end
- dst_io:flush()
+ dst_io:close()
end
end
-
-local function get_executable(name)
- return common.grep(common.map({ common.split(":", os.getenv("PATH")) }, function(e) return e .. PATHSEP .. name end), function(e) return system.stat(e) end)[1]
+function common.rename(src, dst)
+ local _, err = os.rename(src, dst)
+ if err then error("can't rename file " .. src .. " to " .. dst .. ": " .. err) end
end
-
-
-local function is_commit_hash(hash)
- return #hash == 40 and not hash:find("[^a-z0-9]")
+function common.get(source, target, checksum)
+ if not checksum then return system.get(source, target) end
+ if not system.stat(CACHEDIR .. PATHSEP .. "files") then common.mkdirp(CACHEDIR .. PATHSEP .. "files") end
+ local cache_path = CACHEDIR .. PATHSEP .. "files" .. PATHSEP .. checksum
+ if not system.stat(cache_path) then
+ system.get(source, cache_path)
+ if system.hash(cache_path, "file") ~= checksum then fatal_warning("checksum doesn't match for " .. source) end
+ end
+ common.copy(cache_path, target)
end
-
-local HOME, USERDIR, CACHEDIR, JSON, VERBOSE, MOD_VERSION, QUIET, FORCE, AUTO_PULL_REMOTES, ARCH, ASSUME_YES, NO_INSTALL_OPTIONAL, TMPDIR, repositories, lite_xls, system_bottle
-
local actions, warnings = {}, {}
local function log_action(message)
if JSON then table.insert(actions, message) end
@@ -534,25 +473,13 @@ local function match_version(version, pattern)
end
-local function get_all_plugins()
- local t = {}
- for i,r in ipairs(repositories) do
- for j,p in ipairs(r.plugins) do
- table.insert(t, p)
- end
- end
- return t
+local function is_commit_hash(hash)
+ return #hash == 40 and not hash:find("[^a-z0-9]")
end
-function common.get(source, target, checksum)
- if not checksum then return system.get(source, target) end
- if not system.stat(CACHEDIR .. PATHSEP .. "files") then common.mkdirp(CACHEDIR .. PATHSEP .. "files") end
- local cache_path = CACHEDIR .. PATHSEP .. "files" .. PATHSEP .. checksum
- if not system.stat(cache_path) then
- system.get(source, cache_path)
- if system.hash(cache_path, "file") ~= checksum then fatal_warning("checksum doesn't match for " .. source) end
- end
- common.copy(cache_path, target)
+
+local function get_all_plugins()
+ return common.flat_map(repositories, function(r) return r.plugins end)
end
local Plugin = {}
@@ -665,7 +592,7 @@ local core_plugins = {
function Plugin:install(bottle, installing)
if self:is_installed(bottle) then error("plugin " .. self.name .. " is already installed") end
local install_path = self:get_install_path(bottle)
- local temporary_install_path = TMPDIR .. PATHSEP .. install_path:sub(#CACHEDIR)
+ local temporary_install_path = TMPDIR .. PATHSEP .. install_path:sub(#USERDIR + 2)
local status, err = pcall(function()
installing = installing or {}
installing[self.name] = true
@@ -733,8 +660,7 @@ function Plugin:install(bottle, installing)
else
common.rmrf(install_path)
common.mkdirp(common.dirname(install_path))
- local _, err = os.rename(temporary_install_path, install_path)
- if err then error("can't rename file " .. install_path .. ": " .. err) end
+ common.rename(temporary_install_path, install_path)
end
end
@@ -901,7 +827,7 @@ function Repository:add()
system.fetch(path)
if not pcall(system.reset, path, "refs/remotes/origin/master", "hard") then
if pcall(system.reset, path, "refs/remotes/origin/main", "hard") then
- os.rename(path, self.local_path .. PATHSEP .. "main")
+ common.rename(path, self.local_path .. PATHSEP .. "main")
self.branch = "main"
else
error("can't find master or main.")
@@ -996,7 +922,7 @@ function LiteXL:install()
if self:is_installed() then error("lite-xl " .. self.version .. " already installed") end
common.mkdirp(self.local_path)
if system_bottle.lite_xl == self then -- system lite-xl. We have to copy it because we can't really set the user directory.
- local executable, datadir = get_executable("lite-xl")
+ local executable, datadir = common.path("lite-xl")
if not executable then error("can't find system lite-xl executable") end
local stat = system.stat(executable)
executable = stat.symlink and stat.symlink or executable
@@ -1174,7 +1100,7 @@ end
local function lpm_lite_xl_switch(version, target)
if not version then error("requires a version") end
- target = target or get_executable("lite-xl")
+ target = target or common.path("lite-xl")
if not target then error("can't find installed lite-xl. please provide a target to install the symlink explicitly") end
local lite_xl = get_lite_xl(version) or error("can't find lite-xl version " .. version)
system.symlink(lite_xl.local_path .. PATHSEP .. "lite-xl", target)
@@ -1577,7 +1503,7 @@ Flags have the following effects:
end
if not MOD_VERSION then
- local lite_xl_binary = get_executable("lite-xl")
+ local lite_xl_binary = common.path("lite-xl")
if lite_xl_binary then
local hash = system.hash(lite_xl_binary, "file")
for i,repo in ipairs(repositories) do