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