3 Copyright (C) 2011-2019 Free Software Foundation, Inc.
5 This file is part of GDB.
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 3 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "cli/cli-utils.h"
26 static std::string
extract_arg_maybe_quoted (const char **arg
);
28 /* See documentation in cli-utils.h. */
31 get_ulongest (const char **pp
, int trailer
)
33 LONGEST retval
= 0; /* default */
38 value
*val
= value_from_history_ref (p
, &p
);
40 if (val
!= NULL
) /* Value history reference */
42 if (TYPE_CODE (value_type (val
)) == TYPE_CODE_INT
)
43 retval
= value_as_long (val
);
45 error (_("History value must have integer type."));
47 else /* Convenience variable */
49 /* Internal variable. Make a copy of the name, so we can
50 null-terminate it to pass to lookup_internalvar(). */
51 const char *start
= ++p
;
52 while (isalnum (*p
) || *p
== '_')
54 std::string
varname (start
, p
- start
);
55 if (!get_internalvar_integer (lookup_internalvar (varname
.c_str ()),
57 error (_("Convenience variable $%s does not have integer value."),
63 retval
= strtoulst (p
, pp
, 0);
66 /* There is no number here. (e.g. "cond a == b"). */
67 error (_("Expected integer at: %s"), p
);
72 if (!(isspace (*p
) || *p
== '\0' || *p
== trailer
))
73 error (_("Trailing junk at: %s"), p
);
79 /* See documentation in cli-utils.h. */
82 get_number_trailer (const char **pp
, int trailer
)
84 int retval
= 0; /* default */
86 bool negative
= false;
96 struct value
*val
= value_from_history_ref (p
, &p
);
98 if (val
) /* Value history reference */
100 if (TYPE_CODE (value_type (val
)) == TYPE_CODE_INT
)
101 retval
= value_as_long (val
);
104 printf_filtered (_("History value must have integer type.\n"));
108 else /* Convenience variable */
110 /* Internal variable. Make a copy of the name, so we can
111 null-terminate it to pass to lookup_internalvar(). */
113 const char *start
= ++p
;
116 while (isalnum (*p
) || *p
== '_')
118 varname
= (char *) alloca (p
- start
+ 1);
119 strncpy (varname
, start
, p
- start
);
120 varname
[p
- start
] = '\0';
121 if (get_internalvar_integer (lookup_internalvar (varname
),
123 retval
= (int) longest_val
;
126 printf_filtered (_("Convenience variable must "
127 "have integer value.\n"));
135 while (*p
>= '0' && *p
<= '9')
138 /* There is no number here. (e.g. "cond a == b"). */
140 /* Skip non-numeric token. */
141 while (*p
&& !isspace((int) *p
))
143 /* Return zero, which caller must interpret as error. */
149 if (!(isspace (*p
) || *p
== '\0' || *p
== trailer
))
151 /* Trailing junk: return 0 and let caller print error msg. */
152 while (!(isspace (*p
) || *p
== '\0' || *p
== trailer
))
158 return negative
? -retval
: retval
;
161 /* See documentation in cli-utils.h. */
164 get_number (const char **pp
)
166 return get_number_trailer (pp
, '\0');
169 /* See documentation in cli-utils.h. */
172 get_number (char **pp
)
177 result
= get_number_trailer (&p
, '\0');
182 /* See documentation in cli-utils.h. */
185 extract_info_print_args (const char **args
,
188 std::string
*t_regexp
)
190 /* Check for NAMEREGEXP or -- NAMEREGEXP. */
191 if (**args
!= '-' || check_for_argument (args
, "--", 2))
198 if (check_for_argument (args
, "-t", 2))
200 *t_regexp
= extract_arg_maybe_quoted (args
);
201 *args
= skip_spaces (*args
);
205 if (check_for_argument (args
, "-q", 2))
214 /* See documentation in cli-utils.h. */
217 report_unrecognized_option_error (const char *command
, const char *args
)
219 std::string option
= extract_arg (&args
);
221 error (_("Unrecognized option '%s' to %s command. "
222 "Try \"help %s\"."), option
.c_str (),
226 /* See documentation in cli-utils.h. */
229 info_print_args_help (const char *prefix
,
230 const char *entity_kind
)
232 return xstrprintf (_("\
233 %sIf NAMEREGEXP is provided, only prints the %s whose name\n\
234 matches NAMEREGEXP.\n\
235 If -t TYPEREGEXP is provided, only prints the %s whose type\n\
236 matches TYPEREGEXP. Note that the matching is done with the type\n\
237 printed by the 'whatis' command.\n\
238 By default, the command might produce headers and/or messages indicating\n\
239 why no %s can be printed.\n\
240 The flag -q disables the production of these headers and messages."),
241 prefix
, entity_kind
, entity_kind
, entity_kind
);
244 /* See documentation in cli-utils.h. */
246 number_or_range_parser::number_or_range_parser (const char *string
)
251 /* See documentation in cli-utils.h. */
254 number_or_range_parser::init (const char *string
)
263 /* See documentation in cli-utils.h. */
266 number_or_range_parser::get_number ()
270 /* All number-parsing has already been done. Return the next
271 integer value (one greater than the saved previous value).
272 Do not advance the token pointer until the end of range is
275 if (++m_last_retval
== m_end_value
)
277 /* End of range reached; advance token pointer. */
278 m_cur_tok
= m_end_ptr
;
282 else if (*m_cur_tok
!= '-')
284 /* Default case: state->m_cur_tok is pointing either to a solo
285 number, or to the first number of a range. */
286 m_last_retval
= get_number_trailer (&m_cur_tok
, '-');
287 /* If get_number_trailer has found a '-' preceded by a space, it
288 might be the start of a command option. So, do not parse a
289 range if the '-' is followed by an alpha or another '-'. We
290 might also be completing something like
291 "frame apply level 0 -" and we prefer treating that "-" as an
292 option rather than an incomplete range, so check for end of
294 if (m_cur_tok
[0] == '-'
295 && !(isspace (m_cur_tok
[-1])
296 && (isalpha (m_cur_tok
[1])
297 || m_cur_tok
[1] == '-'
298 || m_cur_tok
[1] == '\0')))
302 /* This is the start of a range (<number1> - <number2>).
303 Skip the '-', parse and remember the second number,
304 and also remember the end of the final token. */
307 m_end_ptr
= skip_spaces (m_cur_tok
+ 1);
308 m_end_value
= ::get_number (temp
);
309 if (m_end_value
< m_last_retval
)
311 error (_("inverted range"));
313 else if (m_end_value
== m_last_retval
)
315 /* Degenerate range (number1 == number2). Advance the
316 token pointer so that the range will be treated as a
318 m_cur_tok
= m_end_ptr
;
326 if (isdigit (*(m_cur_tok
+ 1)))
327 error (_("negative value"));
328 if (*(m_cur_tok
+ 1) == '$')
330 /* Convenience variable. */
331 m_last_retval
= ::get_number (&m_cur_tok
);
332 if (m_last_retval
< 0)
333 error (_("negative value"));
336 return m_last_retval
;
339 /* See documentation in cli-utils.h. */
342 number_or_range_parser::setup_range (int start_value
, int end_value
,
345 gdb_assert (start_value
> 0);
349 m_last_retval
= start_value
- 1;
350 m_end_value
= end_value
;
353 /* See documentation in cli-utils.h. */
356 number_or_range_parser::finished () const
358 /* Parsing is finished when at end of string or null string,
359 or we are not in a range and not in front of an integer, negative
360 integer, convenience var or negative convenience var. */
361 return (m_cur_tok
== NULL
|| *m_cur_tok
== '\0'
363 && !(isdigit (*m_cur_tok
) || *m_cur_tok
== '$')
364 && !(*m_cur_tok
== '-'
365 && (isdigit (m_cur_tok
[1]) || m_cur_tok
[1] == '$'))));
368 /* Accept a number and a string-form list of numbers such as is
369 accepted by get_number_or_range. Return TRUE if the number is
372 By definition, an empty list includes all numbers. This is to
373 be interpreted as typing a command such as "delete break" with
377 number_is_in_list (const char *list
, int number
)
379 if (list
== NULL
|| *list
== '\0')
382 number_or_range_parser
parser (list
);
384 if (parser
.finished ())
385 error (_("Arguments must be numbers or '$' variables."));
386 while (!parser
.finished ())
388 int gotnum
= parser
.get_number ();
391 error (_("Arguments must be numbers or '$' variables."));
392 if (gotnum
== number
)
398 /* See documentation in cli-utils.h. */
401 remove_trailing_whitespace (const char *start
, const char *s
)
403 while (s
> start
&& isspace (*(s
- 1)))
409 /* A helper function to extract an argument from *ARG. An argument is
410 delimited by whitespace, but it can also be optionally quoted.
411 The quoting and special characters are handled similarly to
412 the parsing done by gdb_argv.
413 The return value is empty if no argument was found. */
416 extract_arg_maybe_quoted (const char **arg
)
420 bool bsquote
= false;
422 const char *p
= *arg
;
424 /* Find the start of the argument. */
427 /* Parse p similarly to gdb_argv buildargv function. */
430 if (isspace (*p
) && !squote
&& !dquote
&& !bsquote
)
472 /* See documentation in cli-utils.h. */
475 extract_arg (const char **arg
)
480 return std::string ();
482 /* Find the start of the argument. */
483 *arg
= skip_spaces (*arg
);
485 return std::string ();
488 /* Find the end of the argument. */
489 *arg
= skip_to_space (*arg
+ 1);
492 return std::string ();
494 return std::string (result
, *arg
- result
);
497 /* See documentation in cli-utils.h. */
500 extract_arg (char **arg
)
502 const char *arg_const
= *arg
;
505 result
= extract_arg (&arg_const
);
506 *arg
+= arg_const
- *arg
;
510 /* See documentation in cli-utils.h. */
513 check_for_argument (const char **str
, const char *arg
, int arg_len
)
515 if (strncmp (*str
, arg
, arg_len
) == 0
516 && ((*str
)[arg_len
] == '\0' || isspace ((*str
)[arg_len
])))
519 *str
= skip_spaces (*str
);
525 /* See documentation in cli-utils.h. */
528 validate_flags_qcs (const char *which_command
, qcs_flags
*flags
)
530 if (flags
->cont
&& flags
->silent
)
531 error (_("%s: -c and -s are mutually exclusive"), which_command
);
534 /* See documentation in cli-utils.h. */
This page took 0.072703 seconds and 4 git commands to generate.