don't share per-BFD data if relocations are needed
[deliverable/binutils-gdb.git] / gdb / mi / mi-parse.c
CommitLineData
fb40c209 1/* MI Command Set - MI parser.
349c5d5f 2
28e7fd62 3 Copyright (C) 2000-2013 Free Software Foundation, Inc.
349c5d5f 4
ab91fdd5 5 Contributed by Cygnus Solutions (a Red Hat company).
fb40c209
AC
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
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
fb40c209
AC
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
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
fb40c209
AC
21
22#include "defs.h"
23#include "mi-cmds.h"
24#include "mi-parse.h"
f870a310 25#include "charset.h"
fb40c209
AC
26
27#include <ctype.h>
27b82ed2 28#include "gdb_string.h"
529480d0 29#include "cli/cli-utils.h"
fb40c209 30
44d100c3
TT
31static const char mi_no_values[] = "--no-values";
32static const char mi_simple_values[] = "--simple-values";
33static const char mi_all_values[] = "--all-values";
87967e27 34
f870a310
TT
35/* Like parse_escape, but leave the results as a host char, not a
36 target char. */
37
38static int
ee047554 39mi_parse_escape (const char **string_ptr)
f870a310
TT
40{
41 int c = *(*string_ptr)++;
102040f0 42
f870a310
TT
43 switch (c)
44 {
45 case '\n':
46 return -2;
47 case 0:
48 (*string_ptr)--;
49 return 0;
50
51 case '0':
52 case '1':
53 case '2':
54 case '3':
55 case '4':
56 case '5':
57 case '6':
58 case '7':
59 {
60 int i = host_hex_value (c);
61 int count = 0;
102040f0 62
f870a310
TT
63 while (++count < 3)
64 {
65 c = (**string_ptr);
66 if (isdigit (c) && c != '8' && c != '9')
67 {
68 (*string_ptr)++;
69 i *= 8;
70 i += host_hex_value (c);
71 }
72 else
73 {
74 break;
75 }
76 }
77 return i;
78 }
79
80 case 'a':
81 c = '\a';
82 break;
83 case 'b':
84 c = '\b';
85 break;
86 case 'f':
87 c = '\f';
88 break;
89 case 'n':
90 c = '\n';
91 break;
92 case 'r':
93 c = '\r';
94 break;
95 case 't':
96 c = '\t';
97 break;
98 case 'v':
99 c = '\v';
100 break;
101
102 default:
103 break;
104 }
105
106 return c;
107}
108
fb40c209 109static void
ee047554 110mi_parse_argv (const char *args, struct mi_parse *parse)
fb40c209 111{
ee047554 112 const char *chp = args;
fb40c209
AC
113 int argc = 0;
114 char **argv = xmalloc ((argc + 1) * sizeof (char *));
102040f0 115
fb40c209
AC
116 argv[argc] = NULL;
117 while (1)
118 {
119 char *arg;
102040f0 120
2b03b41d 121 /* Skip leading white space. */
ee047554 122 chp = skip_spaces_const (chp);
fb40c209
AC
123 /* Three possibilities: EOF, quoted string, or other text. */
124 switch (*chp)
125 {
126 case '\0':
127 parse->argv = argv;
128 parse->argc = argc;
129 return;
130 case '"':
131 {
2b03b41d 132 /* A quoted string. */
fb40c209 133 int len;
ee047554 134 const char *start = chp + 1;
102040f0 135
2b03b41d 136 /* Determine the buffer size. */
fb40c209
AC
137 chp = start;
138 len = 0;
139 while (*chp != '\0' && *chp != '"')
140 {
141 if (*chp == '\\')
142 {
143 chp++;
f870a310 144 if (mi_parse_escape (&chp) <= 0)
fb40c209 145 {
2b03b41d 146 /* Do not allow split lines or "\000". */
fb40c209
AC
147 freeargv (argv);
148 return;
149 }
150 }
151 else
152 chp++;
153 len++;
154 }
2b03b41d 155 /* Insist on a closing quote. */
fb40c209
AC
156 if (*chp != '"')
157 {
158 freeargv (argv);
159 return;
160 }
2b03b41d 161 /* Insist on trailing white space. */
fb40c209
AC
162 if (chp[1] != '\0' && !isspace (chp[1]))
163 {
164 freeargv (argv);
165 return;
166 }
2b03b41d 167 /* Create the buffer and copy characters in. */
fb40c209 168 arg = xmalloc ((len + 1) * sizeof (char));
fb40c209
AC
169 chp = start;
170 len = 0;
171 while (*chp != '\0' && *chp != '"')
172 {
173 if (*chp == '\\')
174 {
175 chp++;
f870a310 176 arg[len] = mi_parse_escape (&chp);
fb40c209
AC
177 }
178 else
179 arg[len] = *chp++;
180 len++;
181 }
182 arg[len] = '\0';
2b03b41d 183 chp++; /* That closing quote. */
fb40c209
AC
184 break;
185 }
186 default:
187 {
2b03b41d
SS
188 /* An unquoted string. Accumulate all non-blank
189 characters into a buffer. */
fb40c209 190 int len;
ee047554 191 const char *start = chp;
102040f0 192
fb40c209
AC
193 while (*chp != '\0' && !isspace (*chp))
194 {
195 chp++;
196 }
197 len = chp - start;
198 arg = xmalloc ((len + 1) * sizeof (char));
199 strncpy (arg, start, len);
200 arg[len] = '\0';
201 break;
202 }
203 }
2b03b41d 204 /* Append arg to argv. */
fb40c209
AC
205 argv = xrealloc (argv, (argc + 2) * sizeof (char *));
206 argv[argc++] = arg;
207 argv[argc] = NULL;
208 }
209}
210
fb40c209
AC
211void
212mi_parse_free (struct mi_parse *parse)
213{
214 if (parse == NULL)
215 return;
216 if (parse->command != NULL)
b8c9b27d 217 xfree (parse->command);
fb40c209 218 if (parse->token != NULL)
b8c9b27d 219 xfree (parse->token);
fb40c209 220 if (parse->args != NULL)
b8c9b27d 221 xfree (parse->args);
fb40c209
AC
222 if (parse->argv != NULL)
223 freeargv (parse->argv);
b8c9b27d 224 xfree (parse);
fb40c209
AC
225}
226
305aeedc
TT
227/* A cleanup that calls mi_parse_free. */
228
229static void
230mi_parse_cleanup (void *arg)
231{
232 mi_parse_free (arg);
233}
fb40c209
AC
234
235struct mi_parse *
ee047554 236mi_parse (const char *cmd, char **token)
fb40c209 237{
ee047554 238 const char *chp;
fb40c209 239 struct mi_parse *parse = XMALLOC (struct mi_parse);
305aeedc 240 struct cleanup *cleanup;
102040f0 241
fb40c209 242 memset (parse, 0, sizeof (*parse));
a79b8f6e
VP
243 parse->all = 0;
244 parse->thread_group = -1;
1e92afda
VP
245 parse->thread = -1;
246 parse->frame = -1;
fb40c209 247
305aeedc
TT
248 cleanup = make_cleanup (mi_parse_cleanup, parse);
249
2b03b41d 250 /* Before starting, skip leading white space. */
ee047554 251 cmd = skip_spaces_const (cmd);
fb40c209 252
2b03b41d 253 /* Find/skip any token and then extract it. */
fb40c209
AC
254 for (chp = cmd; *chp >= '0' && *chp <= '9'; chp++)
255 ;
38a714bb 256 *token = xmalloc (chp - cmd + 1);
305aeedc
TT
257 memcpy (*token, cmd, (chp - cmd));
258 (*token)[chp - cmd] = '\0';
fb40c209 259
2b03b41d 260 /* This wasn't a real MI command. Return it as a CLI_COMMAND. */
fb40c209
AC
261 if (*chp != '-')
262 {
ee047554 263 chp = skip_spaces_const (chp);
fb40c209
AC
264 parse->command = xstrdup (chp);
265 parse->op = CLI_COMMAND;
305aeedc
TT
266
267 discard_cleanups (cleanup);
268
fb40c209
AC
269 return parse;
270 }
271
2b03b41d 272 /* Extract the command. */
fb40c209 273 {
ee047554 274 const char *tmp = chp + 1; /* discard ``-'' */
102040f0 275
fb40c209
AC
276 for (; *chp && !isspace (*chp); chp++)
277 ;
38a714bb 278 parse->command = xmalloc (chp - tmp + 1);
fb40c209
AC
279 memcpy (parse->command, tmp, chp - tmp);
280 parse->command[chp - tmp] = '\0';
281 }
282
2b03b41d 283 /* Find the command in the MI table. */
fb40c209
AC
284 parse->cmd = mi_lookup (parse->command);
285 if (parse->cmd == NULL)
305aeedc 286 error (_("Undefined MI command: %s"), parse->command);
fb40c209 287
2b03b41d 288 /* Skip white space following the command. */
ee047554 289 chp = skip_spaces_const (chp);
fb40c209 290
1e92afda 291 /* Parse the --thread and --frame options, if present. At present,
2b03b41d
SS
292 some important commands, like '-break-*' are implemented by
293 forwarding to the CLI layer directly. We want to parse --thread
294 and --frame here, so as not to leave those option in the string
295 that will be passed to CLI. */
1e92afda
VP
296 for (;;)
297 {
30a7f059 298 const char *option;
a79b8f6e
VP
299 size_t as = sizeof ("--all ") - 1;
300 size_t tgs = sizeof ("--thread-group ") - 1;
1e92afda
VP
301 size_t ts = sizeof ("--thread ") - 1;
302 size_t fs = sizeof ("--frame ") - 1;
102040f0 303
a79b8f6e
VP
304 if (strncmp (chp, "--all ", as) == 0)
305 {
306 parse->all = 1;
307 chp += as;
308 }
309 /* See if --all is the last token in the input. */
310 if (strcmp (chp, "--all") == 0)
311 {
312 parse->all = 1;
313 chp += strlen (chp);
314 }
315 if (strncmp (chp, "--thread-group ", tgs) == 0)
316 {
ee047554
KS
317 char *endp;
318
30a7f059 319 option = "--thread-group";
a79b8f6e
VP
320 if (parse->thread_group != -1)
321 error (_("Duplicate '--thread-group' option"));
322 chp += tgs;
323 if (*chp != 'i')
324 error (_("Invalid thread group id"));
325 chp += 1;
ee047554
KS
326 parse->thread_group = strtol (chp, &endp, 10);
327 chp = endp;
a79b8f6e 328 }
8e0e408a 329 else if (strncmp (chp, "--thread ", ts) == 0)
1e92afda 330 {
ee047554
KS
331 char *endp;
332
30a7f059 333 option = "--thread";
1e92afda 334 if (parse->thread != -1)
a79b8f6e 335 error (_("Duplicate '--thread' option"));
1e92afda 336 chp += ts;
ee047554
KS
337 parse->thread = strtol (chp, &endp, 10);
338 chp = endp;
1e92afda
VP
339 }
340 else if (strncmp (chp, "--frame ", fs) == 0)
341 {
ee047554
KS
342 char *endp;
343
30a7f059 344 option = "--frame";
1e92afda 345 if (parse->frame != -1)
a79b8f6e 346 error (_("Duplicate '--frame' option"));
1e92afda 347 chp += fs;
ee047554
KS
348 parse->frame = strtol (chp, &endp, 10);
349 chp = endp;
1e92afda
VP
350 }
351 else
352 break;
353
354 if (*chp != '\0' && !isspace (*chp))
30a7f059 355 error (_("Invalid value for the '%s' option"), option);
ee047554 356 chp = skip_spaces_const (chp);
1e92afda
VP
357 }
358
fb40c209 359 /* For new argv commands, attempt to return the parsed argument
2b03b41d 360 list. */
fb40c209
AC
361 if (parse->cmd->argv_func != NULL)
362 {
363 mi_parse_argv (chp, parse);
364 if (parse->argv == NULL)
305aeedc 365 error (_("Problem parsing arguments: %s %s"), parse->command, chp);
fb40c209
AC
366 }
367
368 /* FIXME: DELETE THIS */
9e22b03a 369 /* For CLI commands, also return the remainder of the
fb40c209 370 command line as a single string. */
9e22b03a
VP
371 if (parse->cmd->cli.cmd != NULL)
372 parse->args = xstrdup (chp);
fb40c209 373
305aeedc
TT
374 discard_cleanups (cleanup);
375
2b03b41d 376 /* Fully parsed, flag as an MI command. */
fb40c209
AC
377 parse->op = MI_COMMAND;
378 return parse;
379}
87967e27
YQ
380
381enum print_values
382mi_parse_print_values (const char *name)
383{
384 if (strcmp (name, "0") == 0
385 || strcmp (name, mi_no_values) == 0)
386 return PRINT_NO_VALUES;
387 else if (strcmp (name, "1") == 0
388 || strcmp (name, mi_all_values) == 0)
389 return PRINT_ALL_VALUES;
390 else if (strcmp (name, "2") == 0
391 || strcmp (name, mi_simple_values) == 0)
392 return PRINT_SIMPLE_VALUES;
393 else
394 error (_("Unknown value for PRINT_VALUES: must be: \
3950 or \"%s\", 1 or \"%s\", 2 or \"%s\""),
396 mi_no_values, mi_all_values, mi_simple_values);
397}
This page took 1.569043 seconds and 4 git commands to generate.