Convert tid_range_parser and get_number_or_range to classes
[deliverable/binutils-gdb.git] / gdb / cli / cli-utils.c
CommitLineData
e9cafbcc
TT
1/* CLI utilities.
2
618f726f 3 Copyright (C) 2011-2016 Free Software Foundation, Inc.
e9cafbcc
TT
4
5 This file is part of GDB.
6
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.
11
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.
16
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/>. */
19
20#include "defs.h"
21#include "cli/cli-utils.h"
e9cafbcc
TT
22#include "value.h"
23
24#include <ctype.h>
25
5d5658a1 26/* See documentation in cli-utils.h. */
e9cafbcc 27
5d5658a1 28int
e799154c 29get_number_trailer (const char **pp, int trailer)
e9cafbcc
TT
30{
31 int retval = 0; /* default */
e799154c 32 const char *p = *pp;
e9cafbcc
TT
33
34 if (*p == '$')
35 {
3bd0f5ef 36 struct value *val = value_from_history_ref (p, &p);
e9cafbcc 37
3bd0f5ef 38 if (val) /* Value history reference */
e9cafbcc 39 {
3bd0f5ef
MS
40 if (TYPE_CODE (value_type (val)) == TYPE_CODE_INT)
41 retval = value_as_long (val);
42 else
43 {
2217da06 44 printf_filtered (_("History value must have integer type.\n"));
3bd0f5ef
MS
45 retval = 0;
46 }
47 }
48 else /* Convenience variable */
49 {
50 /* Internal variable. Make a copy of the name, so we can
51 null-terminate it to pass to lookup_internalvar(). */
52 char *varname;
e799154c 53 const char *start = ++p;
3bd0f5ef
MS
54 LONGEST val;
55
56 while (isalnum (*p) || *p == '_')
57 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))
62 retval = (int) val;
63 else
64 {
65 printf_filtered (_("Convenience variable must "
66 "have integer value.\n"));
67 retval = 0;
68 }
e9cafbcc
TT
69 }
70 }
71 else
72 {
73 if (*p == '-')
74 ++p;
75 while (*p >= '0' && *p <= '9')
76 ++p;
77 if (p == *pp)
78 /* There is no number here. (e.g. "cond a == b"). */
79 {
80 /* Skip non-numeric token. */
81 while (*p && !isspace((int) *p))
82 ++p;
83 /* Return zero, which caller must interpret as error. */
84 retval = 0;
85 }
86 else
87 retval = atoi (*pp);
88 }
89 if (!(isspace (*p) || *p == '\0' || *p == trailer))
90 {
91 /* Trailing junk: return 0 and let caller print error msg. */
92 while (!(isspace (*p) || *p == '\0' || *p == trailer))
93 ++p;
94 retval = 0;
95 }
e799154c 96 p = skip_spaces_const (p);
e9cafbcc
TT
97 *pp = p;
98 return retval;
99}
100
101/* See documentation in cli-utils.h. */
102
103int
e799154c 104get_number_const (const char **pp)
e9cafbcc
TT
105{
106 return get_number_trailer (pp, '\0');
107}
108
109/* See documentation in cli-utils.h. */
110
e799154c
TT
111int
112get_number (char **pp)
113{
114 int result;
115 const char *p = *pp;
116
117 result = get_number_trailer (&p, '\0');
118 *pp = (char *) p;
119 return result;
120}
121
122/* See documentation in cli-utils.h. */
123
bfd28288
PA
124number_or_range_parser::number_or_range_parser (const char *string)
125{
126 init (string);
127}
128
129/* See documentation in cli-utils.h. */
130
197f0a60 131void
bfd28288 132number_or_range_parser::init (const char *string)
e9cafbcc 133{
bfd28288
PA
134 m_finished = false;
135 m_cur_tok = string;
136 m_last_retval = 0;
137 m_end_value = 0;
138 m_end_ptr = NULL;
139 m_in_range = false;
197f0a60
TT
140}
141
142/* See documentation in cli-utils.h. */
e9cafbcc 143
197f0a60 144int
bfd28288 145number_or_range_parser::get_number ()
197f0a60 146{
bfd28288 147 if (m_in_range)
71ef29a8
PA
148 {
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
152 reached. */
153
bfd28288 154 if (++m_last_retval == m_end_value)
71ef29a8
PA
155 {
156 /* End of range reached; advance token pointer. */
bfd28288
PA
157 m_cur_tok = m_end_ptr;
158 m_in_range = false;
71ef29a8
PA
159 }
160 }
bfd28288 161 else if (*m_cur_tok != '-')
e9cafbcc 162 {
bfd28288 163 /* Default case: state->m_cur_tok is pointing either to a solo
197f0a60 164 number, or to the first number of a range. */
bfd28288
PA
165 m_last_retval = get_number_trailer (&m_cur_tok, '-');
166 if (*m_cur_tok == '-')
e9cafbcc 167 {
e799154c 168 const char **temp;
e9cafbcc
TT
169
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. */
173
bfd28288
PA
174 temp = &m_end_ptr;
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)
e9cafbcc
TT
178 {
179 error (_("inverted range"));
180 }
bfd28288 181 else if (m_end_value == m_last_retval)
e9cafbcc
TT
182 {
183 /* Degenerate range (number1 == number2). Advance the
184 token pointer so that the range will be treated as a
bfd28288
PA
185 single number. */
186 m_cur_tok = m_end_ptr;
e9cafbcc
TT
187 }
188 else
bfd28288 189 m_in_range = true;
e9cafbcc
TT
190 }
191 }
e9cafbcc 192 else
71ef29a8 193 error (_("negative value"));
bfd28288
PA
194 m_finished = *m_cur_tok == '\0';
195 return m_last_retval;
e9cafbcc
TT
196}
197
71ef29a8
PA
198/* See documentation in cli-utils.h. */
199
200void
bfd28288
PA
201number_or_range_parser::setup_range (int start_value, int end_value,
202 const char *end_ptr)
71ef29a8
PA
203{
204 gdb_assert (start_value > 0);
205
bfd28288
PA
206 m_in_range = true;
207 m_end_ptr = end_ptr;
208 m_last_retval = start_value - 1;
209 m_end_value = end_value;
71ef29a8
PA
210}
211
aea5b279
MS
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
214 in the list.
215
216 By definition, an empty list includes all numbers. This is to
217 be interpreted as typing a command such as "delete break" with
218 no arguments. */
219
220int
e799154c 221number_is_in_list (const char *list, int number)
aea5b279
MS
222{
223 if (list == NULL || *list == '\0')
224 return 1;
225
bfd28288
PA
226 number_or_range_parser parser (list);
227 while (!parser.finished ())
298f437a 228 {
bfd28288 229 int gotnum = parser.get_number ();
aea5b279 230
298f437a
MS
231 if (gotnum == 0)
232 error (_("Args must be numbers or '$' variables."));
233 if (gotnum == number)
234 return 1;
235 }
aea5b279
MS
236 return 0;
237}
238
e9cafbcc
TT
239/* See documentation in cli-utils.h. */
240
c00f8484
KS
241char *
242remove_trailing_whitespace (const char *start, char *s)
243{
244 while (s > start && isspace (*(s - 1)))
245 --s;
246
247 return s;
248}
55aa24fb
SDJ
249
250/* See documentation in cli-utils.h. */
251
252char *
b5be8ce0 253extract_arg_const (const char **arg)
55aa24fb 254{
b5be8ce0 255 const char *result;
55aa24fb
SDJ
256
257 if (!*arg)
258 return NULL;
259
260 /* Find the start of the argument. */
b5be8ce0 261 *arg = skip_spaces_const (*arg);
55aa24fb
SDJ
262 if (!**arg)
263 return NULL;
264 result = *arg;
265
266 /* Find the end of the argument. */
b5be8ce0 267 *arg = skip_to_space_const (*arg + 1);
55aa24fb
SDJ
268
269 if (result == *arg)
270 return NULL;
271
b5be8ce0
JB
272 return savestring (result, *arg - result);
273}
274
275/* See documentation in cli-utils.h. */
276
277char *
278extract_arg (char **arg)
279{
280 const char *arg_const = *arg;
281 char *result;
55aa24fb 282
b5be8ce0
JB
283 result = extract_arg_const (&arg_const);
284 *arg += arg_const - *arg;
285 return result;
55aa24fb 286}
e6f0bce7
HZ
287
288/* See documentation in cli-utils.h. */
289
290int
291check_for_argument (char **str, char *arg, int arg_len)
292{
293 if (strncmp (*str, arg, arg_len) == 0
294 && ((*str)[arg_len] == '\0' || isspace ((*str)[arg_len])))
295 {
296 *str += arg_len;
297 return 1;
298 }
299 return 0;
300}
This page took 0.396237 seconds and 4 git commands to generate.