]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/mi/mi-cmd-env.c
gdb: make string-like set show commands use std::string variable
[thirdparty/binutils-gdb.git] / gdb / mi / mi-cmd-env.c
CommitLineData
068890be 1/* MI Command Set - environment commands.
3666a048 2 Copyright (C) 2002-2021 Free Software Foundation, Inc.
1bac305b 3
068890be
JJ
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
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
068890be
JJ
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
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
068890be 20
068890be
JJ
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"
268a13a5 29#include "gdbsupport/environ.h"
068890be
JJ
30#include "command.h"
31#include "ui-out.h"
32#include "top.h"
53ce3c39 33#include <sys/stat.h>
b46a8d7c 34#include "source.h"
4ef3f3be 35
068890be
JJ
36static const char path_var_name[] = "PATH";
37static char *orig_path = NULL;
38
d303380b
AC
39/* The following is copied from mi-main.c so for m1 and below we can
40 perform old behavior and use cli commands. If ARGS is non-null,
41 append it to the CMD. */
2b03b41d 42
068890be 43static void
d303380b 44env_execute_cli_command (const char *cmd, const char *args)
068890be 45{
d303380b 46 if (cmd != 0)
068890be 47 {
e91a1fa7 48 gdb::unique_xmalloc_ptr<char> run;
102040f0 49
d303380b 50 if (args != NULL)
e91a1fa7 51 run.reset (xstrprintf ("%s %s", cmd, args));
d303380b 52 else
e91a1fa7
TT
53 run.reset (xstrdup (cmd));
54 execute_command ( /*ui */ run.get (), 0 /*from_tty */ );
068890be
JJ
55 }
56}
57
068890be 58/* Print working directory. */
2b03b41d 59
ce8f13f8 60void
9f33b8b7 61mi_cmd_env_pwd (const char *command, char **argv, int argc)
068890be 62{
79a45e25
PA
63 struct ui_out *uiout = current_uiout;
64
068890be 65 if (argc > 0)
2b03b41d 66 error (_("-environment-pwd: No arguments allowed"));
dda83cd7 67
068890be
JJ
68 if (mi_version (uiout) < 2)
69 {
70 env_execute_cli_command ("pwd", NULL);
ce8f13f8 71 return;
068890be
JJ
72 }
73
74 /* Otherwise the mi level is 2 or higher. */
75
43573013
SDJ
76 gdb::unique_xmalloc_ptr<char> cwd (getcwd (NULL, 0));
77 if (cwd == NULL)
1b05df00 78 error (_("-environment-pwd: error finding name of working directory: %s"),
dda83cd7 79 safe_strerror (errno));
43573013
SDJ
80
81 uiout->field_string ("cwd", cwd.get ());
068890be
JJ
82}
83
84/* Change working directory. */
2b03b41d 85
ce8f13f8 86void
9f33b8b7 87mi_cmd_env_cd (const char *command, char **argv, int argc)
068890be
JJ
88{
89 if (argc == 0 || argc > 1)
1b05df00 90 error (_("-environment-cd: Usage DIRECTORY"));
dda83cd7 91
d303380b 92 env_execute_cli_command ("cd", argv[0]);
068890be
JJ
93}
94
95static void
e0700ba4 96env_mod_path (const char *dirname, std::string &which_path)
068890be
JJ
97{
98 if (dirname == 0 || dirname[0] == '\0')
99 return;
100
101 /* Call add_path with last arg 0 to indicate not to parse for
102 separator characters. */
103 add_path (dirname, which_path, 0);
104}
105
106/* Add one or more directories to start of executable search path. */
2b03b41d 107
ce8f13f8 108void
9f33b8b7 109mi_cmd_env_path (const char *command, char **argv, int argc)
068890be 110{
79a45e25 111 struct ui_out *uiout = current_uiout;
a121b7c1 112 const char *env;
068890be 113 int reset = 0;
7082409d 114 int oind = 0;
068890be 115 int i;
7082409d 116 char *oarg;
068890be
JJ
117 enum opt
118 {
119 RESET_OPT
120 };
91174723 121 static const struct mi_opt opts[] =
068890be
JJ
122 {
123 {"r", RESET_OPT, 0},
d5d6fca5 124 { 0, 0, 0 }
068890be
JJ
125 };
126
127 dont_repeat ();
128
129 if (mi_version (uiout) < 2)
130 {
131 for (i = argc - 1; i >= 0; --i)
d303380b 132 env_execute_cli_command ("path", argv[i]);
ce8f13f8 133 return;
068890be
JJ
134 }
135
136 /* Otherwise the mi level is 2 or higher. */
137 while (1)
138 {
1b05df00 139 int opt = mi_getopt ("-environment-path", argc, argv, opts,
dda83cd7 140 &oind, &oarg);
102040f0 141
068890be 142 if (opt < 0)
dda83cd7 143 break;
068890be 144 switch ((enum opt) opt)
dda83cd7
SM
145 {
146 case RESET_OPT:
147 reset = 1;
148 break;
149 }
068890be 150 }
7082409d
AS
151 argv += oind;
152 argc -= oind;
068890be 153
e0700ba4 154 std::string exec_path;
068890be
JJ
155 if (reset)
156 {
157 /* Reset implies resetting to original path first. */
e0700ba4 158 exec_path = orig_path;
068890be
JJ
159 }
160 else
161 {
162 /* Otherwise, get current path to modify. */
9a6c7d9c 163 env = current_inferior ()->environment.get (path_var_name);
068890be
JJ
164
165 /* Can be null if path is not set. */
166 if (!env)
dda83cd7 167 env = "";
e0700ba4
SM
168
169 exec_path = env;
068890be
JJ
170 }
171
172 for (i = argc - 1; i >= 0; --i)
e0700ba4 173 env_mod_path (argv[i], exec_path);
068890be 174
e0700ba4 175 current_inferior ()->environment.set (path_var_name, exec_path.c_str ());
9a6c7d9c 176 env = current_inferior ()->environment.get (path_var_name);
112e8700 177 uiout->field_string ("path", env);
068890be
JJ
178}
179
180/* Add zero or more directories to the front of the source path. */
2b03b41d 181
ce8f13f8 182void
9f33b8b7 183mi_cmd_env_dir (const char *command, char **argv, int argc)
068890be 184{
79a45e25 185 struct ui_out *uiout = current_uiout;
068890be 186 int i;
7082409d 187 int oind = 0;
068890be 188 int reset = 0;
7082409d 189 char *oarg;
068890be
JJ
190 enum opt
191 {
192 RESET_OPT
193 };
91174723 194 static const struct mi_opt opts[] =
068890be
JJ
195 {
196 {"r", RESET_OPT, 0},
d5d6fca5 197 { 0, 0, 0 }
068890be
JJ
198 };
199
200 dont_repeat ();
201
202 if (mi_version (uiout) < 2)
203 {
204 for (i = argc - 1; i >= 0; --i)
d303380b 205 env_execute_cli_command ("dir", argv[i]);
ce8f13f8 206 return;
068890be
JJ
207 }
208
209 /* Otherwise mi level is 2 or higher. */
210 while (1)
211 {
1b05df00 212 int opt = mi_getopt ("-environment-directory", argc, argv, opts,
dda83cd7 213 &oind, &oarg);
102040f0 214
068890be 215 if (opt < 0)
dda83cd7 216 break;
068890be 217 switch ((enum opt) opt)
dda83cd7
SM
218 {
219 case RESET_OPT:
220 reset = 1;
221 break;
222 }
068890be 223 }
7082409d
AS
224 argv += oind;
225 argc -= oind;
068890be
JJ
226
227 if (reset)
228 {
229 /* Reset means setting to default path first. */
068890be
JJ
230 init_source_path ();
231 }
232
233 for (i = argc - 1; i >= 0; --i)
e0700ba4 234 env_mod_path (argv[i], source_path);
068890be 235
112e8700 236 uiout->field_string ("source-path", source_path);
068890be 237 forget_cached_source_info ();
068890be
JJ
238}
239
3cb3b8df 240/* Set the inferior terminal device name. */
2b03b41d 241
ce8f13f8 242void
9f33b8b7 243mi_cmd_inferior_tty_set (const char *command, char **argv, int argc)
3cb3b8df 244{
4e93ea6e
SM
245 if (argc > 0)
246 current_inferior ()->set_tty (argv[0]);
247 else
248 current_inferior ()->set_tty ("");
3cb3b8df
BR
249}
250
2b03b41d
SS
251/* Print the inferior terminal device name. */
252
ce8f13f8 253void
9f33b8b7 254mi_cmd_inferior_tty_show (const char *command, char **argv, int argc)
3cb3b8df 255{
1b05df00
TT
256 if ( !mi_valid_noargs ("-inferior-tty-show", argc, argv))
257 error (_("-inferior-tty-show: Usage: No args"));
3cb3b8df 258
4e93ea6e
SM
259 const std::string &inferior_tty = current_inferior ()->tty ();
260 if (!inferior_tty.empty ())
05779d57 261 current_uiout->field_string ("inferior_tty_terminal", inferior_tty);
3cb3b8df
BR
262}
263
6c265988 264void _initialize_mi_cmd_env ();
068890be 265void
6c265988 266_initialize_mi_cmd_env ()
068890be 267{
a121b7c1 268 const char *env;
068890be 269
3f81c18a
VP
270 /* We want original execution path to reset to, if desired later.
271 At this point, current inferior is not created, so cannot use
1c8e01c9
SDJ
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);
068890be
JJ
276
277 /* Can be null if path is not set. */
278 if (!env)
279 env = "";
280 orig_path = xstrdup (env);
281}