Centralize thread ID printing
[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
26/* *PP is a string denoting a number. Get the number of the. Advance
27 *PP after the string and any trailing whitespace.
28
3bd0f5ef
MS
29 Currently the string can either be a number, or "$" followed by the
30 name of a convenience variable, or ("$" or "$$") followed by digits.
e9cafbcc
TT
31
32 TRAILER is a character which can be found after the number; most
33 commonly this is `-'. If you don't want a trailer, use \0. */
34
35static int
e799154c 36get_number_trailer (const char **pp, int trailer)
e9cafbcc
TT
37{
38 int retval = 0; /* default */
e799154c 39 const char *p = *pp;
e9cafbcc
TT
40
41 if (*p == '$')
42 {
3bd0f5ef 43 struct value *val = value_from_history_ref (p, &p);
e9cafbcc 44
3bd0f5ef 45 if (val) /* Value history reference */
e9cafbcc 46 {
3bd0f5ef
MS
47 if (TYPE_CODE (value_type (val)) == TYPE_CODE_INT)
48 retval = value_as_long (val);
49 else
50 {
2217da06 51 printf_filtered (_("History value must have integer type.\n"));
3bd0f5ef
MS
52 retval = 0;
53 }
54 }
55 else /* Convenience variable */
56 {
57 /* Internal variable. Make a copy of the name, so we can
58 null-terminate it to pass to lookup_internalvar(). */
59 char *varname;
e799154c 60 const char *start = ++p;
3bd0f5ef
MS
61 LONGEST val;
62
63 while (isalnum (*p) || *p == '_')
64 p++;
65 varname = (char *) alloca (p - start + 1);
66 strncpy (varname, start, p - start);
67 varname[p - start] = '\0';
68 if (get_internalvar_integer (lookup_internalvar (varname), &val))
69 retval = (int) val;
70 else
71 {
72 printf_filtered (_("Convenience variable must "
73 "have integer value.\n"));
74 retval = 0;
75 }
e9cafbcc
TT
76 }
77 }
78 else
79 {
80 if (*p == '-')
81 ++p;
82 while (*p >= '0' && *p <= '9')
83 ++p;
84 if (p == *pp)
85 /* There is no number here. (e.g. "cond a == b"). */
86 {
87 /* Skip non-numeric token. */
88 while (*p && !isspace((int) *p))
89 ++p;
90 /* Return zero, which caller must interpret as error. */
91 retval = 0;
92 }
93 else
94 retval = atoi (*pp);
95 }
96 if (!(isspace (*p) || *p == '\0' || *p == trailer))
97 {
98 /* Trailing junk: return 0 and let caller print error msg. */
99 while (!(isspace (*p) || *p == '\0' || *p == trailer))
100 ++p;
101 retval = 0;
102 }
e799154c 103 p = skip_spaces_const (p);
e9cafbcc
TT
104 *pp = p;
105 return retval;
106}
107
108/* See documentation in cli-utils.h. */
109
110int
e799154c 111get_number_const (const char **pp)
e9cafbcc
TT
112{
113 return get_number_trailer (pp, '\0');
114}
115
116/* See documentation in cli-utils.h. */
117
e799154c
TT
118int
119get_number (char **pp)
120{
121 int result;
122 const char *p = *pp;
123
124 result = get_number_trailer (&p, '\0');
125 *pp = (char *) p;
126 return result;
127}
128
129/* See documentation in cli-utils.h. */
130
197f0a60
TT
131void
132init_number_or_range (struct get_number_or_range_state *state,
e799154c 133 const char *string)
e9cafbcc 134{
197f0a60
TT
135 memset (state, 0, sizeof (*state));
136 state->string = string;
137}
138
139/* See documentation in cli-utils.h. */
e9cafbcc 140
197f0a60
TT
141int
142get_number_or_range (struct get_number_or_range_state *state)
143{
144 if (*state->string != '-')
e9cafbcc 145 {
197f0a60
TT
146 /* Default case: state->string is pointing either to a solo
147 number, or to the first number of a range. */
148 state->last_retval = get_number_trailer (&state->string, '-');
149 if (*state->string == '-')
e9cafbcc 150 {
e799154c 151 const char **temp;
e9cafbcc
TT
152
153 /* This is the start of a range (<number1> - <number2>).
154 Skip the '-', parse and remember the second number,
155 and also remember the end of the final token. */
156
197f0a60 157 temp = &state->end_ptr;
e799154c
TT
158 state->end_ptr = skip_spaces_const (state->string + 1);
159 state->end_value = get_number_const (temp);
197f0a60 160 if (state->end_value < state->last_retval)
e9cafbcc
TT
161 {
162 error (_("inverted range"));
163 }
197f0a60 164 else if (state->end_value == state->last_retval)
e9cafbcc
TT
165 {
166 /* Degenerate range (number1 == number2). Advance the
167 token pointer so that the range will be treated as a
168 single number. */
197f0a60 169 state->string = state->end_ptr;
e9cafbcc
TT
170 }
171 else
197f0a60 172 state->in_range = 1;
e9cafbcc
TT
173 }
174 }
197f0a60 175 else if (! state->in_range)
e9cafbcc
TT
176 error (_("negative value"));
177 else
178 {
197f0a60 179 /* state->string points to the '-' that betokens a range. All
e9cafbcc
TT
180 number-parsing has already been done. Return the next
181 integer value (one greater than the saved previous value).
197f0a60 182 Do not advance the token pointer until the end of range
e9cafbcc
TT
183 is reached. */
184
197f0a60 185 if (++state->last_retval == state->end_value)
e9cafbcc
TT
186 {
187 /* End of range reached; advance token pointer. */
197f0a60
TT
188 state->string = state->end_ptr;
189 state->in_range = 0;
e9cafbcc
TT
190 }
191 }
197f0a60
TT
192 state->finished = *state->string == '\0';
193 return state->last_retval;
e9cafbcc
TT
194}
195
aea5b279
MS
196/* Accept a number and a string-form list of numbers such as is
197 accepted by get_number_or_range. Return TRUE if the number is
198 in the list.
199
200 By definition, an empty list includes all numbers. This is to
201 be interpreted as typing a command such as "delete break" with
202 no arguments. */
203
204int
e799154c 205number_is_in_list (const char *list, int number)
aea5b279 206{
197f0a60
TT
207 struct get_number_or_range_state state;
208
aea5b279
MS
209 if (list == NULL || *list == '\0')
210 return 1;
211
197f0a60
TT
212 init_number_or_range (&state, list);
213 while (!state.finished)
298f437a 214 {
197f0a60 215 int gotnum = get_number_or_range (&state);
aea5b279 216
298f437a
MS
217 if (gotnum == 0)
218 error (_("Args must be numbers or '$' variables."));
219 if (gotnum == number)
220 return 1;
221 }
aea5b279
MS
222 return 0;
223}
224
e9cafbcc
TT
225/* See documentation in cli-utils.h. */
226
c00f8484
KS
227char *
228remove_trailing_whitespace (const char *start, char *s)
229{
230 while (s > start && isspace (*(s - 1)))
231 --s;
232
233 return s;
234}
55aa24fb
SDJ
235
236/* See documentation in cli-utils.h. */
237
238char *
b5be8ce0 239extract_arg_const (const char **arg)
55aa24fb 240{
b5be8ce0 241 const char *result;
55aa24fb
SDJ
242
243 if (!*arg)
244 return NULL;
245
246 /* Find the start of the argument. */
b5be8ce0 247 *arg = skip_spaces_const (*arg);
55aa24fb
SDJ
248 if (!**arg)
249 return NULL;
250 result = *arg;
251
252 /* Find the end of the argument. */
b5be8ce0 253 *arg = skip_to_space_const (*arg + 1);
55aa24fb
SDJ
254
255 if (result == *arg)
256 return NULL;
257
b5be8ce0
JB
258 return savestring (result, *arg - result);
259}
260
261/* See documentation in cli-utils.h. */
262
263char *
264extract_arg (char **arg)
265{
266 const char *arg_const = *arg;
267 char *result;
55aa24fb 268
b5be8ce0
JB
269 result = extract_arg_const (&arg_const);
270 *arg += arg_const - *arg;
271 return result;
55aa24fb 272}
e6f0bce7
HZ
273
274/* See documentation in cli-utils.h. */
275
276int
277check_for_argument (char **str, char *arg, int arg_len)
278{
279 if (strncmp (*str, arg, arg_len) == 0
280 && ((*str)[arg_len] == '\0' || isspace ((*str)[arg_len])))
281 {
282 *str += arg_len;
283 return 1;
284 }
285 return 0;
286}
This page took 0.353435 seconds and 4 git commands to generate.