From: Philippe Waroquiers <philippe.waroquiers@skynet.be>
To: gdb-patches@sourceware.org
Cc: Philippe Waroquiers <philippe.waroquiers@skynet.be>
Subject: [RFC 1/5] Add helper functions check_for_flags and check_for_flags_vqcs
Date: Sat, 05 May 2018 19:28:00 -0000 [thread overview]
Message-ID: <20180505192804.12731-2-philippe.waroquiers@skynet.be> (raw)
In-Reply-To: <20180505192804.12731-1-philippe.waroquiers@skynet.be>
check_for_flags helper function allows to look for a set of flags at
the start of a string.
check_for_flags_vqcs is a specialised helper function to handle
the flags vqcs, that are used in the new command 'frame apply'
and in the command 'thread apply.
Modify number_or_range_parser::get_number to differentiate a
- followed by digits from a - followed by a flag (i.e. an alpha).
That is needed for the addition of the optional -FLAGS... argument to
thread apply ID... [-FLAGS...] COMMAND
Modify gdb/testsuite/gdb.multi/tids.exp, as the gdb error message
for 'thread apply -$unknownconvvar p 1'
is now the more clear:
Invalid thread ID: -$unknownconvvar p 1
instead of previously:
negative value
---
gdb/cli/cli-utils.c | 116 ++++++++++++++++++++++++++++++++++++++-
gdb/cli/cli-utils.h | 30 ++++++++++
gdb/testsuite/gdb.multi/tids.exp | 4 +-
3 files changed, 145 insertions(+), 5 deletions(-)
diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c
index c55b5035e4..4abd501d52 100644
--- a/gdb/cli/cli-utils.c
+++ b/gdb/cli/cli-utils.c
@@ -22,7 +22,6 @@
#include "value.h"
#include <ctype.h>
-
/* See documentation in cli-utils.h. */
int
@@ -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 flags. 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,7 +198,10 @@ number_or_range_parser::get_number ()
}
}
else
- error (_("negative value"));
+ {
+ if (*m_cur_tok >= '0' && *m_cur_tok <= '9')
+ error (_("negative value"));
+ }
m_finished = *m_cur_tok == '\0';
return m_last_retval;
}
@@ -304,3 +309,108 @@ check_for_argument (const char **str, const char *arg, int arg_len)
}
return 0;
}
+
+int
+check_for_flags (const char **str, const char *flags,
+ int *flags_counts)
+{
+ const char *p = *str;
+ bool all_valid = true;
+
+ /* First set the flags_counts to 0. */
+ {
+ const char *f = flags;
+ while (*f)
+ {
+ flags_counts[f - flags] = 0;
+ f++;
+ }
+ }
+
+ if (*p != '-')
+ return 0;
+
+ p++;
+ /* If - is the last char, or is followed by a space or a $, then
+ we do not have flags. */
+ if (*p == '\0' || (isspace (*p) || *p == '$'))
+ return 0;
+
+ /* We might have a command that accepts optional flags followed by
+ a negative integer. So, do not handle a negative integer as invalid
+ flags : rather let the caller handle the negative integer. */
+ {
+ const char *p1 = p;
+ while (*p1 >= '0' && *p1 <= '9')
+ ++p1;
+ if (p != p1 && (*p1 == '\0' || isspace (*p1)))
+ return 0;
+ }
+
+ /* We have a set of flags :
+ Scan and validate the flags, and update flags_counts for valid flags. */
+ while (*p != '\0' && !isspace (*p))
+ {
+ const char *f = flags;
+ bool valid = false;
+
+ while (*f && !valid)
+ {
+ valid = *f == *p;
+ if (valid)
+ {
+ flags_counts[f - flags]++;
+ break;
+ }
+ f++;
+ }
+ all_valid = all_valid && valid;
+ p++;
+ }
+
+ /* Skip the space(s) */
+ while (*p && isspace((int) *p))
+ ++p;
+
+ if (all_valid)
+ {
+ *str = p;
+ return 1;
+ }
+ else
+ return -1;
+}
+
+int
+check_for_flags_vqcs (const char *which_command, const char **str,
+ int *print_what_v, int max_v,
+ bool *cont, bool *silent)
+{
+ const char *flags = "vqcs";
+ int flags_counts[4];
+ int res;
+
+ *cont = false;
+ *silent = false;
+
+ res = check_for_flags (str, flags, flags_counts);
+ if (res == 0)
+ return 0;
+ if (res == -1)
+ error (_("%s only accepts flags %s"), which_command, flags);
+ gdb_assert (res == 1);
+
+ *print_what_v = *print_what_v + flags_counts[0] - flags_counts[1];
+ if (*print_what_v < 0)
+ *print_what_v = 0;
+ if (*print_what_v > max_v)
+ *print_what_v = max_v;
+
+ *cont = flags_counts[2] > 0;
+ *silent = flags_counts[3] > 0;
+ if (*cont && *silent)
+ error (_("%s does not accept at the same time flags c and s"),
+ which_command);
+
+ return res;
+}
diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h
index e34ee0df37..defbedf980 100644
--- a/gdb/cli/cli-utils.h
+++ b/gdb/cli/cli-utils.h
@@ -173,4 +173,34 @@ 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.
+ The flags must also either be at the end of the string,
+ or be followed by whitespace. Returns 1 if it finds only valid flags,
+ 0 if no flags are found, -1 if invalid flags are found.
+ FLAGS_COUNTS must be an int array of length equal to strlen(flags).
+ Sets *FLAGS_COUNTS to the number of times the corresponding flag
+ was found in *STR.
+ If only valid flags are found, it updates *STR. Note that a negative
+ integer (e.g. -123) will not be considered as an invalid set of flags. */
+extern int check_for_flags (const char **str, const char *flags,
+ int *flags_counts);
+
+/* A helper function that uses check_for_flags to handle the flags vqcs :
+ A flag v increases *print_what_v.
+ A flag q decreases *print_what_v.
+ A flag c sets *cont to true, otherwise to false.
+ A flag s sets *silent to true, otherwise to false.
+ The caller must initialise *PRINT_WHAT_V to the default verbosity.
+ MAX_V gives the maximum verbosity : the value returned in *PRINT_WHAT_V
+ will always be >= 0 and <= MAX_V.
+ WHICH_COMMAND is used in the error message in case invalid flags are found.
+
+ Returns 1 and updates *STR if it finds only valid flags.
+ Returns 0 if no flags are found.
+ Raises an error if invalid flags are found.
+*/
+extern int check_for_flags_vqcs (const char *which_command, const char **str,
+ int *print_what_v, int max_v,
+ bool *cont, bool *silent);
#endif /* CLI_UTILS_H */
diff --git a/gdb/testsuite/gdb.multi/tids.exp b/gdb/testsuite/gdb.multi/tids.exp
index 67349b5759..ae8328d997 100644
--- a/gdb/testsuite/gdb.multi/tids.exp
+++ b/gdb/testsuite/gdb.multi/tids.exp
@@ -350,8 +350,8 @@ with_test_prefix "two inferiors" {
thr_apply_info_thr_error "${prefix}1-" "inverted range"
thr_apply_info_thr_error "${prefix}2-1" "inverted range"
thr_apply_info_thr_error "${prefix}2-\$one" "inverted range"
- thr_apply_info_thr_error "${prefix}-1" "negative value"
- thr_apply_info_thr_error "${prefix}-\$one" "negative value"
+ thr_apply_info_thr_error "${prefix}-1" "Invalid thread ID: ${prefix_re}-1"
+ thr_apply_info_thr_error "${prefix}-\$one" "Invalid thread ID: ${prefix_re}-\\\$one"
thr_apply_info_thr_error "${prefix}\$minus_one" \
"negative value: ${prefix_re}\\\$minus_one"
--
2.11.0
next prev parent reply other threads:[~2018-05-05 19:28 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-05 19:28 [RFC 0/5] Implenent 'frame apply COMMAND', enhance 'thread apply COMMAND' Philippe Waroquiers
2018-05-05 19:28 ` [RFC 4/5] Documentation changes for 'frame apply' and 'thread apply' Philippe Waroquiers
2018-05-06 19:40 ` Eli Zaretskii
2018-05-05 19:28 ` Philippe Waroquiers [this message]
2018-05-18 1:56 ` [RFC 1/5] Add helper functions check_for_flags and check_for_flags_vqcs Simon Marchi
2018-05-18 23:39 ` Philippe Waroquiers
2018-05-19 6:47 ` Simon Marchi
2018-05-19 6:59 ` Philippe Waroquiers
2018-05-05 19:28 ` [RFC 5/5] Announce 'frame apply', faas, taas, tfaas commands and -FLAGS... arg for frame apply Philippe Waroquiers
2018-05-06 19:13 ` Eli Zaretskii
2018-05-05 19:28 ` [RFC 3/5] Add -FLAGS... argument to thread apply Philippe Waroquiers
2018-05-06 19:09 ` Eli Zaretskii
2018-05-05 19:28 ` [RFC 2/5] Implement frame apply [all | COUNT | -COUNT] [-FLAGS...] COMMAND Philippe Waroquiers
2018-05-06 19:16 ` Eli Zaretskii
2018-05-18 1:58 ` Simon Marchi
2018-05-19 5:16 ` Philippe Waroquiers
2018-05-18 9:46 ` Simon Marchi
2018-05-18 10:42 ` [RFC 0/5] Implenent 'frame apply COMMAND', enhance 'thread apply COMMAND' Simon Marchi
2018-05-18 22:06 ` Philippe Waroquiers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180505192804.12731-2-philippe.waroquiers@skynet.be \
--to=philippe.waroquiers@skynet.be \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).