#
# paths.icn - procedures for manipulating IPATH/LPATH
#
# Author: Clinton Jeffery
#

# link to older IPL module for actual executable path search routine
link getpaths

#
# the global variable "iconc" needs to be defined here for all uses other
# than in the unicon compiler. Defining this global here will not affect any
# other global definition in the unicon compiler sources and will prevent
# any undefined variable messages in other applications that use this IPL file.
#
global iconc

#
# pathsep() returns the sentinel value that separates elements of the path.
# extra care is needed (on non-Windows systems) when space appears in a
# pathname, since space is the path separator for many shells.
#
procedure pathsep()
   return getenv("PATHSEP") | ";"
end

# return the top level unicon directory
procedure ulibprefix()
   static prefix
   local path, f, c, i
   initial  {
      if path := (&features ? (="Libraries at " & tab(upto(';') | 0))) then
         prefix := path || "/"
      else if (path := (&features ? (="Binaries at " & tab(0)))) |
	  ((f := open((path := getpaths()) || ("uniconx" | "iconx" |
					       "uniconx.exe" |"iconx.exe" |
					       "wuniconx.exe" | "wiconx.exe"))))
      then {
	 close(\f)
	 # The returned path has the form  /path/unicon/bin/
	 # Drop the bin directory from the path to get the root
	 # unicon directory

	 # remove the trailing slash it could be / or \
	 c := path[-1:0]
	 path := path[1:-1]
	 # find the previous slash and copy the path up to it including the slash
         every i:= find(c, path)
	 prefix := path[1:i+1]
         }
      if &features=="MS Windows NT" then
	  prefix:=map(prefix, '/', '\\')
      }
   return prefix
end

# unicon library paths
procedure ulibpaths()
   static libpath
   local prefix, sep
   initial {
      sep := pathsep()
      prefix := ulibprefix()
      libpath :=
	  prefix || "ipl/lib"     || sep ||
	  prefix || "uni/lib"     || sep ||
	  prefix || "uni/gui"     || sep ||
	  prefix || "uni/xml"     || sep ||
	  prefix || "uni/parser"  || sep ||
	  prefix || "uni/3d"      || sep ||
	  prefix || "plugins/lib" || sep

      if &features=="MS Windows NT" then
	  libpath:=map(libpath, '/', '\\')
      }
   return libpath
end

procedure ipaths()
    static pathstr
    initial
       pathstr :=  (semicolonpath("IPATH") | ".") || pathsep() || ulibpaths()
    return pathstr
end

procedure lpaths()
static pathstr
local sep, prefix
   initial {
      sep := pathsep()
      prefix := ulibprefix()

      pathstr := ulibpaths()

      pathstr ||:=
         prefix || "/ipl/incl"  || sep ||
         prefix || "/ipl/gincl" || sep ||
         prefix || "/ipl/mincl" || sep

      if \iconc then
         pathstr ||:=
            prefix || "/ipl/procs"  || sep ||
            prefix || "/ipl/gprocs" || sep ||
            prefix || "/ipl/gprogs" || sep

      pathstr := (semicolonpath("LPATH") | ".") || sep || pathstr
      if &features=="MS Windows NT" then
	  pathstr:=map(pathstr, '/', '\\')
      }
   return pathstr
end

# return paths separated by semicolons by default, unless the user asks for something else (supplied by Jafar)
procedure semicolonpath(env, sep)
   local p
   p := getenv(env) | fail
   if not getenv("PATHSEP") then
      # for backward compatibility of space separated paths, replace spaces with semicolons,
      # only do this if the path doesn't contain semicolons already
      if not find(";", p ) then
         return map(p, " ", ";")
   return p
end

procedure paths_get(path, sep)
   local pathstr, rslt
   rslt := []
   pathstr := path
   /sep := pathsep()
   if \pathstr ~== "" then {
      pathstr ? {
         while put(rslt, tab(find(sep))) do
            tab(many('; \t'))
         put(rslt, tab(0))
         }
      }
   return rslt
end

procedure ipaths_get()
   static rslt
   initial
      rslt := paths_get(ipaths())
   return rslt
end

procedure lpaths_get()
   static rslt
   initial
      rslt := paths_get(lpaths())
   return rslt
end
