2003-01-13 Andrew Cagney <ac131313@redhat.com>
[platform/upstream/binutils.git] / gdb / mi / mi-cmd-env.c
1 /* MI Command Set - environment commands.
2
3    Copyright 2002, 2003 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 <sys/stat.h>
39
40 static void env_cli_command (const char *cli, char *args);
41 static void env_mod_path (char *dirname, char **which_path);
42 extern void _initialize_mi_cmd_env (void);
43
44 static const char path_var_name[] = "PATH";
45 static char *orig_path = NULL;
46
47 /* The following is copied from mi-main.c so for m1 and below we
48    can perform old behavior and use cli commands.  */
49 static void
50 env_execute_cli_command (const char *cli, char *args)
51 {
52   if (cli != 0)
53     {
54       struct cleanup *old_cleanups;
55       char *run;
56       xasprintf (&run, cli, args);
57       old_cleanups = make_cleanup (xfree, run);
58       execute_command ( /*ui */ run, 0 /*from_tty */ );
59       do_cleanups (old_cleanups);
60       return;
61     }
62 }
63
64
65 /* Print working directory.  */
66 enum mi_cmd_result
67 mi_cmd_env_pwd (char *command, char **argv, int argc)
68 {
69   if (argc > 0)
70     error ("mi_cmd_env_pwd: No arguments required");
71           
72   if (mi_version (uiout) < 2)
73     {
74       env_execute_cli_command ("pwd", NULL);
75       return MI_CMD_DONE;
76     }
77      
78   /* Otherwise the mi level is 2 or higher.  */
79
80   getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
81   ui_out_field_string (uiout, "cwd", gdb_dirbuf);
82
83   return MI_CMD_DONE;
84 }
85
86 /* Change working directory.  */
87 enum mi_cmd_result
88 mi_cmd_env_cd (char *command, char **argv, int argc)
89 {
90   if (argc == 0 || argc > 1)
91     error ("mi_cmd_env_cd: Usage DIRECTORY");
92           
93   env_execute_cli_command ("cd %s", argv[0]);
94
95   return MI_CMD_DONE;
96 }
97
98 static void
99 env_mod_path (char *dirname, char **which_path)
100 {
101   if (dirname == 0 || dirname[0] == '\0')
102     return;
103
104   /* Call add_path with last arg 0 to indicate not to parse for 
105      separator characters.  */
106   add_path (dirname, which_path, 0);
107 }
108
109 /* Add one or more directories to start of executable search path.  */
110 enum mi_cmd_result
111 mi_cmd_env_path (char *command, char **argv, int argc)
112 {
113   char *exec_path;
114   char *env;
115   int reset = 0;
116   int optind = 0;
117   int i;
118   char *optarg;
119   enum opt
120     {
121       RESET_OPT
122     };
123   static struct mi_opt opts[] =
124   {
125     {"r", RESET_OPT, 0},
126     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 %s", argv[i]);
135       return MI_CMD_DONE;
136     }
137
138   /* Otherwise the mi level is 2 or higher.  */
139   while (1)
140     {
141       int opt = mi_getopt ("mi_cmd_env_path", argc, argv, opts,
142                            &optind, &optarg);
143       if (opt < 0)
144         break;
145       switch ((enum opt) opt)
146         {
147         case RESET_OPT:
148           reset = 1;
149           break;
150         }
151     }
152   argv += optind;
153   argc -= optind;
154
155
156   if (reset)
157     {
158       /* Reset implies resetting to original path first.  */
159       exec_path = xstrdup (orig_path);
160     }
161   else
162     {
163       /* Otherwise, get current path to modify.  */
164       env = get_in_environ (inferior_environ, path_var_name);
165
166       /* Can be null if path is not set.  */
167       if (!env)
168         env = "";
169       exec_path = xstrdup (env);
170     }
171
172   for (i = argc - 1; i >= 0; --i)
173     env_mod_path (argv[i], &exec_path);
174
175   set_in_environ (inferior_environ, path_var_name, exec_path);
176   xfree (exec_path);
177   env = get_in_environ (inferior_environ, path_var_name);
178   ui_out_field_string (uiout, "path", env);
179
180   return MI_CMD_DONE;
181 }
182
183 /* Add zero or more directories to the front of the source path.  */
184 enum mi_cmd_result
185 mi_cmd_env_dir (char *command, char **argv, int argc)
186 {
187   int i;
188   int optind = 0;
189   int reset = 0;
190   char *optarg;
191   enum opt
192     {
193       RESET_OPT
194     };
195   static struct mi_opt opts[] =
196   {
197     {"r", RESET_OPT, 0},
198     0
199   };
200
201   dont_repeat ();
202
203   if (mi_version (uiout) < 2)
204     {
205       for (i = argc - 1; i >= 0; --i)
206         env_execute_cli_command ("dir %s", argv[i]);
207       return MI_CMD_DONE;
208     }
209
210   /* Otherwise mi level is 2 or higher.  */
211   while (1)
212     {
213       int opt = mi_getopt ("mi_cmd_env_dir", argc, argv, opts,
214                            &optind, &optarg);
215       if (opt < 0)
216         break;
217       switch ((enum opt) opt)
218         {
219         case RESET_OPT:
220           reset = 1;
221           break;
222         }
223     }
224   argv += optind;
225   argc -= optind;
226
227   if (reset)
228     {
229       /* Reset means setting to default path first.  */
230       xfree (source_path);
231       init_source_path ();
232     }
233
234   for (i = argc - 1; i >= 0; --i)
235     env_mod_path (argv[i], &source_path);
236   init_last_source_visited ();
237
238   ui_out_field_string (uiout, "source-path", source_path);
239   forget_cached_source_info ();
240
241   return MI_CMD_DONE;
242 }
243
244 void 
245 _initialize_mi_cmd_env (void)
246 {
247   char *env;
248
249   /* We want original execution path to reset to, if desired later.  */
250   env = get_in_environ (inferior_environ, path_var_name);
251
252   /* Can be null if path is not set.  */
253   if (!env)
254     env = "";
255   orig_path = xstrdup (env);
256 }