/* MI Command Set - environment commands.
   Copyright (C) 2002-2021 Free Software Foundation, Inc.

   Contributed by Red Hat Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "inferior.h"
#include "value.h"
#include "mi-out.h"
#include "mi-cmds.h"
#include "mi-getopt.h"
#include "symtab.h"
#include "target.h"
#include "gdbsupport/environ.h"
#include "command.h"
#include "ui-out.h"
#include "top.h"
#include <sys/stat.h>
#include "source.h"

static const char path_var_name[] = "PATH";
static char *orig_path = NULL;

/* The following is copied from mi-main.c so for m1 and below we can
   perform old behavior and use cli commands.  If ARGS is non-null,
   append it to the CMD.  */

static void
env_execute_cli_command (const char *cmd, const char *args)
{
  if (cmd != 0)
    {
      gdb::unique_xmalloc_ptr<char> run;

      if (args != NULL)
	run.reset (xstrprintf ("%s %s", cmd, args));
      else
	run.reset (xstrdup (cmd));
      execute_command ( /*ui */ run.get (), 0 /*from_tty */ );
    }
}

/* Print working directory.  */

void
mi_cmd_env_pwd (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;

  if (argc > 0)
    error (_("-environment-pwd: No arguments allowed"));
	  
  if (mi_version (uiout) < 2)
    {
      env_execute_cli_command ("pwd", NULL);
      return;
    }
     
  /* Otherwise the mi level is 2 or higher.  */

  gdb::unique_xmalloc_ptr<char> cwd (getcwd (NULL, 0));
  if (cwd == NULL)
    error (_("-environment-pwd: error finding name of working directory: %s"),
	   safe_strerror (errno));

  uiout->field_string ("cwd", cwd.get ());
}

/* Change working directory.  */

void
mi_cmd_env_cd (const char *command, char **argv, int argc)
{
  if (argc == 0 || argc > 1)
    error (_("-environment-cd: Usage DIRECTORY"));
	  
  env_execute_cli_command ("cd", argv[0]);
}

static void
env_mod_path (const char *dirname, char **which_path)
{
  if (dirname == 0 || dirname[0] == '\0')
    return;

  /* Call add_path with last arg 0 to indicate not to parse for 
     separator characters.  */
  add_path (dirname, which_path, 0);
}

/* Add one or more directories to start of executable search path.  */

void
mi_cmd_env_path (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;
  char *exec_path;
  const char *env;
  int reset = 0;
  int oind = 0;
  int i;
  char *oarg;
  enum opt
    {
      RESET_OPT
    };
  static const struct mi_opt opts[] =
  {
    {"r", RESET_OPT, 0},
    { 0, 0, 0 }
  };

  dont_repeat ();

  if (mi_version (uiout) < 2)
    {
      for (i = argc - 1; i >= 0; --i)
	env_execute_cli_command ("path", argv[i]);
      return;
    }

  /* Otherwise the mi level is 2 or higher.  */
  while (1)
    {
      int opt = mi_getopt ("-environment-path", argc, argv, opts,
			   &oind, &oarg);

      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case RESET_OPT:
	  reset = 1;
	  break;
	}
    }
  argv += oind;
  argc -= oind;


  if (reset)
    {
      /* Reset implies resetting to original path first.  */
      exec_path = xstrdup (orig_path);
    }
  else
    {
      /* Otherwise, get current path to modify.  */
      env = current_inferior ()->environment.get (path_var_name);

      /* Can be null if path is not set.  */
      if (!env)
	env = "";
      exec_path = xstrdup (env);
    }

  for (i = argc - 1; i >= 0; --i)
    env_mod_path (argv[i], &exec_path);

  current_inferior ()->environment.set (path_var_name, exec_path);
  xfree (exec_path);
  env = current_inferior ()->environment.get (path_var_name);
  uiout->field_string ("path", env);
}

/* Add zero or more directories to the front of the source path.  */

void
mi_cmd_env_dir (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;
  int i;
  int oind = 0;
  int reset = 0;
  char *oarg;
  enum opt
    {
      RESET_OPT
    };
  static const struct mi_opt opts[] =
  {
    {"r", RESET_OPT, 0},
    { 0, 0, 0 }
  };

  dont_repeat ();

  if (mi_version (uiout) < 2)
    {
      for (i = argc - 1; i >= 0; --i)
	env_execute_cli_command ("dir", argv[i]);
      return;
    }

  /* Otherwise mi level is 2 or higher.  */
  while (1)
    {
      int opt = mi_getopt ("-environment-directory", argc, argv, opts,
			   &oind, &oarg);

      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case RESET_OPT:
	  reset = 1;
	  break;
	}
    }
  argv += oind;
  argc -= oind;

  if (reset)
    {
      /* Reset means setting to default path first.  */
      xfree (source_path);
      init_source_path ();
    }

  for (i = argc - 1; i >= 0; --i)
    env_mod_path (argv[i], &source_path);

  uiout->field_string ("source-path", source_path);
  forget_cached_source_info ();
}

/* Set the inferior terminal device name.  */

void
mi_cmd_inferior_tty_set (const char *command, char **argv, int argc)
{
  if (argc > 0)
    current_inferior ()->set_tty (argv[0]);
  else
    current_inferior ()->set_tty ("");
}

/* Print the inferior terminal device name.  */

void
mi_cmd_inferior_tty_show (const char *command, char **argv, int argc)
{
  if ( !mi_valid_noargs ("-inferior-tty-show", argc, argv))
    error (_("-inferior-tty-show: Usage: No args"));

  const std::string &inferior_tty = current_inferior ()->tty ();
  if (!inferior_tty.empty ())
    current_uiout->field_string ("inferior_tty_terminal", inferior_tty);
}

void _initialize_mi_cmd_env ();
void 
_initialize_mi_cmd_env ()
{
  const char *env;

  /* We want original execution path to reset to, if desired later.
     At this point, current inferior is not created, so cannot use
     current_inferior ()->environment.  We use getenv here because it
     is not necessary to create a whole new gdb_environ just for one
     variable.  */
  env = getenv (path_var_name);

  /* Can be null if path is not set.  */
  if (!env)
    env = "";
  orig_path = xstrdup (env);
}
