23296cee9c33169412674b53d0b049f868d77dda
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_number_trailer (const char **pp
, int trailer
)
33 int retval
= 0; /* default */
35 bool negative
= false;
45 struct value
*val
= value_from_history_ref (p
, &p
);
47 if (val
) /* Value history reference */
49 if (TYPE_CODE (value_type (val
)) == TYPE_CODE_INT
)
50 retval
= value_as_long (val
);
53 printf_filtered (_("History value must have integer type.\n"));
57 else /* Convenience variable */
59 /* Internal variable. Make a copy of the name, so we can
60 null-terminate it to pass to lookup_internalvar(). */
62 const char *start
= ++p
;
65 while (isalnum (*p
) || *p
== '_')
67 varname
= (char *) alloca (p
- start
+ 1);
68 strncpy (varname
, start
, p
- start
);
69 varname
[p
- start
] = '\0';
70 if (get_internalvar_integer (lookup_internalvar (varname
),
72 retval
= (int) longest_val
;
75 printf_filtered (_("Convenience variable must "
76 "have integer value.\n"));
84 while (*p
>= '0' && *p
<= '9')
87 /* There is no number here. (e.g. "cond a == b"). */
89 /* Skip non-numeric token. */
90 while (*p
&& !isspace((int) *p
))
92 /* Return zero, which caller must interpret as error. */
98 if (!(isspace (*p
) || *p
== '\0' || *p
== trailer
))
100 /* Trailing junk: return 0 and let caller print error msg. */
101 while (!(isspace (*p
) || *p
== '\0' || *p
== trailer
))
107 return negative
? -retval
: retval
;
110 /* See documentation in cli-utils.h. */
113 get_number (const char **pp
)
115 return get_number_trailer (pp
, '\0');
118 /* See documentation in cli-utils.h. */
121 get_number (char **pp
)
126 result
= get_number_trailer (&p
, '\0');
131 /* See documentation in cli-utils.h. */
134 extract_info_print_args (const char **args
,
137 std::string
*t_regexp
)
139 /* Check for NAMEREGEXP or -- NAMEREGEXP. */
140 if (**args
!= '-' || check_for_argument (args
, "--", 2))
147 if (check_for_argument (args
, "-t", 2))
149 *t_regexp
= extract_arg_maybe_quoted (args
);
150 *args
= skip_spaces (*args
);
154 if (check_for_argument (args
, "-q", 2))
163 /* See documentation in cli-utils.h. */
166 report_unrecognized_option_error (const char *command
, const char *args
)
168 std::string option
= extract_arg (&args
);
170 error (_("Unrecognized option '%s' to %s command. "
171 "Try \"help %s\"."), option
.c_str (),
175 /* See documentation in cli-utils.h. */
178 info_print_args_help (const char *prefix
,
179 const char *entity_kind
)
181 return xstrprintf (_("\
182 %sIf NAMEREGEXP is provided, only prints the %s whose name\n\
183 matches NAMEREGEXP.\n\
184 If -t TYPEREGEXP is provided, only prints the %s whose type\n\
185 matches TYPEREGEXP. Note that the matching is done with the type\n\
186 printed by the 'whatis' command.\n\
187 By default, the command might produce headers and/or messages indicating\n\
188 why no %s can be printed.\n\
189 The flag -q disables the production of these headers and messages."),
190 prefix
, entity_kind
, entity_kind
, entity_kind
);
193 /* See documentation in cli-utils.h. */
195 number_or_range_parser::number_or_range_parser (const char *string
)
200 /* See documentation in cli-utils.h. */
203 number_or_range_parser::init (const char *string
)
212 /* See documentation in cli-utils.h. */
215 number_or_range_parser::get_number ()
219 /* All number-parsing has already been done. Return the next
220 integer value (one greater than the saved previous value).
221 Do not advance the token pointer until the end of range is
224 if (++m_last_retval
== m_end_value
)
226 /* End of range reached; advance token pointer. */
227 m_cur_tok
= m_end_ptr
;
231 else if (*m_cur_tok
!= '-')
233 /* Default case: state->m_cur_tok is pointing either to a solo
234 number, or to the first number of a range. */
235 m_last_retval
= get_number_trailer (&m_cur_tok
, '-');
236 /* If get_number_trailer has found a '-' preceded by a space, it
237 might be the start of a command option. So, do not parse a
238 range if the '-' is followed by an alpha or another '-'. We
239 might also be completing something like
240 "frame apply level 0 -" and we prefer treating that "-" as an
241 option rather than an incomplete range, so check for end of
243 if (m_cur_tok
[0] == '-'
244 && !(isspace (m_cur_tok
[-1])
245 && (isalpha (m_cur_tok
[1])
246 || m_cur_tok
[1] == '-'
247 || m_cur_tok
[1] == '\0')))
251 /* This is the start of a range (<number1> - <number2>).
252 Skip the '-', parse and remember the second number,
253 and also remember the end of the final token. */
256 m_end_ptr
= skip_spaces (m_cur_tok
+ 1);
257 m_end_value
= ::get_number (temp
);
258 if (m_end_value
< m_last_retval
)
260 error (_("inverted range"));
262 else if (m_end_value
== m_last_retval
)
264 /* Degenerate range (number1 == number2). Advance the
265 token pointer so that the range will be treated as a
267 m_cur_tok
= m_end_ptr
;
275 if (isdigit (*(m_cur_tok
+ 1)))
276 error (_("negative value"));
277 if (*(m_cur_tok
+ 1) == '$')
279 /* Convenience variable. */
280 m_last_retval
= ::get_number (&m_cur_tok
);
281 if (m_last_retval
< 0)
282 error (_("negative value"));
285 return m_last_retval
;
288 /* See documentation in cli-utils.h. */
291 number_or_range_parser::setup_range (int start_value
, int end_value
,
294 gdb_assert (start_value
> 0);
298 m_last_retval
= start_value
- 1;
299 m_end_value
= end_value
;
302 /* See documentation in cli-utils.h. */
305 number_or_range_parser::finished () const
307 /* Parsing is finished when at end of string or null string,
308 or we are not in a range and not in front of an integer, negative
309 integer, convenience var or negative convenience var. */
310 return (m_cur_tok
== NULL
|| *m_cur_tok
== '\0'
312 && !(isdigit (*m_cur_tok
) || *m_cur_tok
== '$')
313 && !(*m_cur_tok
== '-'
314 && (isdigit (m_cur_tok
[1]) || m_cur_tok
[1] == '$'))));
317 /* Accept a number and a string-form list of numbers such as is
318 accepted by get_number_or_range. Return TRUE if the number is
321 By definition, an empty list includes all numbers. This is to
322 be interpreted as typing a command such as "delete break" with
326 number_is_in_list (const char *list
, int number
)
328 if (list
== NULL
|| *list
== '\0')
331 number_or_range_parser
parser (list
);
333 if (parser
.finished ())
334 error (_("Arguments must be numbers or '$' variables."));
335 while (!parser
.finished ())
337 int gotnum
= parser
.get_number ();
340 error (_("Arguments must be numbers or '$' variables."));
341 if (gotnum
== number
)
347 /* See documentation in cli-utils.h. */
350 remove_trailing_whitespace (const char *start
, const char *s
)
352 while (s
> start
&& isspace (*(s
- 1)))
358 /* A helper function to extract an argument from *ARG. An argument is
359 delimited by whitespace, but it can also be optionally quoted.
360 The quoting and special characters are handled similarly to
361 the parsing done by gdb_argv.
362 The return value is empty if no argument was found. */
365 extract_arg_maybe_quoted (const char **arg
)
369 bool bsquote
= false;
371 const char *p
= *arg
;
373 /* Find the start of the argument. */
376 /* Parse p similarly to gdb_argv buildargv function. */
379 if (isspace (*p
) && !squote
&& !dquote
&& !bsquote
)
421 /* See documentation in cli-utils.h. */
424 extract_arg (const char **arg
)
429 return std::string ();
431 /* Find the start of the argument. */
432 *arg
= skip_spaces (*arg
);
434 return std::string ();
437 /* Find the end of the argument. */
438 *arg
= skip_to_space (*arg
+ 1);
441 return std::string ();
443 return std::string (result
, *arg
- result
);
446 /* See documentation in cli-utils.h. */
449 extract_arg (char **arg
)
451 const char *arg_const
= *arg
;
454 result
= extract_arg (&arg_const
);
455 *arg
+= arg_const
- *arg
;
459 /* See documentation in cli-utils.h. */
462 check_for_argument (const char **str
, const char *arg
, int arg_len
)
464 if (strncmp (*str
, arg
, arg_len
) == 0
465 && ((*str
)[arg_len
] == '\0' || isspace ((*str
)[arg_len
])))
468 *str
= skip_spaces (*str
);
474 /* See documentation in cli-utils.h. */
477 parse_flags (const char **str
, const char *flags
)
479 const char *p
= skip_spaces (*str
);
483 && (p
[2] == '\0' || isspace (p
[2])))
485 const char pf
= p
[1];
486 const char *f
= flags
;
492 *str
= skip_spaces (p
+ 2);
493 return f
- flags
+ 1;
502 /* See documentation in cli-utils.h. */
505 parse_flags_qcs (const char *which_command
, const char **str
,
508 switch (parse_flags (str
, "qcs"))
519 flags
->silent
= true;
522 gdb_assert_not_reached ("int qcs flag out of bound");
525 if (flags
->cont
&& flags
->silent
)
526 error (_("%s: -c and -s are mutually exclusive"), which_command
);
This page took 0.042634 seconds and 3 git commands to generate.