1 /* MI Command Set - environment commands. 2 3 Copyright 2002, 2003, 2004 Free Software Foundation, Inc. 4 5 Contributed by Red Hat Inc. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 59 Temple Place - Suite 330, 22 Boston, MA 02111-1307, USA. */ 23 24 #include "defs.h" 25 #include "inferior.h" 26 #include "value.h" 27 #include "mi-out.h" 28 #include "mi-cmds.h" 29 #include "mi-getopt.h" 30 #include "symtab.h" 31 #include "target.h" 32 #include "environ.h" 33 #include "command.h" 34 #include "ui-out.h" 35 #include "top.h" 36 37 #include "gdb_string.h" 38 #include "gdb_stat.h" 39 40 static void env_mod_path (char *dirname, char **which_path); 41 extern void _initialize_mi_cmd_env (void); 42 43 static const char path_var_name[] = "PATH"; 44 static char *orig_path = NULL; 45 46 /* The following is copied from mi-main.c so for m1 and below we can 47 perform old behavior and use cli commands. If ARGS is non-null, 48 append it to the CMD. */ 49 static void 50 env_execute_cli_command (const char *cmd, const char *args) 51 { 52 if (cmd != 0) 53 { 54 struct cleanup *old_cleanups; 55 char *run; 56 if (args != NULL) 57 run = xstrprintf ("%s %s", cmd, args); 58 else 59 run = xstrdup (cmd); 60 old_cleanups = make_cleanup (xfree, run); 61 execute_command ( /*ui */ run, 0 /*from_tty */ ); 62 do_cleanups (old_cleanups); 63 return; 64 } 65 } 66 67 68 /* Print working directory. */ 69 enum mi_cmd_result 70 mi_cmd_env_pwd (char *command, char **argv, int argc) 71 { 72 if (argc > 0) 73 error ("mi_cmd_env_pwd: No arguments required"); 74 75 if (mi_version (uiout) < 2) 76 { 77 env_execute_cli_command ("pwd", NULL); 78 return MI_CMD_DONE; 79 } 80 81 /* Otherwise the mi level is 2 or higher. */ 82 83 getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); 84 ui_out_field_string (uiout, "cwd", gdb_dirbuf); 85 86 return MI_CMD_DONE; 87 } 88 89 /* Change working directory. */ 90 enum mi_cmd_result 91 mi_cmd_env_cd (char *command, char **argv, int argc) 92 { 93 if (argc == 0 || argc > 1) 94 error ("mi_cmd_env_cd: Usage DIRECTORY"); 95 96 env_execute_cli_command ("cd", argv[0]); 97 98 return MI_CMD_DONE; 99 } 100 101 static void 102 env_mod_path (char *dirname, char **which_path) 103 { 104 if (dirname == 0 || dirname[0] == '\0') 105 return; 106 107 /* Call add_path with last arg 0 to indicate not to parse for 108 separator characters. */ 109 add_path (dirname, which_path, 0); 110 } 111 112 /* Add one or more directories to start of executable search path. */ 113 enum mi_cmd_result 114 mi_cmd_env_path (char *command, char **argv, int argc) 115 { 116 char *exec_path; 117 char *env; 118 int reset = 0; 119 int optind = 0; 120 int i; 121 char *optarg; 122 enum opt 123 { 124 RESET_OPT 125 }; 126 static struct mi_opt opts[] = 127 { 128 {"r", RESET_OPT, 0}, 129 0 130 }; 131 132 dont_repeat (); 133 134 if (mi_version (uiout) < 2) 135 { 136 for (i = argc - 1; i >= 0; --i) 137 env_execute_cli_command ("path", argv[i]); 138 return MI_CMD_DONE; 139 } 140 141 /* Otherwise the mi level is 2 or higher. */ 142 while (1) 143 { 144 int opt = mi_getopt ("mi_cmd_env_path", argc, argv, opts, 145 &optind, &optarg); 146 if (opt < 0) 147 break; 148 switch ((enum opt) opt) 149 { 150 case RESET_OPT: 151 reset = 1; 152 break; 153 } 154 } 155 argv += optind; 156 argc -= optind; 157 158 159 if (reset) 160 { 161 /* Reset implies resetting to original path first. */ 162 exec_path = xstrdup (orig_path); 163 } 164 else 165 { 166 /* Otherwise, get current path to modify. */ 167 env = get_in_environ (inferior_environ, path_var_name); 168 169 /* Can be null if path is not set. */ 170 if (!env) 171 env = ""; 172 exec_path = xstrdup (env); 173 } 174 175 for (i = argc - 1; i >= 0; --i) 176 env_mod_path (argv[i], &exec_path); 177 178 set_in_environ (inferior_environ, path_var_name, exec_path); 179 xfree (exec_path); 180 env = get_in_environ (inferior_environ, path_var_name); 181 ui_out_field_string (uiout, "path", env); 182 183 return MI_CMD_DONE; 184 } 185 186 /* Add zero or more directories to the front of the source path. */ 187 enum mi_cmd_result 188 mi_cmd_env_dir (char *command, char **argv, int argc) 189 { 190 int i; 191 int optind = 0; 192 int reset = 0; 193 char *optarg; 194 enum opt 195 { 196 RESET_OPT 197 }; 198 static struct mi_opt opts[] = 199 { 200 {"r", RESET_OPT, 0}, 201 0 202 }; 203 204 dont_repeat (); 205 206 if (mi_version (uiout) < 2) 207 { 208 for (i = argc - 1; i >= 0; --i) 209 env_execute_cli_command ("dir", argv[i]); 210 return MI_CMD_DONE; 211 } 212 213 /* Otherwise mi level is 2 or higher. */ 214 while (1) 215 { 216 int opt = mi_getopt ("mi_cmd_env_dir", argc, argv, opts, 217 &optind, &optarg); 218 if (opt < 0) 219 break; 220 switch ((enum opt) opt) 221 { 222 case RESET_OPT: 223 reset = 1; 224 break; 225 } 226 } 227 argv += optind; 228 argc -= optind; 229 230 if (reset) 231 { 232 /* Reset means setting to default path first. */ 233 xfree (source_path); 234 init_source_path (); 235 } 236 237 for (i = argc - 1; i >= 0; --i) 238 env_mod_path (argv[i], &source_path); 239 init_last_source_visited (); 240 241 ui_out_field_string (uiout, "source-path", source_path); 242 forget_cached_source_info (); 243 244 return MI_CMD_DONE; 245 } 246 247 void 248 _initialize_mi_cmd_env (void) 249 { 250 char *env; 251 252 /* We want original execution path to reset to, if desired later. */ 253 env = get_in_environ (inferior_environ, path_var_name); 254 255 /* Can be null if path is not set. */ 256 if (!env) 257 env = ""; 258 orig_path = xstrdup (env); 259 } 260