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