[AArch64] PR target/20666, fix wrong encoding of new introduced BFC pseudo
[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
197f0a60
TT
124void
125init_number_or_range (struct get_number_or_range_state *state,
e799154c 126 const char *string)
e9cafbcc 127{
197f0a60
TT
128 memset (state, 0, sizeof (*state));
129 state->string = string;
130}
131
132/* See documentation in cli-utils.h. */
e9cafbcc 133
197f0a60
TT
134int
135get_number_or_range (struct get_number_or_range_state *state)
136{
71ef29a8
PA
137 if (state->in_range)
138 {
139 /* All number-parsing has already been done. Return the next
140 integer value (one greater than the saved previous value).
141 Do not advance the token pointer until the end of range is
142 reached. */
143
144 if (++state->last_retval == state->end_value)
145 {
146 /* End of range reached; advance token pointer. */
147 state->string = state->end_ptr;
148 state->in_range = 0;
149 }
150 }
151 else if (*state->string != '-')
e9cafbcc 152 {
197f0a60
TT
153 /* Default case: state->string is pointing either to a solo
154 number, or to the first number of a range. */
155 state->last_retval = get_number_trailer (&state->string, '-');
156 if (*state->string == '-')
e9cafbcc 157 {
e799154c 158 const char **temp;
e9cafbcc
TT
159
160 /* This is the start of a range (<number1> - <number2>).
161 Skip the '-', parse and remember the second number,
162 and also remember the end of the final token. */
163
197f0a60 164 temp = &state->end_ptr;
e799154c
TT
165 state->end_ptr = skip_spaces_const (state->string + 1);
166 state->end_value = get_number_const (temp);
197f0a60 167 if (state->end_value < state->last_retval)
e9cafbcc
TT
168 {
169 error (_("inverted range"));
170 }
197f0a60 171 else if (state->end_value == state->last_retval)
e9cafbcc
TT
172 {
173 /* Degenerate range (number1 == number2). Advance the
174 token pointer so that the range will be treated as a
175 single number. */
197f0a60 176 state->string = state->end_ptr;
e9cafbcc
TT
177 }
178 else
197f0a60 179 state->in_range = 1;
e9cafbcc
TT
180 }
181 }
e9cafbcc 182 else
71ef29a8 183 error (_("negative value"));
197f0a60
TT
184 state->finished = *state->string == '\0';
185 return state->last_retval;
e9cafbcc
TT
186}
187
71ef29a8
PA
188/* See documentation in cli-utils.h. */
189
190void
191number_range_setup_range (struct get_number_or_range_state *state,
192 int start_value, int end_value, const char *end_ptr)
193{
194 gdb_assert (start_value > 0);
195
196 state->in_range = 1;
197 state->end_ptr = end_ptr;
198 state->last_retval = start_value - 1;
199 state->end_value = end_value;
200}
201
aea5b279
MS
202/* Accept a number and a string-form list of numbers such as is
203 accepted by get_number_or_range. Return TRUE if the number is
204 in the list.
205
206 By definition, an empty list includes all numbers. This is to
207 be interpreted as typing a command such as "delete break" with
208 no arguments. */
209
210int
e799154c 211number_is_in_list (const char *list, int number)
aea5b279 212{
197f0a60
TT
213 struct get_number_or_range_state state;
214
aea5b279
MS
215 if (list == NULL || *list == '\0')
216 return 1;
217
197f0a60
TT
218 init_number_or_range (&state, list);
219 while (!state.finished)
298f437a 220 {
197f0a60 221 int gotnum = get_number_or_range (&state);
aea5b279 222
298f437a
MS
223 if (gotnum == 0)
224 error (_("Args must be numbers or '$' variables."));
225 if (gotnum == number)
226 return 1;
227 }
aea5b279
MS
228 return 0;
229}
230
e9cafbcc
TT
231/* See documentation in cli-utils.h. */
232
c00f8484
KS
233char *
234remove_trailing_whitespace (const char *start, char *s)
235{
236 while (s > start && isspace (*(s - 1)))
237 --s;
238
239 return s;
240}
55aa24fb
SDJ
241
242/* See documentation in cli-utils.h. */
243
244char *
b5be8ce0 245extract_arg_const (const char **arg)
55aa24fb 246{
b5be8ce0 247 const char *result;
55aa24fb
SDJ
248
249 if (!*arg)
250 return NULL;
251
252 /* Find the start of the argument. */
b5be8ce0 253 *arg = skip_spaces_const (*arg);
55aa24fb
SDJ
254 if (!**arg)
255 return NULL;
256 result = *arg;
257
258 /* Find the end of the argument. */
b5be8ce0 259 *arg = skip_to_space_const (*arg + 1);
55aa24fb
SDJ
260
261 if (result == *arg)
262 return NULL;
263
b5be8ce0
JB
264 return savestring (result, *arg - result);
265}
266
267/* See documentation in cli-utils.h. */
268
269char *
270extract_arg (char **arg)
271{
272 const char *arg_const = *arg;
273 char *result;
55aa24fb 274
b5be8ce0
JB
275 result = extract_arg_const (&arg_const);
276 *arg += arg_const - *arg;
277 return result;
55aa24fb 278}
e6f0bce7
HZ
279
280/* See documentation in cli-utils.h. */
281
282int
283check_for_argument (char **str, char *arg, int arg_len)
284{
285 if (strncmp (*str, arg, arg_len) == 0
286 && ((*str)[arg_len] == '\0' || isspace ((*str)[arg_len])))
287 {
288 *str += arg_len;
289 return 1;
290 }
291 return 0;
292}
This page took 0.389357 seconds and 4 git commands to generate.