Remove free_splay_tree cleanup
[external/binutils.git] / gdb / mi / mi-cmd-env.c
1 /* MI Command Set - environment commands.
2    Copyright (C) 2002-2017 Free Software Foundation, Inc.
3
4    Contributed by Red Hat Inc.
5
6    This file is part of GDB.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
21 #include "defs.h"
22 #include "inferior.h"
23 #include "value.h"
24 #include "mi-out.h"
25 #include "mi-cmds.h"
26 #include "mi-getopt.h"
27 #include "symtab.h"
28 #include "target.h"
29 #include "environ.h"
30 #include "command.h"
31 #include "ui-out.h"
32 #include "top.h"
33 #include <sys/stat.h>
34
35 static void env_mod_path (char *dirname, char **which_path);
36
37 static const char path_var_name[] = "PATH";
38 static char *orig_path = NULL;
39
40 /* The following is copied from mi-main.c so for m1 and below we can
41    perform old behavior and use cli commands.  If ARGS is non-null,
42    append it to the CMD.  */
43
44 static void
45 env_execute_cli_command (const char *cmd, const char *args)
46 {
47   if (cmd != 0)
48     {
49       gdb::unique_xmalloc_ptr<char> run;
50
51       if (args != NULL)
52         run.reset (xstrprintf ("%s %s", cmd, args));
53       else
54         run.reset (xstrdup (cmd));
55       execute_command ( /*ui */ run.get (), 0 /*from_tty */ );
56     }
57 }
58
59 /* Print working directory.  */
60
61 void
62 mi_cmd_env_pwd (const char *command, char **argv, int argc)
63 {
64   struct ui_out *uiout = current_uiout;
65
66   if (argc > 0)
67     error (_("-environment-pwd: No arguments allowed"));
68           
69   if (mi_version (uiout) < 2)
70     {
71       env_execute_cli_command ("pwd", NULL);
72       return;
73     }
74      
75   /* Otherwise the mi level is 2 or higher.  */
76
77   gdb::unique_xmalloc_ptr<char> cwd (getcwd (NULL, 0));
78   if (cwd == NULL)
79     error (_("-environment-pwd: error finding name of working directory: %s"),
80            safe_strerror (errno));
81
82   uiout->field_string ("cwd", cwd.get ());
83 }
84
85 /* Change working directory.  */
86
87 void
88 mi_cmd_env_cd (const char *command, char **argv, int argc)
89 {
90   if (argc == 0 || argc > 1)
91     error (_("-environment-cd: Usage DIRECTORY"));
92           
93   env_execute_cli_command ("cd", argv[0]);
94 }
95
96 static void
97 env_mod_path (char *dirname, char **which_path)
98 {
99   if (dirname == 0 || dirname[0] == '\0')
100     return;
101
102   /* Call add_path with last arg 0 to indicate not to parse for 
103      separator characters.  */
104   add_path (dirname, which_path, 0);
105 }
106
107 /* Add one or more directories to start of executable search path.  */
108
109 void
110 mi_cmd_env_path (const char *command, char **argv, int argc)
111 {
112   struct ui_out *uiout = current_uiout;
113   char *exec_path;
114   const char *env;
115   int reset = 0;
116   int oind = 0;
117   int i;
118   char *oarg;
119   enum opt
120     {
121       RESET_OPT
122     };
123   static const struct mi_opt opts[] =
124   {
125     {"r", RESET_OPT, 0},
126     { 0, 0, 0 }
127   };
128
129   dont_repeat ();
130
131   if (mi_version (uiout) < 2)
132     {
133       for (i = argc - 1; i >= 0; --i)
134         env_execute_cli_command ("path", argv[i]);
135       return;
136     }
137
138   /* Otherwise the mi level is 2 or higher.  */
139   while (1)
140     {
141       int opt = mi_getopt ("-environment-path", argc, argv, opts,
142                            &oind, &oarg);
143
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 += oind;
154   argc -= oind;
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 = current_inferior ()->environment.get (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   current_inferior ()->environment.set (path_var_name, exec_path);
177   xfree (exec_path);
178   env = current_inferior ()->environment.get (path_var_name);
179   uiout->field_string ("path", env);
180 }
181
182 /* Add zero or more directories to the front of the source path.  */
183
184 void
185 mi_cmd_env_dir (const char *command, char **argv, int argc)
186 {
187   struct ui_out *uiout = current_uiout;
188   int i;
189   int oind = 0;
190   int reset = 0;
191   char *oarg;
192   enum opt
193     {
194       RESET_OPT
195     };
196   static const 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;
209     }
210
211   /* Otherwise mi level is 2 or higher.  */
212   while (1)
213     {
214       int opt = mi_getopt ("-environment-directory", argc, argv, opts,
215                            &oind, &oarg);
216
217       if (opt < 0)
218         break;
219       switch ((enum opt) opt)
220         {
221         case RESET_OPT:
222           reset = 1;
223           break;
224         }
225     }
226   argv += oind;
227   argc -= oind;
228
229   if (reset)
230     {
231       /* Reset means setting to default path first.  */
232       xfree (source_path);
233       init_source_path ();
234     }
235
236   for (i = argc - 1; i >= 0; --i)
237     env_mod_path (argv[i], &source_path);
238
239   uiout->field_string ("source-path", source_path);
240   forget_cached_source_info ();
241 }
242
243 /* Set the inferior terminal device name.  */
244
245 void
246 mi_cmd_inferior_tty_set (const char *command, char **argv, int argc)
247 {
248   set_inferior_io_terminal (argv[0]);
249 }
250
251 /* Print the inferior terminal device name.  */
252
253 void
254 mi_cmd_inferior_tty_show (const char *command, char **argv, int argc)
255 {
256   const char *inferior_io_terminal = get_inferior_io_terminal ();
257   
258   if ( !mi_valid_noargs ("-inferior-tty-show", argc, argv))
259     error (_("-inferior-tty-show: Usage: No args"));
260
261   if (inferior_io_terminal)
262     current_uiout->field_string ("inferior_tty_terminal", inferior_io_terminal);
263 }
264
265 void 
266 _initialize_mi_cmd_env (void)
267 {
268   const char *env;
269
270   /* We want original execution path to reset to, if desired later.
271      At this point, current inferior is not created, so cannot use
272      current_inferior ()->environment.  We use getenv here because it
273      is not necessary to create a whole new gdb_environ just for one
274      variable.  */
275   env = getenv (path_var_name);
276
277   /* Can be null if path is not set.  */
278   if (!env)
279     env = "";
280   orig_path = xstrdup (env);
281 }