diff options
Diffstat (limited to 'gdb/cli/cli-utils.c')
-rw-r--r-- | gdb/cli/cli-utils.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c new file mode 100644 index 0000000..0c98ca9 --- /dev/null +++ b/gdb/cli/cli-utils.c @@ -0,0 +1,186 @@ +/* CLI utilities. + + Copyright (c) 2011 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "defs.h" +#include "cli/cli-utils.h" +#include "gdb_string.h" +#include "value.h" + +#include <ctype.h> + +/* *PP is a string denoting a number. Get the number of the. Advance + *PP after the string and any trailing whitespace. + + Currently the string can either be a number or "$" followed by the + name of a convenience variable. + + TRAILER is a character which can be found after the number; most + commonly this is `-'. If you don't want a trailer, use \0. */ + +static int +get_number_trailer (char **pp, int trailer) +{ + int retval = 0; /* default */ + char *p = *pp; + + if (*p == '$') + { + /* Make a copy of the name, so we can null-terminate it + to pass to lookup_internalvar(). */ + char *varname; + char *start = ++p; + LONGEST val; + + while (isalnum (*p) || *p == '_') + p++; + varname = (char *) alloca (p - start + 1); + strncpy (varname, start, p - start); + varname[p - start] = '\0'; + if (get_internalvar_integer (lookup_internalvar (varname), &val)) + retval = (int) val; + else + { + printf_filtered (_("Convenience variable must " + "have integer value.\n")); + retval = 0; + } + } + else + { + if (*p == '-') + ++p; + while (*p >= '0' && *p <= '9') + ++p; + if (p == *pp) + /* There is no number here. (e.g. "cond a == b"). */ + { + /* Skip non-numeric token. */ + while (*p && !isspace((int) *p)) + ++p; + /* Return zero, which caller must interpret as error. */ + retval = 0; + } + else + retval = atoi (*pp); + } + if (!(isspace (*p) || *p == '\0' || *p == trailer)) + { + /* Trailing junk: return 0 and let caller print error msg. */ + while (!(isspace (*p) || *p == '\0' || *p == trailer)) + ++p; + retval = 0; + } + p = skip_spaces (p); + *pp = p; + return retval; +} + +/* See documentation in cli-utils.h. */ + +int +get_number (char **pp) +{ + return get_number_trailer (pp, '\0'); +} + +/* See documentation in cli-utils.h. */ + +int +get_number_or_range (char **pp) +{ + static int last_retval, end_value; + static char *end_ptr; + static int in_range = 0; + + if (**pp != '-') + { + /* Default case: pp is pointing either to a solo number, + or to the first number of a range. */ + last_retval = get_number_trailer (pp, '-'); + if (**pp == '-') + { + char **temp; + + /* This is the start of a range (<number1> - <number2>). + Skip the '-', parse and remember the second number, + and also remember the end of the final token. */ + + temp = &end_ptr; + end_ptr = *pp + 1; + while (isspace ((int) *end_ptr)) + end_ptr++; /* skip white space */ + end_value = get_number (temp); + if (end_value < last_retval) + { + error (_("inverted range")); + } + else if (end_value == last_retval) + { + /* Degenerate range (number1 == number2). Advance the + token pointer so that the range will be treated as a + single number. */ + *pp = end_ptr; + } + else + in_range = 1; + } + } + else if (! in_range) + error (_("negative value")); + else + { + /* pp points to the '-' that betokens a range. All + number-parsing has already been done. Return the next + integer value (one greater than the saved previous value). + Do not advance the token pointer 'pp' until the end of range + is reached. */ + + if (++last_retval == end_value) + { + /* End of range reached; advance token pointer. */ + *pp = end_ptr; + in_range = 0; + } + } + return last_retval; +} + +/* See documentation in cli-utils.h. */ + +char * +skip_spaces (char *chp) +{ + if (chp == NULL) + return NULL; + while (*chp && isspace (*chp)) + chp++; + return chp; +} + +/* See documentation in cli-utils.h. */ + +char * +skip_to_space (char *chp) +{ + if (chp == NULL) + return NULL; + while (*chp && !isspace (*chp)) + chp++; + return chp; +} |