/usr/share/lua/5.1/pl/app.lua is in lua-penlight 1.2.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | --- Application support functions.
-- See @{01-introduction.md.Application_Support|the Guide}
--
-- Dependencies: `pl.utils`, `pl.path`
-- @module pl.app
local io,package,require = _G.io, _G.package, _G.require
local utils = require 'pl.utils'
local path = require 'pl.path'
local app = {}
local function check_script_name ()
if _G.arg == nil then error('no command line args available\nWas this run from a main script?') end
return _G.arg[0]
end
--- add the current script's path to the Lua module path.
-- Applies to both the source and the binary module paths. It makes it easy for
-- the main file of a multi-file program to access its modules in the same directory.
-- `base` allows these modules to be put in a specified subdirectory, to allow for
-- cleaner deployment and resolve potential conflicts between a script name and its
-- library directory.
-- @param base optional base directory.
-- @return the current script's path with a trailing slash
function app.require_here (base)
local p = path.dirname(check_script_name())
if not path.isabs(p) then
p = path.join(path.currentdir(),p)
end
if p:sub(-1,-1) ~= path.sep then
p = p..path.sep
end
if base then
p = p..base..path.sep
end
local so_ext = path.is_windows and 'dll' or 'so'
local lsep = package.path:find '^;' and '' or ';'
local csep = package.cpath:find '^;' and '' or ';'
package.path = ('%s?.lua;%s?%sinit.lua%s%s'):format(p,p,path.sep,lsep,package.path)
package.cpath = ('%s?.%s%s%s'):format(p,so_ext,csep,package.cpath)
return p
end
--- return a suitable path for files private to this application.
-- These will look like '~/.SNAME/file', with '~' as with expanduser and
-- SNAME is the name of the script without .lua extension.
-- @param file a filename (w/out path)
-- @return a full pathname, or nil
-- @return 'cannot create' error
function app.appfile (file)
local sname = path.basename(check_script_name())
local name,ext = path.splitext(sname)
local dir = path.join(path.expanduser('~'),'.'..name)
if not path.isdir(dir) then
local ret = path.mkdir(dir)
if not ret then return utils.raise ('cannot create '..dir) end
end
return path.join(dir,file)
end
--- return string indicating operating system.
-- @return 'Windows','OSX' or whatever uname returns (e.g. 'Linux')
function app.platform()
if path.is_windows then
return 'Windows'
else
local f = io.popen('uname')
local res = f:read()
if res == 'Darwin' then res = 'OSX' end
f:close()
return res
end
end
--- return the full command-line used to invoke this script
-- any extra flags occupy slots, so that 'lua -lpl' gives us {[-2]='lua',[-1]='-lpl')
-- @return command-line
-- @return name of Lua program used
function app.lua ()
local args = _G.arg or error "not in a main program"
local imin = 0
for i in pairs(args) do
if i < imin then imin = i end
end
local cmd, append = {}, table.insert
for i = imin,-1 do
local a = args[i]
if a:match '%s' then
a = '"'..a..'"'
end
append(cmd,a)
end
return table.concat(cmd,' '),args[imin]
end
--- parse command-line arguments into flags and parameters.
-- Understands GNU-style command-line flags; short (-f) and long (--flag).
-- These may be given a value with either '=' or ':' (-k:2,--alpha=3.2,-n2);
-- note that a number value can be given without a space.
-- Multiple short args can be combined like so: (-abcd).
-- @param args an array of strings (default is the global 'arg')
-- @param flags_with_values any flags that take values, e.g. <code>{out=true}</code>
-- @return a table of flags (flag=value pairs)
-- @return an array of parameters
-- @raise if args is nil, then the global `args` must be available!
function app.parse_args (args,flags_with_values)
if not args then
args = _G.arg
if not args then error "Not in a main program: 'arg' not found" end
end
flags_with_values = flags_with_values or {}
local _args = {}
local flags = {}
local i = 1
while i <= #args do
local a = args[i]
local v = a:match('^-(.+)')
local is_long
if v then -- we have a flag
if v:find '^-' then
is_long = true
v = v:sub(2)
end
if flags_with_values[v] then
if i == #_args or args[i+1]:find '^-' then
return utils.raise ("no value for '"..v.."'")
end
flags[v] = args[i+1]
i = i + 1
else
-- a value can also be indicated with =
local var,val = utils.splitv (v,'=')
var = var or v
val = val or true
if not is_long then
if #var > 1 then
if var:find '.%d+' then -- short flag, number value
val = var:sub(2)
var = var:sub(1,1)
else -- multiple short flags
for i = 1,#var do
flags[var:sub(i,i)] = true
end
val = nil -- prevents use of var as a flag below
end
else -- single short flag (can have value, defaults to true)
val = val or true
end
end
if val then
flags[var] = val
end
end
else
_args[#_args+1] = a
end
i = i + 1
end
return flags,_args
end
return app
|