pax_global_header00006660000000000000000000000064130546501330014512gustar00rootroot0000000000000052 comment=4ebe222ba12589fb9d86c1d3895d7f509df77b6a .gitignore000066400000000000000000000000071305465013300130430ustar00rootroot00000000000000build/ CMakeLists.txt000066400000000000000000000031071305465013300136170ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.6) INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}") INCLUDE_DIRECTORIES("${LUA_INCDIR}") LINK_DIRECTORIES("${LUA_LIBDIR}") INCLUDE(CheckIncludeFiles) INCLUDE(CheckFunctionExists) INCLUDE(CheckLibraryExists) IF (UNIX OR NOT WIN32) CHECK_INCLUDE_FILES(fcntl.h HAVE_FCNTL_H) CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H) CHECK_INCLUDE_FILES(dirent.h HAVE_DIRENT_H) CHECK_INCLUDE_FILES(time.h HAVE_TIME_H) CHECK_INCLUDE_FILES(sys/time.h HAVE_SYS_TIME_H) CHECK_INCLUDE_FILES(sys/ndir.h HAVE_SYS_NDIR_H) CHECK_INCLUDE_FILES(sys/utsname.h HAVE_SYS_UTSNAME_H) CHECK_INCLUDE_FILES(sys/dir.h HAVE_SYS_DIR_H) CHECK_INCLUDE_FILES(ndir.h HAVE_NDIR_H) CHECK_FUNCTION_EXISTS(getcwd HAVE_GETCWD) CHECK_LIBRARY_EXISTS(dl dlopen "" HAVE_DLOPEN) ENDIF (UNIX OR NOT WIN32) CONFIGURE_FILE("paths.h.in" "${CMAKE_CURRENT_BINARY_DIR}/paths.h") SET(src "${CMAKE_CURRENT_SOURCE_DIR}/paths.c" "${CMAKE_CURRENT_BINARY_DIR}/paths.h" ) SET(luasrc "${CMAKE_CURRENT_SOURCE_DIR}/init.lua") # When using MSVC IF(MSVC) # we want to respect the standard, and we are bored of those **** . ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE=1) ENDIF(MSVC) ADD_LIBRARY("paths" MODULE ${src}) SET_TARGET_PROPERTIES("paths" PROPERTIES PREFIX "lib" IMPORT_PREFIX "lib") IF(APPLE) SET_TARGET_PROPERTIES("paths" PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") ENDIF() INSTALL(FILES ${luasrc} DESTINATION ${LUADIR}/paths) INSTALL(TARGETS paths LIBRARY DESTINATION ${LIBDIR} RUNTIME DESTINATION ${LIBDIR}) IF(LUALIB) TARGET_LINK_LIBRARIES(paths ${LUALIB}) ENDIF() COPYRIGHT.txt000066400000000000000000000040011305465013300131620ustar00rootroot00000000000000Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert) Copyright (c) 2012-2014 Deepmind Technologies (Koray Kavukcuoglu) Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu) Copyright (c) 2011-2013 NYU (Clement Farabet) Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, Iain Melvin, Jason Weston) Copyright (c) 2006 Idiap Research Institute (Samy Bengio) Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, Samy Bengio, Johnny Mariethoz) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the names of Deepmind Technologies, NYU, NEC Laboratories America and IDIAP Research Institute nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. README.md000066400000000000000000000012031305465013300123310ustar00rootroot00000000000000 # Filename Manipulation Package # This package provides portable functions and variables to manipulate the file system : * [Manipulating filenames](doc/filenames.md) : functions for manipulating filenames ; * [Directory functions](doc/dirfunctions.md) : functions for listing and manipulating directories ; * [Directory paths](doc/dirpaths.md) : paths to well known directories ; * [Miscellaneous](doc/misc.md) : uncategorized functions ; When this package is loaded, it also computes a number of useful variables indicating where the various Torch components are installed. Do not change their values. doc/000077500000000000000000000000001305465013300116235ustar00rootroot00000000000000doc/dirfunctions.md000066400000000000000000000041551305465013300146610ustar00rootroot00000000000000 ## Directory Functions ## The following functions can be used to examine directory contents or manipulate directories. ### paths.dir(dname) ### Return a table containing the files and directories in directory `dname`. This function return `nil` if the specified directory does not exists. For linux, this includes the `.` and `..` directories. ### paths.files(dname [, include]) ### Returns an iterator over the files and directories located in directory `dname`. For linux, this includes the `.` and `..` directories. This can be used in *__for__* expression as shown below: ```lua for f in paths.files(".") do print(f) end ``` Optional argument `include` is either a function or a string used to determine which files are to be included. The function takes the filename as argument and should return true if the file is to be included. When a string is provided, the following function is used : ```lua function(file) return file:find(f) end ``` Files and directories of sub-folders aren't included. ### paths.iterdirs(dname) ### Returns an iterator over the directories located in directory `dname`. This can be used in *__for__* expression as shown below: ```lua for dir in paths.iterdirs(".") do print(dir) end ``` Directories of sub-folders, and the `.` and `..` folders aren't included. ### paths.iterfiles(dname) ### Returns an iterator over the files (non-directories) located in directory `dname`. This can be used in *__for__* expression as shown below: ```lua for file in paths.iterfiles(".") do print(file) end ``` Files of sub-folders, and the `.` and `..` folders aren't included. ### paths.mkdir(s) ### Create a directory. Returns `true` on success. ### paths.rmdir(s) ### Delete an empty directory. Returns `true` on success. ### paths.rmall(s, y) ### Recursively delete file or directory `s` and its contents. Argument `y` must be string `"yes"` Returns `true` on success. doc/dirpaths.md000066400000000000000000000042471305465013300137720ustar00rootroot00000000000000 ## Directory Paths ## These variables indicate the paths where the various Torch components are installed, as well as other common environment variables like `$HOME`. It is not advisable to change their values! ### paths.install_prefix ### The base directory of the Torch installation. ### paths.install_bin ### The name of the directory containing the executable programs. Under Windows, this directory also contains the dynamically loadable libraries (`.dll`). ### paths.install_man ### The name of the directory containing the unix style manual pages. ### paths.install_lib ### The name of the directory containing the object code libraries. Under Unix, this directory also contains the dynamically loadable libraries (`.so` or `.dylib`). ### paths.install_share ### The name of the directory containing processor independent data files, such as lua code and other text files. ### paths.install_include ### The name of the directory containing the include files for the various Torch libraries. ### paths.install_hlp ### The name of the directory containing the Torch help files. ### paths.install_html ### The name of the directory containing the HTML version of the Torch help files. These files are generated when you enable the CMake option `HTML_DOC`. ### paths.install_cmake ### The name of the directory containing the CMake files used by external Torch modules. ### paths.install_lua_path ### The name of the directory containing the Lua packages. This directory is used to build variable `package.path`. ### paths.install_lua_cpath ### The name of the directory containing the Lua loadable binary modules. This directory is used to build variable `package.cpath`. ### paths.home ### The home directory of the current user. doc/filenames.md000066400000000000000000000042101305465013300141050ustar00rootroot00000000000000 ## Manipulating Filenames ## The following functions can be used to manipulate filenames in a portable way over multiple platforms. ### paths.filep(path) ### Return a boolean indicating whether `path` refers to an existing file. ### paths.dirp(path) ### Return a boolean indicating whether `path` refers to an existing directory. ### paths.basename(path,[suffix]) ### Return the last path component of `path` and optionally strip the suffix `suffix`. This is similar to the well know shell command `"basename"`. ### paths.dirname(path) ### Return the name of directory containing file `path`. This is similar to the well known shell command `"dirname"`. ### paths.extname(path) ### Return the extension of the `path` or nil if none is found. ### paths.concat([path1,....,pathn]) ### Concatenates relative filenames. First this function computes the full filename of `path1` relative to the current directory. Then it successively computes the full filenames of arguments `path2` to `pathn` relative to the filename returned for the previous argument. Finally the last result is returned. Calling this function without argument returns the full name of the current directory. ### paths.cwd() ### Return the full path of the current working directory. ### paths.execdir() ### Return the name of the directory containing the current Lua executable. When the module `paths` is first loaded, this information is used to relocate the variables indicating the location of the various Torch components. ### paths.tmpname() ### Return the name of a temporary file. All the temporaty files whose name was obtained in this way are removed when Lua exits. This function should be preferred over `os.tmpname()` because it makes sure that the files are removed on exit. In addition, `os.tmpname()` under windows often returns filenames for which the user has no permission to write. doc/index.md000066400000000000000000000011641305465013300132560ustar00rootroot00000000000000 # Filename Manipulation Package # This package provides portable functions and variables to manipulate the file system : * [Manipulating filenames](filenames.md) : functions for manipulating filenames ; * [Directory functions](dirfunctions.md) : functions for listing and manipulating directories ; * [Directory paths](dirpaths.md) : paths to well known directories ; * [Miscellaneous](misc.md) : uncategorized functions ; When this package is loaded, it also computes a number of useful variables indicating where the various Torch components are installed. Do not change their values. doc/misc.md000066400000000000000000000036721305465013300131100ustar00rootroot00000000000000 ## Miscellaneous ## ### paths.uname() ### Returns up to three strings describing the operating system. The first string is a system name, e.g., "Windows", "Linux", "Darwin", "FreeBSD", etc. The second string is the network name of this computer. The third string indicates the processor type. ### paths.is_win() ### Returns true if the operating system is Microsoft Windows. ### paths.is_mac() ### 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 named "progname" and returns its full path. If none is found, continue searching programs named after the following arguments and return the full path of the first match. All the directories specified by the PATH variable are searched. Under windows, this also searches the "App Path" registry entries. ### paths.thisfile([arg]) ### Calling `paths.thisfile()` without argument inside a lua file returns returns the full pathname of the file from which it is called. This function always returns `nil` when called interactively. Calling `paths.thisfile(arg)` with a string argument `arg` returns the full pathname of the file `arg` relative to the directory containing the file from which function `paths.thisfile` is invoked. This is useful, for instance, to locate files located in the same directory as a lua script. ### paths.dofile(filename) ### This function is similar to the standard Lua function `dofile` but interprets `filename` relative to the directory containing the file that contains the call to `paths.dofile`, or to the current directory when `paths.dofile` is called interactively. init.lua000066400000000000000000000076021305465013300125310ustar00rootroot00000000000000require 'libpaths' local assert = assert local debug = debug local pcall = pcall local type = type local ipairs = ipairs local os = os function paths.is_win() return paths.uname():match('Windows') end function paths.is_mac() return paths.uname():match('Darwin') end if paths.is_win() then paths.home = os.getenv('HOMEDRIVE') or 'C:' paths.home = paths.home .. ( os.getenv('HOMEPATH') or '\\' ) else paths.home = os.getenv('HOME') or '.' end function paths.files(s, f) local d = paths.dir(s) local n = 0 if type(f) == 'string' then local pattern = f f = function(file) return file:find(pattern) end elseif f and type(f) ~= 'function' then error("Expecting optional arg 2 to be function or string. Got : "..torch.type(f)) end f = f or function(file) return true end local n = 0 return function() while true do n = n + 1 if d == nil or n > #d then return nil elseif f(d[n]) then return d[n] end end end end function paths.iterdirs(s) return paths.files(s, function(dir) return paths.dirp(paths.concat(s, dir)) and dir ~= '.' and dir ~= '..' end) end function paths.iterfiles(s) return paths.files(s, function(file) return paths.filep(paths.concat(s, file)) and file ~= '.' and file ~= '..' end) end function paths.thisfile(arg, depth) local s = debug.getinfo(depth or 2).source if type(s) ~= "string" then s = nil elseif s:match("^@") then -- when called from a file s = paths.concat(s:sub(2)) elseif s:match("^qt[.]") then -- when called from a qtide editor local function z(s) return qt[s].fileName:tostring() end local b, f = pcall(z, s:sub(4)); if b and f and f ~= "" then s = f else s = nil end end if type(arg) == "string" then if s then s = paths.concat(paths.dirname(s), arg) else s = arg end end return s end function paths.dofile(f, depth) local s = paths.thisfile(nil, 1 + (depth or 2)) if s and s ~= "" then f = paths.concat(paths.dirname(s),f) end return dofile(f) end function paths.rmall(d, more) if more ~= 'yes' then return nil, "missing second argument ('yes')" elseif paths.filep(d) then return os.remove(d) elseif paths.dirp(d) then for f in paths.files(d) do if f ~= '.' and f ~= '..' then local ff = paths.concat(d, f) local r0,r1,r2 = paths.rmall(ff, more) if not r0 then return r0,r1,ff end end end return paths.rmdir(d) else return nil, "not a file or directory", d end end function paths.findprogram(...) for _,exe in ipairs{...} do if paths.is_win() then if not exe:match('[.]exe$') then exe = exe .. '.exe' end local path, k, x = os.getenv("PATH") or "." for dir in path:gmatch('[^;]+') do x = paths.concat(dir, exe) if paths.filep(x) then return x end end local function clean(s) if s:match('^"') then return s:match('[^"]+') else return s end end k = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\' .. exe x = paths.getregistryvalue('HKEY_CURRENT_USER', k, '') if type(x) == 'string' then return clean(x) end x = paths.getregistryvalue('HKEY_LOCAL_MACHINE', k, '') if type(x) == 'string' then return clean(x) end k = 'Applications\\' .. exe .. '\\shell\\open\\command' x = paths.getregistryvalue('HKEY_CLASSES_ROOT', k, '') if type(x) == 'string' then return clean(x) end else local path = os.getenv("PATH") or "." for dir in path:gmatch('[^:]+') do local x = paths.concat(dir, exe) if paths.filep(x) then return x end end end end return nil end return paths mkdocs.yml000066400000000000000000000004731305465013300130650ustar00rootroot00000000000000site_name: paths theme : simplex repo_url : https://github.com/torch/paths use_directory_urls : false markdown_extensions: [extra] docs_dir : doc pages: - [index.md, Paths] - [filenames.md, Manipulating Filenames] - [dirfunctions.md, Directory Functions] - [dirpaths.md, Directory Paths] - [misc.md, Miscellaneous] paths.c000066400000000000000000000573221305465013300123520ustar00rootroot00000000000000/* -*- C -*- */ #include "paths.h" /* ------------------------------------------------------ */ /* Utils to manipulate strings */ #define SBINCREMENT 256 typedef struct { char *buffer; int maxlen; int len; } SB; static void sbinit(SB *sb) { sb->buffer = (char*)malloc(SBINCREMENT); sb->maxlen = SBINCREMENT; sb->len = 0; } static char * sbfree(SB *sb) { if (sb->buffer) free(sb->buffer); sb->buffer = 0; return 0; } static void sbgrow(SB *sb, int n) { if (sb->buffer && sb->len + n > sb->maxlen) { int nlen = sb->maxlen; while (sb->len + n > nlen) nlen += SBINCREMENT; sb->buffer = (char*)realloc(sb->buffer, nlen); sb->maxlen = nlen; } } static void sbadd1(SB *sb, char c) { sbgrow(sb, 1); if (sb->buffer) sb->buffer[sb->len++] = c; } static void sbaddn(SB *sb, const char *s, int n) { sbgrow(sb, n); if (sb->buffer && s && n) memcpy(sb->buffer + sb->len, s, n); else if (sb->buffer && n) sbfree(sb); sb->len += n; } static void sbaddsf(SB *sb, char *s) { if (s) sbaddn(sb, s, strlen(s)); else sbfree(sb); if (s) free((void*)s); } static void sbslash(SB *sb) { int i; if (sb->buffer && sb->len) for(i=0; ilen; i++) if (sb->buffer[i]=='\\') sb->buffer[i]='/'; } static int sbpush(lua_State *L, SB *sb) { sbslash(sb); lua_pushlstring(L, sb->buffer, sb->len); sbfree(sb); return 1; } static int sbsetpush(lua_State *L, SB *sb, const char *s) { sbfree(sb); lua_pushstring(L, s); return 1; } /* ------------------------------------------------------ */ /* filep, dirp, basename, dirname */ static int filep(lua_State *L, int i) { const char *s = luaL_checkstring(L, i); #ifdef _WIN32 struct _stat buf; if (_stat(s,&buf) < 0) return 0; if (buf.st_mode & S_IFDIR) return 0; #else struct stat buf; if (stat(s,&buf) < 0) return 0; if (buf.st_mode & S_IFDIR) return 0; #endif return 1; } static int dirp(lua_State *L, int i) { const char *s = luaL_checkstring(L, i); #ifdef _WIN32 char buffer[8]; struct _stat buf; const char *last; if ((s[0]=='/' || s[0]=='\\') && (s[1]=='/' || s[1]=='\\') && !s[2]) return 1; if (s[0] && isalpha((unsigned char)(s[0])) && s[1] == ':' && s[2] == 0) { buffer[0]=s[0]; buffer[1]=':'; buffer[2]='.'; buffer[3]=0; s = buffer; } if (_stat(s, &buf) >= 0) if (buf.st_mode & S_IFDIR) return 1; #else struct stat buf; if (stat(s,&buf)==0) if (buf.st_mode & S_IFDIR) return 1; #endif return 0; } static int lua_filep(lua_State *L) { lua_pushboolean(L, filep(L, 1)); return 1; } static int lua_dirp(lua_State *L) { lua_pushboolean(L, dirp(L, 1)); return 1; } static int lua_basename(lua_State *L) { const char *fname = luaL_checkstring(L, 1); const char *suffix = luaL_optstring(L, 2, 0); #ifdef _WIN32 int sl; const char *p, *s; SB sb; sbinit(&sb); /* Special cases */ if (fname[0] && fname[1]==':') { sbaddn(&sb, fname, 2); fname += 2; if (fname[0]=='/' || fname[0]=='\\') sbadd1(&sb, '/'); while (fname[0]=='/' || fname[0]=='\\') fname += 1; if (fname[0]==0) return sbpush(L, &sb); sb.len = 0; } /* Position p after last nontrivial slash */ s = p = fname; while (*s) { if ((s[0]=='\\' || s[0]=='/') && (s[1] && s[1]!='/' && s[1]!='\\' ) ) p = s + 1; s++; } /* Copy into buffer */ while (*p && *p!='/' && *p!='\\') sbadd1(&sb, *p++); /* Process suffix */ if (suffix==0 || suffix[0]==0) return sbpush(L, &sb); if (suffix[0]=='.') suffix += 1; if (suffix[0]==0) return sbpush(L, &sb); sl = strlen(suffix); if (sb.len > sl) { s = sb.buffer + sb.len - (sl + 1); if (s[0]=='.' && _strnicmp(s+1,suffix, sl)==0) sb.len = s - sb.buffer; } return sbpush(L, &sb); #else int sl; const char *s, *p; SB sb; sbinit(&sb); /* Position p after last nontrivial slash */ s = p = fname; while (*s) { if (s[0]=='/' && s[1] && s[1]!='/') p = s + 1; s++; } /* Copy into buffer */ while (*p && *p!='/') sbadd1(&sb, *p++); /* Process suffix */ if (suffix==0 || suffix[0]==0) return sbpush(L, &sb); if (suffix[0]=='.') suffix += 1; if (suffix[0]==0) return sbpush(L, &sb); sl = strlen(suffix); if (sb.len > sl) { s = sb.buffer + sb.len - (sl + 1); if (s[0]=='.' && strncmp(s+1,suffix, sl)==0) sb.len = s - sb.buffer; } return sbpush(L, &sb); #endif } static int lua_dirname(lua_State *L) { const char *fname = luaL_checkstring(L, 1); #ifdef _WIN32 const char *s; const char *p; SB sb; sbinit(&sb); /* Handle leading drive specifier */ if (isalpha((unsigned char)fname[0]) && fname[1]==':') { sbadd1(&sb, *fname++); sbadd1(&sb, *fname++); } /* Search last non terminal / or \ */ p = 0; s = fname; while (*s) { if ((s[0]=='\\' || s[0]=='/') && (s[1] && s[1]!='/' && s[1]!='\\') ) p = s; s++; } /* Cannot find non terminal / or \ */ if (p == 0) { if (sb.len > 0) { if (fname[0]==0 || fname[0]=='/' || fname[0]=='\\') sbadd1(&sb, '/'); return sbpush(L, &sb); } else { if (fname[0]=='/' || fname[0]=='\\') return sbsetpush(L, &sb, "//"); else return sbsetpush(L, &sb, "."); } } /* Single leading slash */ if (p == fname) { sbadd1(&sb, '/'); return sbpush(L, &sb); } /* Backtrack all slashes */ while (p>fname && (p[-1]=='/' || p[-1]=='\\')) p--; /* Multiple leading slashes */ if (p == fname) return sbsetpush(L, &sb, "//"); /* Regular case */ s = fname; do { sbadd1(&sb, *s++); } while (s= fname) { if (*p == '.') { lua_pushstring(L, p + 1); return 1; } p--; } return 0; } /* ------------------------------------------------------ */ /* cwd and concat */ static int lua_cwd(lua_State *L) { #ifdef _WIN32 char drv[2]; int l; SB sb; sbinit(&sb); drv[0] = '.'; drv[1] = 0; l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0); if (l > sb.maxlen) { sbgrow(&sb, l+1); l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0); } if (l <= 0) return sbsetpush(L, &sb, "."); sb.len += l; return sbpush(L, &sb); #elif HAVE_GETCWD const char *s; SB sb; sbinit(&sb); s = getcwd(sb.buffer, sb.maxlen); while (!s && errno==ERANGE) { sbgrow(&sb, sb.maxlen + SBINCREMENT); s = getcwd(sb.buffer, sb.maxlen); } if (! s) return sbsetpush(L, &sb, "."); sb.len += strlen(s); return sbpush(L, &sb); #else const char *s; SB sb; sbinit(&sb); sbgrow(&sb, PATH_MAX); s = getwd(sb.buffer); if (! s) return sbsetpush(L, &sb, "."); sb.len += strlen(s); return sbpush(L, &sb); #endif } static int concat_fname(lua_State *L, const char *fname) { const char *from = lua_tostring(L, -1); #ifdef _WIN32 const char *s; SB sb; sbinit(&sb); sbaddn(&sb, from, strlen(from)); if (fname==0) return sbpush(L, &sb); /* Handle absolute part of fname */ if (fname[0]=='/' || fname[0]=='\\') { if (fname[1]=='/' || fname[1]=='\\') { sb.len = 0; /* Case //abcd */ sbaddn(&sb, "//", 2); } else { char drive; if (sb.len >= 2 && sb.buffer[1]==':' /* Case "/abcd" */ && isalpha((unsigned char)(sb.buffer[0])) ) drive = sb.buffer[0]; else drive = _getdrive() + 'A' - 1; sb.len = 0; sbadd1(&sb, drive); sbaddn(&sb, ":/", 2); } } else if (fname[0] && /* Case "x:abcd" */ isalpha((unsigned char)(fname[0])) && fname[1]==':') { if (fname[2]!='/' && fname[2]!='\\') { if (sb.len < 2 || sb.buffer[1]!=':' || !isalpha((unsigned char)(sb.buffer[0])) || (toupper((unsigned char)sb.buffer[0]) != toupper((unsigned char)fname[0]) ) ) { int l; char drv[4]; sb.len = 0; drv[0]=fname[0]; drv[1]=':'; drv[2]='.'; drv[3]=0; l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0); if (l > sb.maxlen) { sbgrow(&sb, l+1); l = GetFullPathNameA(drv, sb.maxlen, sb.buffer, 0); } if (l <= 0) sbaddn(&sb, drv, 3); else sb.len += l; } fname += 2; } else { sb.len = 0; /* Case "x:/abcd" */ sbadd1(&sb, toupper((unsigned char)fname[0])); sbaddn(&sb, ":/", 2); fname += 2; while (*fname == '/' || *fname == '\\') fname += 1; } } /* Process path components */ for (;;) { while (*fname=='/' || *fname=='\\') fname ++; if (*fname == 0) return sbpush(L, &sb); if (fname[0]=='.') { if (fname[1]=='/' || fname[1]=='\\' || fname[1]==0) { fname += 1; continue; } if (fname[1]=='.') if (fname[2]=='/' || fname[2]=='\\' || fname[2]==0) { size_t l; fname += 2; lua_pushcfunction(L, lua_dirname); sbpush(L, &sb); lua_call(L, 1, 1); s = lua_tolstring(L, -1, &l); sbinit(&sb); sbaddn(&sb, s, l); lua_pop(L, 1); continue; } } if (sb.len==0 || (sb.buffer[sb.len-1]!='/' && sb.buffer[sb.len-1]!='\\') ) sbadd1(&sb, '/'); while (*fname && *fname!='/' && *fname!='\\') sbadd1(&sb, *fname++); } #else SB sb; sbinit(&sb); if (fname && fname[0]=='/') sbadd1(&sb, '/'); else sbaddn(&sb, from, strlen(from)); for (;;) { while (fname && fname[0]=='/') fname++; if (!fname || !fname[0]) { sbadd1(&sb, '/'); while (sb.len > 1 && sb.buffer[sb.len-1]=='/') sb.len --; return sbpush(L, &sb); } if (fname[0]=='.') { if (fname[1]=='/' || fname[1]==0) { fname +=1; continue; } if (fname[1]=='.') if (fname[2]=='/' || fname[2]==0) { fname +=2; while (sb.len > 0 && sb.buffer[sb.len-1]=='/') sb.len --; while (sb.len > 0 && sb.buffer[sb.len-1]!='/') sb.len --; continue; } } if (sb.len == 0 || sb.buffer[sb.len-1] != '/') sbadd1(&sb, '/'); while (*fname!=0 && *fname!='/') sbadd1(&sb, *fname++); } #endif } static int lua_concatfname(lua_State *L) { int i; int narg = lua_gettop(L); lua_cwd(L); for (i=1; i<=narg; i++) { concat_fname(L, luaL_checkstring(L, i)); lua_remove(L, -2); } return 1; } /* ------------------------------------------------------ */ /* execdir */ static int lua_execdir(lua_State *L) { const char *s = 0; #if HAVE_LUA_EXECUTABLE_DIR s = lua_executable_dir(0); #endif if (s && s[0]) lua_pushstring(L, s); else lua_pushnil(L); return 1; } /* ------------------------------------------------------ */ /* file lists */ static int lua_dir(lua_State *L) { int k = 0; const char *s = luaL_checkstring(L, 1); #ifdef _WIN32 SB sb; struct _finddata_t info; intptr_t hfind; /* special cases */ lua_createtable(L, 0, 0); if ((s[0]=='/' || s[0]=='\\') && (s[1]=='/' || s[1]=='\\') && !s[2]) { int drive; hfind = GetLogicalDrives(); for (drive='A'; drive<='Z'; drive++) if (hfind & ((intptr_t)1<<(drive-'A'))) { lua_pushfstring(L, "%c:/", drive); lua_rawseti(L, -2, ++k); } } else if (dirp(L, 1)) { lua_pushliteral(L, ".."); lua_rawseti(L, -2, ++k); } else { lua_pushnil(L); return 1; } /* files */ sbinit(&sb); sbaddn(&sb, s, strlen(s)); if (sb.len>0 && sb.buffer[sb.len-1]!='/' && sb.buffer[sb.len-1]!='\\') sbadd1(&sb, '/'); sbaddn(&sb, "*.*", 3); sbadd1(&sb, 0); hfind = _findfirst(sb.buffer, &info); if (hfind != -1) { do { if (strcmp(".",info.name) && strcmp("..",info.name)) { lua_pushstring(L, info.name); lua_rawseti(L, -2, ++k); } } while ( _findnext(hfind, &info) != -1 ); _findclose(hfind); } sbfree(&sb); #else DIR *dirp; struct dirent *d; dirp = opendir(s); if (dirp) { lua_createtable(L, 0, 0); while ((d = readdir(dirp))) { int n = NAMLEN(d); lua_pushlstring(L, d->d_name, n); lua_rawseti(L, -2, ++k); } closedir(dirp); } else lua_pushnil(L); #endif return 1; } /* ------------------------------------------------------ */ /* tmpname */ static const char *tmpnames_key = "tmpname_sentinel"; struct tmpname_s { struct tmpname_s *next; char tmp[4]; }; static int gc_tmpname(lua_State *L) { if (lua_isuserdata(L, -1)) { struct tmpname_s **pp = (struct tmpname_s **)lua_touserdata(L, -1); while (pp && *pp) { struct tmpname_s *p = *pp; *pp = p->next; remove(p->tmp); free(p); } } return 0; } static void add_tmpname(lua_State *L, const char *tmp) { struct tmpname_s **pp = 0; lua_pushlightuserdata(L, (void*)tmpnames_key); lua_rawget(L, LUA_REGISTRYINDEX); if (lua_isuserdata(L, -1)) { pp = (struct tmpname_s **)lua_touserdata(L, -1); lua_pop(L, 1); } else { lua_pop(L, 1); /* create sentinel */ lua_pushlightuserdata(L, (void*)tmpnames_key); pp = (struct tmpname_s **)lua_newuserdata(L, sizeof(void*)); pp[0] = 0; lua_createtable(L, 0, 1); lua_pushcfunction(L, gc_tmpname); lua_setfield(L,-2,"__gc"); lua_setmetatable(L, -2); lua_rawset(L, LUA_REGISTRYINDEX); } while (pp && *pp) { struct tmpname_s *p = *pp; if (!strcmp(p->tmp, tmp)) return; pp = &(p->next); } if (pp) { int len = strlen(tmp); struct tmpname_s *t = (struct tmpname_s*)malloc(len + sizeof(struct tmpname_s)); if (t) { t->next = 0; memcpy(t->tmp, tmp, len); t->tmp[len] = 0; *pp = t; } } } static int lua_tmpname(lua_State *L) { #ifdef _WIN32 char *tmp = _tempnam("c:/temp", "luatmp"); #else char *tmp = tempnam(NULL, "luatmp"); #endif if (tmp) { lua_pushstring(L, tmp); add_tmpname(L, tmp); free(tmp); return 1; } else { lua_pushnil(L); return 1; } } /* ------------------------------------------------------ */ /* mkdir, rmdir */ static int pushresult (lua_State *L, int i, const char *filename) { int en = errno; if (i) { lua_pushboolean(L, 1); return 1; } else { lua_pushnil(L); lua_pushfstring(L, "%s: %s", filename, strerror(en)); lua_pushinteger(L, en); return 3; } } static int lua_mkdir(lua_State *L) { int status = 0; const char *s = luaL_checkstring(L, 1); lua_pushcfunction(L, lua_mkdir); lua_pushcfunction(L, lua_dirname); lua_pushvalue(L, 1); lua_call(L, 1, 1); if (! dirp(L, -1)) lua_call(L, 1, 3); #ifdef _WIN32 status = _mkdir(s); #else status = mkdir(s, 0777); #endif return pushresult(L, status == 0, s); } static int lua_rmdir(lua_State *L) { const char *s = luaL_checkstring(L, 1); #ifdef _WIN32 int status = _rmdir(s); #else int status = rmdir(s); #endif return pushresult(L, status == 0, s); } /* ------------------------------------------------------ */ /* uname */ static int lua_uname(lua_State *L) { #if defined(_WIN32) const char *name; SYSTEM_INFO info; lua_pushliteral(L, "Windows"); name = getenv("COMPUTERNAME"); lua_pushstring(L, name ? name : ""); memset(&info, 0, sizeof(info)); GetSystemInfo(&info); if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) lua_pushliteral(L, "AMD64"); else if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) lua_pushliteral(L, "X86"); else if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM) lua_pushliteral(L, "ARM"); else if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) lua_pushliteral(L, "IA64"); else if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) lua_pushstring(L, ""); return 3; #else # if defined(HAVE_SYS_UTSNAME_H) struct utsname info; if (uname(&info) >= 0) { lua_pushstring(L, info.sysname); lua_pushstring(L, info.nodename); lua_pushstring(L, info.machine); return 3; } # endif lua_pushstring(L, "Unknown"); return 1; #endif } static int lua_getregistryvalue(lua_State *L) { #ifdef _WIN32 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 = NULL; 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 (len > 0) { len += 8; data = (char*)malloc(len); if (! data) luaL_error(L, "out of memory"); res = RegQueryValueExA(skey, value, NULL, &type, (LPBYTE)data, &len); } RegCloseKey(skey); if (res != ERROR_SUCCESS) { if (data) free(data); 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_DWORD: lua_pushinteger(L, (lua_Integer)*(const DWORD*)data); if (data) free(data); return 1; case REG_EXPAND_SZ: if (data && len > 0) { if ((len = ExpandEnvironmentStrings(data, NULL, 0)) > 0) { char *buf = (char*)malloc(len + 8); if (!buf) luaL_error(L, "out of memory"); len = ExpandEnvironmentStrings(data, buf, len+8); free(data); data = buf; } } /* fall thru */ case REG_SZ: if (data && len > 0) if (((const char*)data)[len-1] == 0) len -= 1; /* fall thru */ case REG_BINARY: if (data && len > 0) lua_pushlstring(L, (const char*)data, (int)len); else lua_pushliteral(L, ""); if (data) free(data); return 1; /* unimplemented */ case REG_QWORD: case REG_MULTI_SZ: 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) */ #ifdef HAVE_DLOPEN # define NEED_PATH_REQUIRE 1 # include # ifndef RTLD_LAZY # define RTLD_LAZY 1 # endif # ifndef RTLD_GLOBAL # define RTLD_GLOBAL 0 # endif # define LL_LOAD(h,fname) h=dlopen(fname,RTLD_LAZY|RTLD_GLOBAL) # define LL_SYM(h,sym) dlsym(h, sym) #endif #ifdef _WIN32 # define NEED_PATH_REQUIRE 1 # include # define LL_LOAD(h,fname) h=(void*)LoadLibraryA(fname) # define LL_SYM(h,sym) GetProcAddress((HINSTANCE)h,sym) #endif #if NEED_PATH_REQUIRE /* {{{ functions copied or derived from loadlib.c */ static int readable (const char *filename) { FILE *f = fopen(filename, "r"); /* try to open file */ if (f == NULL) return 0; /* open failed */ fclose(f); return 1; } #if LUA_VERSION_NUM >= 502 /* LUA52 compatibility defs */ #define LUA_PATHSEP ";" #define PATHS_LUA_CLEANUP_DEFS 1 #endif static const char *pushnexttemplate (lua_State *L, const char *path) { const char *l; while (*path == *LUA_PATHSEP) path++; /* skip separators */ if (*path == '\0') return NULL; /* no more templates */ l = strchr(path, *LUA_PATHSEP); /* find next separator */ if (l == NULL) l = path + strlen(path); lua_pushlstring(L, path, l - path); /* template */ return l; } #ifdef PATHS_LUA_CLEANUP_DEFS /* cleanup after yourself */ #undef LUA_PATHSEP #endif static const char *pushfilename (lua_State *L, const char *name) { const char *path; const char *filename; lua_getglobal(L, "package"); lua_getfield(L, -1, "cpath"); lua_remove(L, -2); if (! (path = lua_tostring(L, -1))) luaL_error(L, LUA_QL("package.cpath") " must be a string"); lua_pushliteral(L, ""); while ((path = pushnexttemplate(L, path))) { filename = luaL_gsub(L, lua_tostring(L, -1), "?", name); lua_remove(L, -2); if (readable(filename)) { /* stack: cpath errmsg filename */ lua_remove(L, -3); lua_remove(L, -2); return lua_tostring(L, -1); } lua_pushfstring(L, "\n\tno file " LUA_QS, filename); lua_remove(L, -2); /* remove file name */ lua_concat(L, 2); /* add entry to possible error message */ } lua_pushfstring(L, "module " LUA_QS " not found", name); lua_replace(L, -3); lua_concat(L, 2); lua_error(L); return 0; } /* functions copied or derived from loadlib.c }}} */ static int path_require(lua_State *L) { const char *filename; lua_CFunction func; void *handle; const char *name = luaL_checkstring(L, 1); lua_settop(L, 1); lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); /* index 2 */ lua_getfield(L, 2, name); if (lua_toboolean(L, -1)) return 1; filename = pushfilename(L, name); /* index 3 */ LL_LOAD(handle, filename); if (! handle) luaL_error(L, "cannot load " LUA_QS, filename); lua_pushfstring(L, "luaopen_%s", name); /* index 4 */ func = (lua_CFunction)LL_SYM(handle, lua_tostring(L, -1)); if (! func) luaL_error(L, "no symbol " LUA_QS " in module " LUA_QS, lua_tostring(L, -1), filename); lua_pushboolean(L, 1); lua_setfield(L, 2, name); lua_pushcfunction(L, func); lua_pushstring(L, name); lua_call(L, 1, 1); if (! lua_isnil(L, -1)) lua_setfield(L, 2, name); lua_getfield(L, 2, name); return 1; } #else /* fallback to calling require */ static int path_require(lua_State *L) { int narg = lua_gettop(L); lua_getglobal(L, "require"); lua_insert(L, 1); lua_call(L, narg, 1); return 1; } #endif /* ------------------------------------------------------ */ /* register */ static const struct luaL_Reg paths__ [] = { {"filep", lua_filep}, {"dirp", lua_dirp}, {"basename", lua_basename}, {"dirname", lua_dirname}, {"extname", lua_extname}, {"cwd", lua_cwd}, {"concat", lua_concatfname}, {"execdir", lua_execdir}, {"dir", lua_dir}, {"tmpname", lua_tmpname}, {"mkdir", lua_mkdir}, {"rmdir", lua_rmdir}, {"uname", lua_uname}, {"getregistryvalue", lua_getregistryvalue}, {"require", path_require}, {NULL, NULL} }; PATHS_API int luaopen_libpaths(lua_State *L) { lua_newtable(L); lua_pushvalue(L, -1); lua_setglobal(L, "paths"); #if LUA_VERSION_NUM >= 502 luaL_setfuncs(L, paths__, 0); #else luaL_register(L, NULL, paths__); #endif return 1; } paths.h.in000066400000000000000000000031131305465013300127510ustar00rootroot00000000000000/* -*- C -*- */ #include "lua.h" #include "lauxlib.h" #include #include #include #include #if defined(_WIN32) || defined(LUA_WIN) # ifdef paths_EXPORTS # define PATHS_API __declspec(dllexport) # else # define PATHS_API __declspec(dllimport) # endif #else # define PATHS_API /**/ #endif #if defined(_WIN32) || defined(LUA_WIN) # include # include # include # include # include # include # include # include # include #else #cmakedefine HAVE_DIRENT_H 1 #cmakedefine HAVE_FCNTL_H 1 #cmakedefine HAVE_UNISTD_H 1 #cmakedefine HAVE_TIME_H 1 #cmakedefine HAVE_SYS_TIME_H 1 #cmakedefine HAVE_SYS_NDIR_H 1 #cmakedefine HAVE_SYS_DIR_H 1 #cmakedefine HAVE_SYS_UTSNAME_H 1 #cmakedefine HAVE_NDIR_H 1 #cmakedefine HAVE_GETCWD 1 #cmakedefine HAVE_DLOPEN 1 # include # include # include # if HAVE_FCNTL_H # include # endif # if HAVE_UNISTD_H # include # endif # if HAVE_SYS_TIME_H # include # endif # if HAVE_SYS_UTSNAME_H # include # endif # if HAVE_TIME_H # include # endif # ifdef HAVE_UNISTD_H # include # endif # ifdef HAVE_DIRENT_H # include # define NAMLEN(dirent) strlen((dirent)->d_name) # else # define dirent direct # define NAMLEN(dirent) (dirent)->d_namlen # if HAVE_SYS_NDIR_H # include # endif # if HAVE_SYS_DIR_H # include # endif # if HAVE_NDIR_H # include # endif # endif #endif rocks/000077500000000000000000000000001305465013300121775ustar00rootroot00000000000000rocks/paths-scm-1.rockspec000066400000000000000000000011731305465013300157710ustar00rootroot00000000000000package = "paths" version = "scm-1" source = { url = "git://github.com/torch/paths.git", } description = { summary = "Paths manipulations", detailed = [[ ]], homepage = "https://github.com/torch/paths", license = "BSD" } dependencies = { "lua >= 5.1", } build = { type = "command", build_command = [[ cmake -E make_directory build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Release -DLUALIB=$(LUALIB) -DLUA_INCDIR="$(LUA_INCDIR)" -DLUA_LIBDIR="$(LUA_LIBDIR)" -DLUADIR="$(LUADIR)" -DLIBDIR="$(LIBDIR)" -DCMAKE_INSTALL_PREFIX="$(PREFIX)" && $(MAKE) ]], install_command = "cd build && $(MAKE) install" }