1130803Smarcel/* MI Command Set - environment commands. 2130803Smarcel 3130803Smarcel Copyright 2002, 2003, 2004 Free Software Foundation, Inc. 4130803Smarcel 5130803Smarcel Contributed by Red Hat Inc. 6130803Smarcel 7130803Smarcel This file is part of GDB. 8130803Smarcel 9130803Smarcel This program is free software; you can redistribute it and/or modify 10130803Smarcel it under the terms of the GNU General Public License as published by 11130803Smarcel the Free Software Foundation; either version 2 of the License, or 12130803Smarcel (at your option) any later version. 13130803Smarcel 14130803Smarcel This program is distributed in the hope that it will be useful, 15130803Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 16130803Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17130803Smarcel GNU General Public License for more details. 18130803Smarcel 19130803Smarcel You should have received a copy of the GNU General Public License 20130803Smarcel along with this program; if not, write to the Free Software 21130803Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 22130803Smarcel Boston, MA 02111-1307, USA. */ 23130803Smarcel 24130803Smarcel#include "defs.h" 25130803Smarcel#include "inferior.h" 26130803Smarcel#include "value.h" 27130803Smarcel#include "mi-out.h" 28130803Smarcel#include "mi-cmds.h" 29130803Smarcel#include "mi-getopt.h" 30130803Smarcel#include "symtab.h" 31130803Smarcel#include "target.h" 32130803Smarcel#include "environ.h" 33130803Smarcel#include "command.h" 34130803Smarcel#include "ui-out.h" 35130803Smarcel#include "top.h" 36130803Smarcel 37130803Smarcel#include "gdb_string.h" 38130803Smarcel#include "gdb_stat.h" 39130803Smarcel 40130803Smarcelstatic void env_mod_path (char *dirname, char **which_path); 41130803Smarcelextern void _initialize_mi_cmd_env (void); 42130803Smarcel 43130803Smarcelstatic const char path_var_name[] = "PATH"; 44130803Smarcelstatic char *orig_path = NULL; 45130803Smarcel 46130803Smarcel/* The following is copied from mi-main.c so for m1 and below we can 47130803Smarcel perform old behavior and use cli commands. If ARGS is non-null, 48130803Smarcel append it to the CMD. */ 49130803Smarcelstatic void 50130803Smarcelenv_execute_cli_command (const char *cmd, const char *args) 51130803Smarcel{ 52130803Smarcel if (cmd != 0) 53130803Smarcel { 54130803Smarcel struct cleanup *old_cleanups; 55130803Smarcel char *run; 56130803Smarcel if (args != NULL) 57130803Smarcel xasprintf (&run, "%s %s", cmd, args); 58130803Smarcel else 59130803Smarcel run = xstrdup (cmd); 60130803Smarcel old_cleanups = make_cleanup (xfree, run); 61130803Smarcel execute_command ( /*ui */ run, 0 /*from_tty */ ); 62130803Smarcel do_cleanups (old_cleanups); 63130803Smarcel return; 64130803Smarcel } 65130803Smarcel} 66130803Smarcel 67130803Smarcel 68130803Smarcel/* Print working directory. */ 69130803Smarcelenum mi_cmd_result 70130803Smarcelmi_cmd_env_pwd (char *command, char **argv, int argc) 71130803Smarcel{ 72130803Smarcel if (argc > 0) 73130803Smarcel error ("mi_cmd_env_pwd: No arguments required"); 74130803Smarcel 75130803Smarcel if (mi_version (uiout) < 2) 76130803Smarcel { 77130803Smarcel env_execute_cli_command ("pwd", NULL); 78130803Smarcel return MI_CMD_DONE; 79130803Smarcel } 80130803Smarcel 81130803Smarcel /* Otherwise the mi level is 2 or higher. */ 82130803Smarcel 83130803Smarcel getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); 84130803Smarcel ui_out_field_string (uiout, "cwd", gdb_dirbuf); 85130803Smarcel 86130803Smarcel return MI_CMD_DONE; 87130803Smarcel} 88130803Smarcel 89130803Smarcel/* Change working directory. */ 90130803Smarcelenum mi_cmd_result 91130803Smarcelmi_cmd_env_cd (char *command, char **argv, int argc) 92130803Smarcel{ 93130803Smarcel if (argc == 0 || argc > 1) 94130803Smarcel error ("mi_cmd_env_cd: Usage DIRECTORY"); 95130803Smarcel 96130803Smarcel env_execute_cli_command ("cd", argv[0]); 97130803Smarcel 98130803Smarcel return MI_CMD_DONE; 99130803Smarcel} 100130803Smarcel 101130803Smarcelstatic void 102130803Smarcelenv_mod_path (char *dirname, char **which_path) 103130803Smarcel{ 104130803Smarcel if (dirname == 0 || dirname[0] == '\0') 105130803Smarcel return; 106130803Smarcel 107130803Smarcel /* Call add_path with last arg 0 to indicate not to parse for 108130803Smarcel separator characters. */ 109130803Smarcel add_path (dirname, which_path, 0); 110130803Smarcel} 111130803Smarcel 112130803Smarcel/* Add one or more directories to start of executable search path. */ 113130803Smarcelenum mi_cmd_result 114130803Smarcelmi_cmd_env_path (char *command, char **argv, int argc) 115130803Smarcel{ 116130803Smarcel char *exec_path; 117130803Smarcel char *env; 118130803Smarcel int reset = 0; 119130803Smarcel int optind = 0; 120130803Smarcel int i; 121130803Smarcel char *optarg; 122130803Smarcel enum opt 123130803Smarcel { 124130803Smarcel RESET_OPT 125130803Smarcel }; 126130803Smarcel static struct mi_opt opts[] = 127130803Smarcel { 128130803Smarcel {"r", RESET_OPT, 0}, 129130803Smarcel 0 130130803Smarcel }; 131130803Smarcel 132130803Smarcel dont_repeat (); 133130803Smarcel 134130803Smarcel if (mi_version (uiout) < 2) 135130803Smarcel { 136130803Smarcel for (i = argc - 1; i >= 0; --i) 137130803Smarcel env_execute_cli_command ("path", argv[i]); 138130803Smarcel return MI_CMD_DONE; 139130803Smarcel } 140130803Smarcel 141130803Smarcel /* Otherwise the mi level is 2 or higher. */ 142130803Smarcel while (1) 143130803Smarcel { 144130803Smarcel int opt = mi_getopt ("mi_cmd_env_path", argc, argv, opts, 145130803Smarcel &optind, &optarg); 146130803Smarcel if (opt < 0) 147130803Smarcel break; 148130803Smarcel switch ((enum opt) opt) 149130803Smarcel { 150130803Smarcel case RESET_OPT: 151130803Smarcel reset = 1; 152130803Smarcel break; 153130803Smarcel } 154130803Smarcel } 155130803Smarcel argv += optind; 156130803Smarcel argc -= optind; 157130803Smarcel 158130803Smarcel 159130803Smarcel if (reset) 160130803Smarcel { 161130803Smarcel /* Reset implies resetting to original path first. */ 162130803Smarcel exec_path = xstrdup (orig_path); 163130803Smarcel } 164130803Smarcel else 165130803Smarcel { 166130803Smarcel /* Otherwise, get current path to modify. */ 167130803Smarcel env = get_in_environ (inferior_environ, path_var_name); 168130803Smarcel 169130803Smarcel /* Can be null if path is not set. */ 170130803Smarcel if (!env) 171130803Smarcel env = ""; 172130803Smarcel exec_path = xstrdup (env); 173130803Smarcel } 174130803Smarcel 175130803Smarcel for (i = argc - 1; i >= 0; --i) 176130803Smarcel env_mod_path (argv[i], &exec_path); 177130803Smarcel 178130803Smarcel set_in_environ (inferior_environ, path_var_name, exec_path); 179130803Smarcel xfree (exec_path); 180130803Smarcel env = get_in_environ (inferior_environ, path_var_name); 181130803Smarcel ui_out_field_string (uiout, "path", env); 182130803Smarcel 183130803Smarcel return MI_CMD_DONE; 184130803Smarcel} 185130803Smarcel 186130803Smarcel/* Add zero or more directories to the front of the source path. */ 187130803Smarcelenum mi_cmd_result 188130803Smarcelmi_cmd_env_dir (char *command, char **argv, int argc) 189130803Smarcel{ 190130803Smarcel int i; 191130803Smarcel int optind = 0; 192130803Smarcel int reset = 0; 193130803Smarcel char *optarg; 194130803Smarcel enum opt 195130803Smarcel { 196130803Smarcel RESET_OPT 197130803Smarcel }; 198130803Smarcel static struct mi_opt opts[] = 199130803Smarcel { 200130803Smarcel {"r", RESET_OPT, 0}, 201130803Smarcel 0 202130803Smarcel }; 203130803Smarcel 204130803Smarcel dont_repeat (); 205130803Smarcel 206130803Smarcel if (mi_version (uiout) < 2) 207130803Smarcel { 208130803Smarcel for (i = argc - 1; i >= 0; --i) 209130803Smarcel env_execute_cli_command ("dir", argv[i]); 210130803Smarcel return MI_CMD_DONE; 211130803Smarcel } 212130803Smarcel 213130803Smarcel /* Otherwise mi level is 2 or higher. */ 214130803Smarcel while (1) 215130803Smarcel { 216130803Smarcel int opt = mi_getopt ("mi_cmd_env_dir", argc, argv, opts, 217130803Smarcel &optind, &optarg); 218130803Smarcel if (opt < 0) 219130803Smarcel break; 220130803Smarcel switch ((enum opt) opt) 221130803Smarcel { 222130803Smarcel case RESET_OPT: 223130803Smarcel reset = 1; 224130803Smarcel break; 225130803Smarcel } 226130803Smarcel } 227130803Smarcel argv += optind; 228130803Smarcel argc -= optind; 229130803Smarcel 230130803Smarcel if (reset) 231130803Smarcel { 232130803Smarcel /* Reset means setting to default path first. */ 233130803Smarcel xfree (source_path); 234130803Smarcel init_source_path (); 235130803Smarcel } 236130803Smarcel 237130803Smarcel for (i = argc - 1; i >= 0; --i) 238130803Smarcel env_mod_path (argv[i], &source_path); 239130803Smarcel init_last_source_visited (); 240130803Smarcel 241130803Smarcel ui_out_field_string (uiout, "source-path", source_path); 242130803Smarcel forget_cached_source_info (); 243130803Smarcel 244130803Smarcel return MI_CMD_DONE; 245130803Smarcel} 246130803Smarcel 247130803Smarcelvoid 248130803Smarcel_initialize_mi_cmd_env (void) 249130803Smarcel{ 250130803Smarcel char *env; 251130803Smarcel 252130803Smarcel /* We want original execution path to reset to, if desired later. */ 253130803Smarcel env = get_in_environ (inferior_environ, path_var_name); 254130803Smarcel 255130803Smarcel /* Can be null if path is not set. */ 256130803Smarcel if (!env) 257130803Smarcel env = ""; 258130803Smarcel orig_path = xstrdup (env); 259130803Smarcel} 260