Merge from vendor branch GDB:
[dragonfly.git] / contrib / gdb-6 / gdb / mi / mi-cmd-env.c
1 /* MI Command Set - environment commands.
2
3    Copyright (C) 2002, 2003, 2004, 2007 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 3 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, see <http://www.gnu.org/licenses/>.  */
21
22 #include "defs.h"
23 #include "inferior.h"
24 #include "value.h"
25 #include "mi-out.h"
26 #include "mi-cmds.h"
27 #include "mi-getopt.h"
28 #include "symtab.h"
29 #include "target.h"
30 #include "environ.h"
31 #include "command.h"
32 #include "ui-out.h"
33 #include "top.h"
34
35 #include "gdb_string.h"
36 #include "gdb_stat.h"
37
38 static void env_mod_path (char *dirname, char **which_path);
39 extern void _initialize_mi_cmd_env (void);
40
41 static const char path_var_name[] = "PATH";
42 static char *orig_path = NULL;
43
44 /* The following is copied from mi-main.c so for m1 and below we can
45    perform old behavior and use cli commands.  If ARGS is non-null,
46    append it to the CMD.  */
47 static void
48 env_execute_cli_command (const char *cmd, const char *args)
49 {
50   if (cmd != 0)
51     {
52       struct cleanup *old_cleanups;
53       char *run;
54       if (args != NULL)
55         run = xstrprintf ("%s %s", cmd, args);
56       else
57         run = xstrdup (cmd);
58       old_cleanups = make_cleanup (xfree, run);
59       execute_command ( /*ui */ run, 0 /*from_tty */ );
60       do_cleanups (old_cleanups);
61       return;
62     }
63 }
64
65
66 /* Print working directory.  */
67 enum mi_cmd_result
68 mi_cmd_env_pwd (char *command, char **argv, int argc)
69 {
70   if (argc > 0)
71     error (_("mi_cmd_env_pwd: No arguments required"));
72           
73   if (mi_version (uiout) < 2)
74     {
75       env_execute_cli_command ("pwd", NULL);
76       return MI_CMD_DONE;
77     }
78      
79   /* Otherwise the mi level is 2 or higher.  */
80
81   getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
82   ui_out_field_string (uiout, "cwd", gdb_dirbuf);
83
84   return MI_CMD_DONE;
85 }
86
87 /* Change working directory.  */
88 enum mi_cmd_result
89 mi_cmd_env_cd (char *command, char **argv, int argc)
90 {
91   if (argc == 0 || argc > 1)
92     error (_("mi_cmd_env_cd: Usage DIRECTORY"));
93           
94   env_execute_cli_command ("cd", argv[0]);
95
96   return MI_CMD_DONE;
97 }
98
99 static void
100 env_mod_path (char *dirname, char **which_path)
101 {
102   if (dirname == 0 || dirname[0] == '\0')
103     return;
104
105   /* Call add_path with last arg 0 to indicate not to parse for 
106      separator characters.  */
107   add_path (dirname, which_path, 0);
108 }
109
110 /* Add one or more directories to start of executable search path.  */
111 enum mi_cmd_result
112 mi_cmd_env_path (char *command, char **argv, int argc)
113 {
114   char *exec_path;
115   char *env;
116   int reset = 0;
117   int optind = 0;
118   int i;
119   char *optarg;
120   enum opt
121     {
122       RESET_OPT
123     };
124   static struct mi_opt opts[] =
125   {
126     {"r", RESET_OPT, 0},
127     { 0, 0, 0 }
128   };
129
130   dont_repeat ();
131
132   if (mi_version (uiout) < 2)
133     {
134       for (i = argc - 1; i >= 0; --i)
135         env_execute_cli_command ("path", argv[i]);
136       return MI_CMD_DONE;
137     }
138
139   /* Otherwise the mi level is 2 or higher.  */
140   while (1)
141     {
142       int opt = mi_getopt ("mi_cmd_env_path", argc, argv, opts,
143                            &optind, &optarg);
144       if (opt < 0)
145         break;
146       switch ((enum opt) opt)
147         {
148         case RESET_OPT:
149           reset = 1;
150           break;
151         }
152     }
153   argv += optind;
154   argc -= optind;
155
156
157   if (reset)
158     {
159       /* Reset implies resetting to original path first.  */
160       exec_path = xstrdup (orig_path);
161     }
162   else
163     {
164       /* Otherwise, get current path to modify.  */
165       env = get_in_environ (inferior_environ, path_var_name);
166
167       /* Can be null if path is not set.  */
168       if (!env)
169         env = "";
170       exec_path = xstrdup (env);
171     }
172
173   for (i = argc - 1; i >= 0; --i)
174     env_mod_path (argv[i], &exec_path);
175
176   set_in_environ (inferior_environ, path_var_name, exec_path);
177   xfree (exec_path);
178   env = get_in_environ (inferior_environ, path_var_name);
179   ui_out_field_string (uiout, "path", env);
180
181   return MI_CMD_DONE;
182 }
183
184 /* Add zero or more directories to the front of the source path.  */
185 enum mi_cmd_result
186 mi_cmd_env_dir (char *command, char **argv, int argc)
187 {
188   int i;
189   int optind = 0;
190   int reset = 0;
191   char *optarg;
192   enum opt
193     {
194       RESET_OPT
195     };
196   static struct mi_opt opts[] =
197   {
198     {"r", RESET_OPT, 0},
199     { 0, 0, 0 }
200   };
201
202   dont_repeat ();
203
204   if (mi_version (uiout) < 2)
205     {
206       for (i = argc - 1; i >= 0; --i)
207         env_execute_cli_command ("dir", argv[i]);
208       return MI_CMD_DONE;
209     }
210
211   /* Otherwise mi level is 2 or higher.  */
212   while (1)
213     {
214       int opt = mi_getopt ("mi_cmd_env_dir", argc, argv, opts,
215                            &optind, &optarg);
216       if (opt < 0)
217         break;
218       switch ((enum opt) opt)
219         {
220         case RESET_OPT:
221           reset = 1;
222           break;
223         }
224     }
225   argv += optind;
226   argc -= optind;
227
228   if (reset)
229     {
230       /* Reset means setting to default path first.  */
231       xfree (source_path);
232       init_source_path ();
233     }
234
235   for (i = argc - 1; i >= 0; --i)
236     env_mod_path (argv[i], &source_path);
237   init_last_source_visited ();
238
239   ui_out_field_string (uiout, "source-path", source_path);
240   forget_cached_source_info ();
241
242   return MI_CMD_DONE;
243 }
244
245 /* Set the inferior terminal device name.  */
246 enum mi_cmd_result
247 mi_cmd_inferior_tty_set (char *command, char **argv, int argc)
248 {
249   set_inferior_io_terminal (argv[0]);
250
251   return MI_CMD_DONE;
252 }
253
254 /* Print the inferior terminal device name  */
255 enum mi_cmd_result
256 mi_cmd_inferior_tty_show (char *command, char **argv, int argc)
257 {
258   const char *inferior_io_terminal = get_inferior_io_terminal ();
259   
260   if ( !mi_valid_noargs ("mi_cmd_inferior_tty_show", argc, argv))
261     error (_("mi_cmd_inferior_tty_show: Usage: No args"));
262
263   if (inferior_io_terminal)
264     ui_out_field_string (uiout, "inferior_tty_terminal", inferior_io_terminal);
265
266   return MI_CMD_DONE;
267 }
268
269 void 
270 _initialize_mi_cmd_env (void)
271 {
272   char *env;
273
274   /* We want original execution path to reset to, if desired later.  */
275   env = get_in_environ (inferior_environ, path_var_name);
276
277   /* Can be null if path is not set.  */
278   if (!env)
279     env = "";
280   orig_path = xstrdup (env);
281 }