2011-02-24 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / cli / cli-utils.c
CommitLineData
e9cafbcc
TT
1/* CLI utilities.
2
3 Copyright (c) 2011 Free Software Foundation, Inc.
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"
22#include "gdb_string.h"
23#include "value.h"
3bd0f5ef 24#include "gdb_assert.h"
e9cafbcc
TT
25
26#include <ctype.h>
27
28/* *PP is a string denoting a number. Get the number of the. Advance
29 *PP after the string and any trailing whitespace.
30
3bd0f5ef
MS
31 Currently the string can either be a number, or "$" followed by the
32 name of a convenience variable, or ("$" or "$$") followed by digits.
e9cafbcc
TT
33
34 TRAILER is a character which can be found after the number; most
35 commonly this is `-'. If you don't want a trailer, use \0. */
36
37static int
38get_number_trailer (char **pp, int trailer)
39{
40 int retval = 0; /* default */
41 char *p = *pp;
42
43 if (*p == '$')
44 {
3bd0f5ef 45 struct value *val = value_from_history_ref (p, &p);
e9cafbcc 46
3bd0f5ef 47 if (val) /* Value history reference */
e9cafbcc 48 {
3bd0f5ef
MS
49 if (TYPE_CODE (value_type (val)) == TYPE_CODE_INT)
50 retval = value_as_long (val);
51 else
52 {
53 printf_filtered (_("History value must have integer type."));
54 retval = 0;
55 }
56 }
57 else /* Convenience variable */
58 {
59 /* Internal variable. Make a copy of the name, so we can
60 null-terminate it to pass to lookup_internalvar(). */
61 char *varname;
62 char *start = ++p;
63 LONGEST val;
64
65 while (isalnum (*p) || *p == '_')
66 p++;
67 varname = (char *) alloca (p - start + 1);
68 strncpy (varname, start, p - start);
69 varname[p - start] = '\0';
70 if (get_internalvar_integer (lookup_internalvar (varname), &val))
71 retval = (int) val;
72 else
73 {
74 printf_filtered (_("Convenience variable must "
75 "have integer value.\n"));
76 retval = 0;
77 }
e9cafbcc
TT
78 }
79 }
80 else
81 {
82 if (*p == '-')
83 ++p;
84 while (*p >= '0' && *p <= '9')
85 ++p;
86 if (p == *pp)
87 /* There is no number here. (e.g. "cond a == b"). */
88 {
89 /* Skip non-numeric token. */
90 while (*p && !isspace((int) *p))
91 ++p;
92 /* Return zero, which caller must interpret as error. */
93 retval = 0;
94 }
95 else
96 retval = atoi (*pp);
97 }
98 if (!(isspace (*p) || *p == '\0' || *p == trailer))
99 {
100 /* Trailing junk: return 0 and let caller print error msg. */
101 while (!(isspace (*p) || *p == '\0' || *p == trailer))
102 ++p;
103 retval = 0;
104 }
105 p = skip_spaces (p);
106 *pp = p;
107 return retval;
108}
109
110/* See documentation in cli-utils.h. */
111
112int
113get_number (char **pp)
114{
115 return get_number_trailer (pp, '\0');
116}
117
118/* See documentation in cli-utils.h. */
119
120int
121get_number_or_range (char **pp)
122{
123 static int last_retval, end_value;
124 static char *end_ptr;
125 static int in_range = 0;
126
127 if (**pp != '-')
128 {
129 /* Default case: pp is pointing either to a solo number,
130 or to the first number of a range. */
131 last_retval = get_number_trailer (pp, '-');
132 if (**pp == '-')
133 {
134 char **temp;
135
136 /* This is the start of a range (<number1> - <number2>).
137 Skip the '-', parse and remember the second number,
138 and also remember the end of the final token. */
139
140 temp = &end_ptr;
141 end_ptr = *pp + 1;
142 while (isspace ((int) *end_ptr))
143 end_ptr++; /* skip white space */
144 end_value = get_number (temp);
145 if (end_value < last_retval)
146 {
147 error (_("inverted range"));
148 }
149 else if (end_value == last_retval)
150 {
151 /* Degenerate range (number1 == number2). Advance the
152 token pointer so that the range will be treated as a
153 single number. */
154 *pp = end_ptr;
155 }
156 else
157 in_range = 1;
158 }
159 }
160 else if (! in_range)
161 error (_("negative value"));
162 else
163 {
164 /* pp points to the '-' that betokens a range. All
165 number-parsing has already been done. Return the next
166 integer value (one greater than the saved previous value).
167 Do not advance the token pointer 'pp' until the end of range
168 is reached. */
169
170 if (++last_retval == end_value)
171 {
172 /* End of range reached; advance token pointer. */
173 *pp = end_ptr;
174 in_range = 0;
175 }
176 }
177 return last_retval;
178}
179
aea5b279
MS
180/* Accept a number and a string-form list of numbers such as is
181 accepted by get_number_or_range. Return TRUE if the number is
182 in the list.
183
184 By definition, an empty list includes all numbers. This is to
185 be interpreted as typing a command such as "delete break" with
186 no arguments. */
187
188int
189number_is_in_list (char *list, int number)
190{
191 if (list == NULL || *list == '\0')
192 return 1;
193
298f437a
MS
194 while (*list != '\0')
195 {
196 int gotnum = get_number_or_range (&list);
aea5b279 197
298f437a
MS
198 if (gotnum == 0)
199 error (_("Args must be numbers or '$' variables."));
200 if (gotnum == number)
201 return 1;
202 }
aea5b279
MS
203 return 0;
204}
205
e9cafbcc
TT
206/* See documentation in cli-utils.h. */
207
208char *
209skip_spaces (char *chp)
210{
211 if (chp == NULL)
212 return NULL;
213 while (*chp && isspace (*chp))
214 chp++;
215 return chp;
216}
217
218/* See documentation in cli-utils.h. */
219
220char *
221skip_to_space (char *chp)
222{
223 if (chp == NULL)
224 return NULL;
225 while (*chp && !isspace (*chp))
226 chp++;
227 return chp;
228}
This page took 0.033043 seconds and 4 git commands to generate.