lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Philipp Janda once stated:
> Anyway, I also wanted to mention a new rock that appeared recently on 
> LuaRocks.org, and might be of interest: lua-whereami[1], which gives you 
> the path to the Lua executable, so you can at least require modules 
> relative to the Lua executable on non-Windows machines, too ...
>
>   [1]: https://luarocks.org/modules/jprjr/whereami

  Interesting.  Not at all how I would expected it to be done (very system
specific code for each major operating system).  Included below is a module
I just wrote that (hopefully) does the same thing but in pure Lua (just in
case anyone wants this but doesn't want to rely upon a C library).

  -spc

-- ***************************************************************
--
-- Copyright 2017 by Sean Conner.  All Rights Reserved.
--
-- This library is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or (at your
-- option) any later version.
--
-- This library is distributed in the hope that it will be useful, but
-- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
-- License for more details.
--
-- You should have received a copy of the GNU Lesser General Public License
-- along with this library; if not, see <http://www.gnu.org/licenses/>.
--
-- Comments, questions and criticisms can be sent to: sean@conman.org
--
-- ********************************************************************
-- luacheck: ignore 611

local package = require "package"
local io      = require "io"
local os      = require "os"
local arg     = arg

local DIR = package.config:sub(1,1)
local PATHSEP

-- ------------------------------------------------------------------------
-- On Windows, the path seperator in $PATH is ';' but on other systems
-- (namely Unix) it's ':'.  We check obtain the directory separator (from
-- package[]) and if it's the backslash, then we're on a Windows system and
-- we set the PATHSEP accordingly.
-- ------------------------------------------------------------------------

if DIR == "\\" then
  PATHSEP = ";"
else
  PATHSEP = ":"
end

-- ************************************************************************
-- Usage:       path,directory,err = whereami()
-- Desc:        Return the path and directory of the Lua executable
-- Return:      path (string) path (including program name) of executable
--              directory (string) the above, minus the program name
--              err (string/optional) error message
-- ************************************************************************

return function()
  if not arg then
    return nil,nil,"no argument list"
  end
  
  -- -----------------------------------------------------------------------
  -- If there's a directory separator in the program name, then we won't
  -- find ourselves in $PATH.  In this case, we just return the program name
  -- and the path.
  -- -----------------------------------------------------------------------
  
  if arg[-1]:match(DIR) then
    return arg[-1],arg[-1]:match("^(.*)" .. DIR .. "[^" .. DIR .. "]*$")
  end
  
  -- --------------------------------------------------------------------
  -- Most commonly used operating systems support $PATH.  If you are using
  -- a system that doesn't have $PATH, then why are you using this?
  -- ---------------------------------------------------------------------
  
  local path = os.getenv("PATH")
  if not path then
    return nil,nil,"missing $PATH"
  end
  
  for segment in path:gmatch("[^" .. PATHSEP .. "]+") do
    local name = segment .. DIR .. arg[-1]
    local f    = io.open(name,"r")
    if f then
      f:close()
      return name,segment
    end
  end
  return nil,nil,"not in path?"
end