From bcc2b133e88081692a5d2bd5be3727ddeec0e8bf Mon Sep 17 00:00:00 2001 From: Leon Bottou Date: Mon, 26 Aug 2013 10:35:10 -0400 Subject: added paths.findprogram and adjust gnuplot.lua --- dok/index.dok | 13 +++++++-- init.lua.in | 24 +++++++++++++++ paths.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 119 insertions(+), 11 deletions(-) diff --git a/dok/index.dok b/dok/index.dok index 0b7dbd6..6cde4e5 100644 --- a/dok/index.dok +++ b/dok/index.dok @@ -242,8 +242,8 @@ This directory is used to build variable ''package.cpath''. The home directory of the current user. -===== Operating system info ===== -{{anchor:paths.osinfo.dok}} +===== Miscellaneous ===== +{{anchor:paths.misc.dok}} ==== paths.uname() ==== @@ -264,4 +264,13 @@ Returns true if the operating system is Microsoft Windows. Returns true if the operating system is Mac OS X. +==== paths.getregistryvalue(key,subkey,value) ==== +Query a value in the Windows registry value. +Causes an error on other systems. + +==== paths.findprogram(progname) ==== + +Finds an executable program and returns its full path. +All the directories specified by the PATH variable are searched. +Under windows, this also searches the "App Path" registry entries. diff --git a/init.lua.in b/init.lua.in index 515437f..197ca42 100644 --- a/init.lua.in +++ b/init.lua.in @@ -116,4 +116,28 @@ function rmall(d, more) else return nil, "not a file or directory", d end +end + +function findprogram(exe) + if is_win() then + local k = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\' .. exe; + local x = getregistryvalue('HKEY_LOCAL_MACHINE', k, '') + if type(x) == 'string' then return x end + x = getregistryvalue('HKEY_LOCAL_MACHINE', k .. '.exe', '') + if type(x) == 'string' then return x end + local path = os.getenv("PATH") or "." + for dir in path:gmatch('[^;]+') do + x = concat(dir, exe) + if filep(x) then return x end + x = x .. '.exe' + if filep(x) then return x end + end + else + local path = os.getenv("PATH") or "." + for dir in path:gmatch('[^:]+') do + local x = concat(dir, exe) + if filep(x) then return x end + end + end + return nil end \ No newline at end of file diff --git a/paths.c b/paths.c index 6af5f47..2aa4cd6 100644 --- a/paths.c +++ b/paths.c @@ -129,9 +129,6 @@ filep(lua_State *L, int i) } -static int -concat_fname(lua_State *L, const char *fname); - static int dirp(lua_State *L, int i) { @@ -802,7 +799,8 @@ lua_rmdir(lua_State *L) /* uname */ -static int lua_uname(lua_State *L) +static int +lua_uname(lua_State *L) { #if defined(LUA_WIN) const char *name; @@ -839,7 +837,87 @@ static int lua_uname(lua_State *L) #endif } - +static int +lua_getregistryvalue(lua_State *L) +{ +#ifdef LUA_WIN + static char *keynames[] = { + "HKEY_CLASSES_ROOT", + "HKEY_CURRENT_CONFIG", + "HKEY_CURRENT_USER", + "HKEY_LOCAL_MACHINE", + "HKEY_USERS", + NULL }; + static HKEY keys[] = { + HKEY_CLASSES_ROOT, + HKEY_CURRENT_CONFIG, + HKEY_CURRENT_USER, + HKEY_LOCAL_MACHINE, + HKEY_USERS + }; + + HKEY rkey = keys[ luaL_checkoption(L, 1, NULL, keynames) ]; + const char *subkey = luaL_checkstring(L, 2); + const char *value = luaL_checkstring(L, 3); + HKEY skey; + DWORD type; + DWORD len = 0; + char *data = ""; + LONG res; + res = RegOpenKeyExA(rkey, subkey, 0, KEY_READ, &skey); + if (res != ERROR_SUCCESS) + { + lua_pushnil(L); + lua_pushinteger(L, res); + if (res == ERROR_FILE_NOT_FOUND) + lua_pushstring(L, "subkey not found"); + if (res == ERROR_ACCESS_DENIED) + lua_pushstring(L, "subkey access denied"); + else + return 2; + return 3; + } + res = RegQueryValueExA(skey, value, NULL, &type, (LPBYTE)data, &len); + if (res == ERROR_MORE_DATA) + { + len += 8; + if ((data = (char*)malloc(len))) + res = RegQueryValueExA(skey, value, NULL, &type, (LPBYTE)data, &len); + } + if (res != ERROR_SUCCESS) + { + RegCloseKey(skey); + lua_pushnil(L); + lua_pushinteger(L, res); + if (res == ERROR_FILE_NOT_FOUND) + lua_pushstring(L, "value not found"); + if (res == ERROR_ACCESS_DENIED) + lua_pushstring(L, "value access denied"); + else + return 2; + return 3; + } + switch(type) + { + case REG_SZ: + if (((const char*)data)[len-1] == 0) len -= 1; + case REG_BINARY: + lua_pushlstring(L, (const char*)data, (int)len); + return 1; + case REG_DWORD: + lua_pushinteger(L, (lua_Integer)*(const DWORD*)data); + return 1; + default: + lua_pushnil(L); + lua_pushinteger(L, res); + lua_pushfstring(L, "getting registry type %d not implemented", type); + return 3; + } +#else + luaL_error(L, "This function exists only on windows"); + return 0; +#endif +} /* ------------------------------------------------------ */ /* require (with global flag) */ @@ -969,10 +1047,6 @@ path_require(lua_State *L) -/* ------------------------------------------------------ */ -/* uname */ - - /* ------------------------------------------------------ */ /* register */ @@ -991,6 +1065,7 @@ static const struct luaL_Reg paths__ [] = { {"mkdir", lua_mkdir}, {"rmdir", lua_rmdir}, {"uname", lua_uname}, + {"getregistryvalue", lua_getregistryvalue}, {"require", path_require}, {NULL, NULL} }; -- cgit v1.2.3