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."),
64 retval
= strtoulst (p
, &end
, 0);
67 /* There is no number here. (e.g. "cond a == b"). */
68 error (_("Expected integer at: %s"), p
);
73 if (!(isspace (*p
) || *p
== '\0' || *p
== trailer
))
74 error (_("Trailing junk at: %s"), p
);
80 /* See documentation in cli-utils.h. */
83 get_number_trailer (const char **pp
, int trailer
)
85 int retval
= 0; /* default */
87 bool negative
= false;
97 struct value
*val
= value_from_history_ref (p
, &p
);
99 if (val
) /* Value history reference */
101 if (TYPE_CODE (value_type (val
)) == TYPE_CODE_INT
)
102 retval
= value_as_long (val
);
105 printf_filtered (_("History value must have integer type.\n"));
109 else /* Convenience variable */
111 /* Internal variable. Make a copy of the name, so we can
112 null-terminate it to pass to lookup_internalvar(). */
114 const char *start
= ++p
;
117 while (isalnum (*p
) || *p
== '_')
119 varname
= (char *) alloca (p
- start
+ 1);
120 strncpy (varname
, start
, p
- start
);
121 varname
[p
- start
] = '\0';
122 if (get_internalvar_integer (lookup_internalvar (varname
),
124 retval
= (int) longest_val
;
127 printf_filtered (_("Convenience variable must "
128 "have integer value.\n"));
136 while (*p
>= '0' && *p
<= '9')
139 /* There is no number here. (e.g. "cond a == b"). */
141 /* Skip non-numeric token. */
142 while (*p
&& !isspace((int) *p
))
144 /* Return zero, which caller must interpret as error. */
150 if (!(isspace (*p
) || *p
== '\0' || *p
== trailer
))
152 /* Trailing junk: return 0 and let caller print error msg. */
153 while (!(isspace (*p
) || *p
== '\0' || *p
== trailer
))
159 return negative
? -retval
: retval
;
162 /* See documentation in cli-utils.h. */
165 get_number (const char **pp
)
167 return get_number_trailer (pp
, '\0');
170 /* See documentation in cli-utils.h. */
173 get_number (char **pp
)
178 result
= get_number_trailer (&p
, '\0');
183 /* See documentation in cli-utils.h. */
186 extract_info_print_args (const char **args
,
189 std::string
*t_regexp
)
191 /* Check for NAMEREGEXP or -- NAMEREGEXP. */
192 if (**args
!= '-' || check_for_argument (args
, "--", 2))
199 if (check_for_argument (args
, "-t", 2))
201 *t_regexp
= extract_arg_maybe_quoted (args
);
202 *args
= skip_spaces (*args
);
206 if (check_for_argument (args
, "-q", 2))
215 /* See documentation in cli-utils.h. */
218 report_unrecognized_option_error (const char *command
, const char *args
)
220 std::string option
= extract_arg (&args
);
222 error (_("Unrecognized option '%s' to %s command. "
223 "Try \"help %s\"."), option
.c_str (),
227 /* See documentation in cli-utils.h. */
230 info_print_args_help (const char *prefix
,
231 const char *entity_kind
)
233 return xstrprintf (_("\
234 %sIf NAMEREGEXP is provided, only prints the %s whose name\n\
235 matches NAMEREGEXP.\n\
236 If -t TYPEREGEXP is provided, only prints the %s whose type\n\
237 matches TYPEREGEXP. Note that the matching is done with the type\n\
238 printed by the 'whatis' command.\n\
239 By default, the command might produce headers and/or messages indicating\n\
240 why no %s can be printed.\n\
241 The flag -q disables the production of these headers and messages."),
242 prefix
, entity_kind
, entity_kind
, entity_kind
);
245 /* See documentation in cli-utils.h. */
247 number_or_range_parser::number_or_range_parser (const char *string
)
252 /* See documentation in cli-utils.h. */
255 number_or_range_parser::init (const char *string
)
264 /* See documentation in cli-utils.h. */
267 number_or_range_parser::get_number ()
271 /* All number-parsing has already been done. Return the next
272 integer value (one greater than the saved previous value).
273 Do not advance the token pointer until the end of range is
276 if (++m_last_retval
== m_end_value
)
278 /* End of range reached; advance token pointer. */
279 m_cur_tok
= m_end_ptr
;
283 else if (*m_cur_tok
!= '-')
285 /* Default case: state->m_cur_tok is pointing either to a solo
286 number, or to the first number of a range. */
287 m_last_retval
= get_number_trailer (&m_cur_tok
, '-');
288 /* If get_number_trailer has found a '-' preceded by a space, it
289 might be the start of a command option. So, do not parse a
290 range if the '-' is followed by an alpha or another '-'. We
291 might also be completing something like
292 "frame apply level 0 -" and we prefer treating that "-" as an
293 option rather than an incomplete range, so check for end of
295 if (m_cur_tok
[0] == '-'
296 && !(isspace (m_cur_tok
[-1])
297 && (isalpha (m_cur_tok
[1])
298 || m_cur_tok
[1] == '-'
299 || m_cur_tok
[1] == '\0')))
303 /* This is the start of a range (<number1> - <number2>).
304 Skip the '-', parse and remember the second number,
305 and also remember the end of the final token. */
308 m_end_ptr
= skip_spaces (m_cur_tok
+ 1);
309 m_end_value
= ::get_number (temp
);
310 if (m_end_value
< m_last_retval
)
312 error (_("inverted range"));
314 else if (m_end_value
== m_last_retval
)
316 /* Degenerate range (number1 == number2). Advance the
317 token pointer so that the range will be treated as a
319 m_cur_tok
= m_end_ptr
;
327 if (isdigit (*(m_cur_tok
+ 1)))
328 error (_("negative value"));
329 if (*(m_cur_tok
+ 1) == '$')
331 /* Convenience variable. */
332 m_last_retval
= ::get_number (&m_cur_tok
);
333 if (m_last_retval
< 0)
334 error (_("negative value"));
337 return m_last_retval
;
340 /* See documentation in cli-utils.h. */
343 number_or_range_parser::setup_range (int start_value
, int end_value
,
346 gdb_assert (start_value
> 0);
350 m_last_retval
= start_value
- 1;
351 m_end_value
= end_value
;
354 /* See documentation in cli-utils.h. */
357 number_or_range_parser::finished () const
359 /* Parsing is finished when at end of string or null string,
360 or we are not in a range and not in front of an integer, negative
361 integer, convenience var or negative convenience var. */
362 return (m_cur_tok
== NULL
|| *m_cur_tok
== '\0'
364 && !(isdigit (*m_cur_tok
) || *m_cur_tok
== '$')
365 && !(*m_cur_tok
== '-'
366 && (isdigit (m_cur_tok
[1]) || m_cur_tok
[1] == '$'))));
369 /* Accept a number and a string-form list of numbers such as is
370 accepted by get_number_or_range. Return TRUE if the number is
373 By definition, an empty list includes all numbers. This is to
374 be interpreted as typing a command such as "delete break" with
378 number_is_in_list (const char *list
, int number
)
380 if (list
== NULL
|| *list
== '\0')
383 number_or_range_parser
parser (list
);
385 if (parser
.finished ())
386 error (_("Arguments must be numbers or '$' variables."));
387 while (!parser
.finished ())
389 int gotnum
= parser
.get_number ();
392 error (_("Arguments must be numbers or '$' variables."));
393 if (gotnum
== number
)
399 /* See documentation in cli-utils.h. */
402 remove_trailing_whitespace (const char *start
, const char *s
)
404 while (s
> start
&& isspace (*(s
- 1)))
410 /* A helper function to extract an argument from *ARG. An argument is
411 delimited by whitespace, but it can also be optionally quoted.
412 The quoting and special characters are handled similarly to
413 the parsing done by gdb_argv.
414 The return value is empty if no argument was found. */
417 extract_arg_maybe_quoted (const char **arg
)
421 bool bsquote
= false;
423 const char *p
= *arg
;
425 /* Find the start of the argument. */
428 /* Parse p similarly to gdb_argv buildargv function. */
431 if (isspace (*p
) && !squote
&& !dquote
&& !bsquote
)
473 /* See documentation in cli-utils.h. */
476 extract_arg (const char **arg
)
481 return std::string ();
483 /* Find the start of the argument. */
484 *arg
= skip_spaces (*arg
);
486 return std::string ();
489 /* Find the end of the argument. */
490 *arg
= skip_to_space (*arg
+ 1);
493 return std::string ();
495 return std::string (result
, *arg
- result
);
498 /* See documentation in cli-utils.h. */
501 extract_arg (char **arg
)
503 const char *arg_const
= *arg
;
506 result
= extract_arg (&arg_const
);
507 *arg
+= arg_const
- *arg
;
511 /* See documentation in cli-utils.h. */
514 check_for_argument (const char **str
, const char *arg
, int arg_len
)
516 if (strncmp (*str
, arg
, arg_len
) == 0
517 && ((*str
)[arg_len
] == '\0' || isspace ((*str
)[arg_len
])))
520 *str
= skip_spaces (*str
);
526 /* See documentation in cli-utils.h. */
529 validate_flags_qcs (const char *which_command
, qcs_flags
*flags
)
531 if (flags
->cont
&& flags
->silent
)
532 error (_("%s: -c and -s are mutually exclusive"), which_command
);
535 /* See documentation in cli-utils.h. */
This page took 0.041258 seconds and 4 git commands to generate.