aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog13
-rw-r--r--gdb/cli/cli-utils.c96
-rw-r--r--gdb/cli/cli-utils.h45
-rw-r--r--gdb/testsuite/ChangeLog4
-rw-r--r--gdb/testsuite/gdb.base/skip.exp6
5 files changed, 151 insertions, 13 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 1a37862..7eb8d01 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,16 @@
+2018-07-12 Philippe Waroquiers <philippe.waroquiers@skynet.be>
+
+ * cli-utils.c (number_or_range_parser::get_number): Only handle
+ numbers or convenience var as numbers.
+ (parse_flags): New function.
+ (parse_flags_qcs): New function.
+ (number_or_range_parser::finished): Ensure parsing end is detected
+ before end of string.
+ * cli-utils.h (parse_flags): New function.
+ (parse_flags_qcs): New function.
+ (number_or_range_parser): Remove m_finished bool.
+ (number_or_range_parser::skip_range): Set m_in_range to false.
+
2018-07-12 Sergio Durigan Junior <sergiodj@redhat.com>
* ser-tcp.c (try_connect): Declare 'ioarg' as 'u_long' if building
diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c
index c55b503..98b7414 100644
--- a/gdb/cli/cli-utils.c
+++ b/gdb/cli/cli-utils.c
@@ -137,7 +137,6 @@ number_or_range_parser::number_or_range_parser (const char *string)
void
number_or_range_parser::init (const char *string)
{
- m_finished = false;
m_cur_tok = string;
m_last_retval = 0;
m_end_value = 0;
@@ -169,7 +168,10 @@ number_or_range_parser::get_number ()
/* Default case: state->m_cur_tok is pointing either to a solo
number, or to the first number of a range. */
m_last_retval = get_number_trailer (&m_cur_tok, '-');
- if (*m_cur_tok == '-')
+ /* If get_number_trailer has found a -, it might be the start
+ of a command option. So, do not parse a range if the - is
+ followed by an alpha. */
+ if (*m_cur_tok == '-' && !isalpha (*(m_cur_tok + 1)))
{
const char **temp;
@@ -196,8 +198,17 @@ number_or_range_parser::get_number ()
}
}
else
- error (_("negative value"));
- m_finished = *m_cur_tok == '\0';
+ {
+ if (isdigit (*(m_cur_tok + 1)))
+ error (_("negative value"));
+ if (*(m_cur_tok + 1) == '$')
+ {
+ /* Convenience variable. */
+ m_last_retval = ::get_number (&m_cur_tok);
+ if (m_last_retval < 0)
+ error (_("negative value"));
+ }
+ }
return m_last_retval;
}
@@ -215,6 +226,21 @@ number_or_range_parser::setup_range (int start_value, int end_value,
m_end_value = end_value;
}
+/* See documentation in cli-utils.h. */
+
+bool
+number_or_range_parser::finished () const
+{
+ /* Parsing is finished when at end of string or null string,
+ or we are not in a range and not in front of an integer, negative
+ integer, convenience var or negative convenience var. */
+ return (m_cur_tok == NULL || *m_cur_tok == '\0'
+ || (!m_in_range
+ && !(isdigit (*m_cur_tok) || *m_cur_tok == '$')
+ && !(*m_cur_tok == '-'
+ && (isdigit (m_cur_tok[1]) || m_cur_tok[1] == '$'))));
+}
+
/* Accept a number and a string-form list of numbers such as is
accepted by get_number_or_range. Return TRUE if the number is
in the list.
@@ -230,12 +256,15 @@ number_is_in_list (const char *list, int number)
return 1;
number_or_range_parser parser (list);
+
+ if (parser.finished ())
+ error (_("Arguments must be numbers or '$' variables."));
while (!parser.finished ())
{
int gotnum = parser.get_number ();
if (gotnum == 0)
- error (_("Args must be numbers or '$' variables."));
+ error (_("Arguments must be numbers or '$' variables."));
if (gotnum == number)
return 1;
}
@@ -304,3 +333,60 @@ check_for_argument (const char **str, const char *arg, int arg_len)
}
return 0;
}
+
+/* See documentation in cli-utils.h. */
+
+int
+parse_flags (const char **str, const char *flags)
+{
+ const char *p = skip_spaces (*str);
+
+ if (p[0] == '-'
+ && isalpha (p[1])
+ && (p[2] == '\0' || isspace (p[2])))
+ {
+ const char pf = p[1];
+ const char *f = flags;
+
+ while (*f != '\0')
+ {
+ if (*f == pf)
+ {
+ *str = skip_spaces (p + 2);
+ return f - flags + 1;
+ }
+ f++;
+ }
+ }
+
+ return 0;
+}
+
+/* See documentation in cli-utils.h. */
+
+bool
+parse_flags_qcs (const char *which_command, const char **str,
+ qcs_flags *flags)
+{
+ switch (parse_flags (str, "qcs"))
+ {
+ case 0:
+ return false;
+ case 1:
+ flags->quiet = true;
+ break;
+ case 2:
+ flags->cont = true;
+ break;
+ case 3:
+ flags->silent = true;
+ break;
+ default:
+ gdb_assert_not_reached ("int qcs flag out of bound");
+ }
+
+ if (flags->cont && flags->silent)
+ error (_("%s: -c and -s are mutually exclusive"), which_command);
+
+ return true;
+}
diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h
index e34ee0d..fa7d02d 100644
--- a/gdb/cli/cli-utils.h
+++ b/gdb/cli/cli-utils.h
@@ -75,8 +75,7 @@ public:
const char *end_ptr);
/* Returns true if parsing has completed. */
- bool finished () const
- { return m_finished; }
+ bool finished () const;
/* Return the string being parsed. When parsing has finished, this
points past the last parsed token. */
@@ -96,6 +95,7 @@ public:
{
gdb_assert (m_in_range);
m_cur_tok = m_end_ptr;
+ m_in_range = false;
}
private:
@@ -103,9 +103,6 @@ private:
number_or_range_parser (const number_or_range_parser &);
number_or_range_parser &operator= (const number_or_range_parser &);
- /* True if parsing has completed. */
- bool m_finished;
-
/* The string being parsed. When parsing has finished, this points
past the last parsed token. */
const char *m_cur_tok;
@@ -173,4 +170,42 @@ check_for_argument (char **str, const char *arg, int arg_len)
arg, arg_len);
}
+/* A helper function that looks for a set of flags at the start of a
+ string. The possible flags are given as a null terminated string.
+ A flag in STR must either be at the end of the string,
+ or be followed by whitespace.
+ Returns 0 if no valid flag is found at the start of STR.
+ Otherwise updates *STR, and returns N (which is > 0),
+ such that FLAGS [N - 1] is the valid found flag. */
+extern int parse_flags (const char **str, const char *flags);
+
+/* qcs_flags struct regroups the flags parsed by parse_flags_qcs. */
+
+struct qcs_flags
+{
+ bool quiet = false;
+ bool cont = false;
+ bool silent = false;
+};
+
+/* A helper function that uses parse_flags to handle the flags qcs :
+ A flag -q sets FLAGS->QUIET to true.
+ A flag -c sets FLAGS->CONT to true.
+ A flag -s sets FLAGS->SILENT to true.
+
+ The caller is responsible to initialize *FLAGS to false before the (first)
+ call to parse_flags_qcs.
+ parse_flags_qcs can then be called iteratively to search for more
+ valid flags, as part of a 'main parsing loop' searching for -q/-c/-s
+ flags together with other flags and options.
+
+ Returns true and updates *STR and one of FLAGS->QUIET, FLAGS->CONT,
+ FLAGS->SILENT if it finds a valid flag.
+ Returns false if no valid flag is found at the beginning of STR.
+
+ Throws an error if a flag is found such that both FLAGS->CONT and
+ FLAGS->SILENT are true. */
+
+extern bool parse_flags_qcs (const char *which_command, const char **str,
+ qcs_flags *flags);
#endif /* CLI_UTILS_H */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 2ddf7f8..95ad798 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2018-07-12 Philippe Waroquiers <philippe.waroquiers@skynet.be>
+
+ * gdb.base/skip.exp: Update expected error message.
+
2018-07-11 Sergio Durigan Junior <sergiodj@redhat.com>
Jan Kratochvil <jan.kratochvil@redhat.com>
Paul Fertser <fercerpav@gmail.com>
diff --git a/gdb/testsuite/gdb.base/skip.exp b/gdb/testsuite/gdb.base/skip.exp
index 4b556b1..223c93d 100644
--- a/gdb/testsuite/gdb.base/skip.exp
+++ b/gdb/testsuite/gdb.base/skip.exp
@@ -69,9 +69,9 @@ gdb_test "skip function baz" "Function baz will be skipped when stepping\."
gdb_test "skip enable 999" "No skiplist entries found with number 999."
gdb_test "skip disable 999" "No skiplist entries found with number 999."
gdb_test "skip delete 999" "No skiplist entries found with number 999."
-gdb_test "skip enable a" "Args must be numbers or '\\$' variables."
-gdb_test "skip disable a" "Args must be numbers or '\\$' variables."
-gdb_test "skip delete a" "Args must be numbers or '\\$' variables."
+gdb_test "skip enable a" "Arguments must be numbers or '\\$' variables."
+gdb_test "skip disable a" "Arguments must be numbers or '\\$' variables."
+gdb_test "skip delete a" "Arguments must be numbers or '\\$' variables."
# Ask for info on a skiplist entry which doesn't exist.