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