3 Copyright (C) 2011-2016 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 /* See documentation in cli-utils.h. */
29 get_number_trailer (const char **pp, int trailer)
31 int retval = 0; /* default */
36 struct value *val = value_from_history_ref (p, &p);
38 if (val) /* Value history reference */
40 if (TYPE_CODE (value_type (val)) == TYPE_CODE_INT)
41 retval = value_as_long (val);
44 printf_filtered (_("History value must have integer type.\n"));
48 else /* Convenience variable */
50 /* Internal variable. Make a copy of the name, so we can
51 null-terminate it to pass to lookup_internalvar(). */
53 const char *start = ++p;
56 while (isalnum (*p) || *p == '_')
58 varname = (char *) alloca (p - start + 1);
59 strncpy (varname, start, p - start);
60 varname[p - start] = '\0';
61 if (get_internalvar_integer (lookup_internalvar (varname), &val))
65 printf_filtered (_("Convenience variable must "
66 "have integer value.\n"));
75 while (*p >= '0' && *p <= '9')
78 /* There is no number here. (e.g. "cond a == b"). */
80 /* Skip non-numeric token. */
81 while (*p && !isspace((int) *p))
83 /* Return zero, which caller must interpret as error. */
89 if (!(isspace (*p) || *p == '\0' || *p == trailer))
91 /* Trailing junk: return 0 and let caller print error msg. */
92 while (!(isspace (*p) || *p == '\0' || *p == trailer))
96 p = skip_spaces_const (p);
101 /* See documentation in cli-utils.h. */
104 get_number_const (const char **pp)
106 return get_number_trailer (pp, '\0');
109 /* See documentation in cli-utils.h. */
112 get_number (char **pp)
117 result = get_number_trailer (&p, '\0');
122 /* See documentation in cli-utils.h. */
124 number_or_range_parser::number_or_range_parser (const char *string)
129 /* See documentation in cli-utils.h. */
132 number_or_range_parser::init (const char *string)
142 /* See documentation in cli-utils.h. */
145 number_or_range_parser::get_number ()
149 /* All number-parsing has already been done. Return the next
150 integer value (one greater than the saved previous value).
151 Do not advance the token pointer until the end of range is
154 if (++m_last_retval == m_end_value)
156 /* End of range reached; advance token pointer. */
157 m_cur_tok = m_end_ptr;
161 else if (*m_cur_tok != '-')
163 /* Default case: state->m_cur_tok is pointing either to a solo
164 number, or to the first number of a range. */
165 m_last_retval = get_number_trailer (&m_cur_tok, '-');
166 if (*m_cur_tok == '-')
170 /* This is the start of a range (<number1> - <number2>).
171 Skip the '-', parse and remember the second number,
172 and also remember the end of the final token. */
175 m_end_ptr = skip_spaces_const (m_cur_tok + 1);
176 m_end_value = get_number_const (temp);
177 if (m_end_value < m_last_retval)
179 error (_("inverted range"));
181 else if (m_end_value == m_last_retval)
183 /* Degenerate range (number1 == number2). Advance the
184 token pointer so that the range will be treated as a
186 m_cur_tok = m_end_ptr;
193 error (_("negative value"));
194 m_finished = *m_cur_tok == '\0';
195 return m_last_retval;
198 /* See documentation in cli-utils.h. */
201 number_or_range_parser::setup_range (int start_value, int end_value,
204 gdb_assert (start_value > 0);
208 m_last_retval = start_value - 1;
209 m_end_value = end_value;
212 /* Accept a number and a string-form list of numbers such as is
213 accepted by get_number_or_range. Return TRUE if the number is
216 By definition, an empty list includes all numbers. This is to
217 be interpreted as typing a command such as "delete break" with
221 number_is_in_list (const char *list, int number)
223 if (list == NULL || *list == '\0')
226 number_or_range_parser parser (list);
227 while (!parser.finished ())
229 int gotnum = parser.get_number ();
232 error (_("Args must be numbers or '$' variables."));
233 if (gotnum == number)
239 /* See documentation in cli-utils.h. */
242 remove_trailing_whitespace (const char *start, char *s)
244 while (s > start && isspace (*(s - 1)))
250 /* See documentation in cli-utils.h. */
253 extract_arg_const (const char **arg)
260 /* Find the start of the argument. */
261 *arg = skip_spaces_const (*arg);
266 /* Find the end of the argument. */
267 *arg = skip_to_space_const (*arg + 1);
272 return savestring (result, *arg - result);
275 /* See documentation in cli-utils.h. */
278 extract_arg (char **arg)
280 const char *arg_const = *arg;
283 result = extract_arg_const (&arg_const);
284 *arg += arg_const - *arg;
288 /* See documentation in cli-utils.h. */
291 check_for_argument (char **str, char *arg, int arg_len)
293 if (strncmp (*str, arg, arg_len) == 0
294 && ((*str)[arg_len] == '\0' || isspace ((*str)[arg_len])))