(********************************************************************)
(*                                                                  *)
(*  environment.s7i  Support for program arguments and environment. *)
(*  Copyright (C) 1989 - 2012  Thomas Mertes                        *)
(*                                                                  *)
(*  This file is part of the Seed7 Runtime Library.                 *)
(*                                                                  *)
(*  The Seed7 Runtime 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 2.1 of the License, or (at your      *)
(*  option) any later version.                                      *)
(*                                                                  *)
(*  The Seed7 Runtime 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 program; if not, write to the    *)
(*  Free Software Foundation, Inc., 51 Franklin Street,             *)
(*  Fifth Floor, Boston, MA  02110-1301, USA.                       *)
(*                                                                  *)
(********************************************************************)


(**
 *  Return the argument vector of the program as [[array]] of [[string]]s.
 *  The name of the program is not part of the argument vector.
 *  @return an array of strings containing the argument vector.
 *)
const func array string: argv (PROGRAM)                is action "PRC_ARGS";


(**
 *  Returns the name of the program without path and extension.
 *  The name returned by ''name(PROGRAM)'' is the same for interpreted
 *  and compiled programs. The function ''name(PROGRAM)'' does not follow
 *  symbolic links. It determines, with which name a program was called.
 *  When several symbolic links refer to one program ''name(PROGRAM)''
 *  returns the name of the symbolic link.
 *  @return the name of the program.
 *)
const func string: name (PROGRAM)                      is action "PRG_OWN_NAME";


(**
 *  Return the absolute path of the program.
 *  For an interpreted program this is the absolute path of the source file.
 *  For a compiled program this is the absolute path of the executable.
 *  The function path(PROGRAM) does follow symbolic links.
 *  @return the absolute path of the program.
 *)
const func string: path (PROGRAM)                      is action "PRG_OWN_PATH";


(**
 *  Returns the absolute path of the directory containing the program.
 *  The function dir(PROGRAM) allows placing configuration data in the
 *  directory of the program. The function is based on path(PROGRAM).
 *  @return The absolute path of the directory containing the program.
 *)
const func string: dir (PROGRAM) is func
  result
    var string: absolutePath is "";
  local
    var integer: slashPos is 0;
  begin
    absolutePath := path(PROGRAM);
    slashPos := rpos(absolutePath, '/');
    if slashPos = 1 then
      absolutePath := "/";
    elsif slashPos > 1 then
      absolutePath := absolutePath[.. pred(slashPos)];
    end if;
  end func;


(**
 *  Returns the filename of the program without path.
 *  The function is based on path(PROGRAM).
 *  @return The filename of the program.
 *)
const func string: file (PROGRAM) is func
  result
    var string: filename is "";
  local
    var integer: slashPos is 0;
  begin
    filename := path(PROGRAM);
    slashPos := rpos(filename, '/');
    if slashPos <> 0 then
      filename := filename[succ(slashPos) ..];
    end if;
  end func;


(**
 *  Determine the value of an environment variable.
 *  The function getenv searches the environment for an environment variable
 *  with the given ''name''. When such an environment variable exists the
 *  corresponding [[string]] value is returned.
 *  @return the value of an environment variable or "",
 *          when the requested environment variable does not exist.
 *  @exception MEMORY_ERROR Not enough memory to convert ''name'' to the
 *             system string type or not enough memory to represent the
 *             result string.
 *)
const func string: getenv (in string: name)            is action "CMD_GETENV";


(**
 *  Add or change an environment variable.
 *  The function setenv searches the environment for an environment variable
 *  with the given ''name''. When such an environment variable exists the
 *  corresponding value is changed to ''value''. When no environment variable
 *  with the given ''name'' exists a new environment variable ''name'' with
 *  the value ''value'' is created.
 *  @exception MEMORY_ERROR Not enough memory to convert ''name'' or ''value''
 *             to the system string type.
 *  @exception RANGE_ERROR ''name'' or ''value'' cannot be converted to the
 *             system string type or a system function returns an error.
 *)
const proc: setenv (in string: name, in string: value) is action "CMD_SETENV";


(**
 *  Returns the list of environment variable names as [[array]] of [[string]]s.
 *  @return the list of environment variable names.
 *  @exception MEMORY_ERROR Not enough memory to create the result.
 *)
const func array string: environment                   is action "CMD_ENVIRONMENT";