From patchwork Tue Jun 5 20:48:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Philippe Waroquiers X-Patchwork-Id: 27644 Received: (qmail 86704 invoked by alias); 5 Jun 2018 20:49:51 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 85905 invoked by uid 89); 5 Jun 2018 20:49:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=solo, philippe.waroquiers@skynet.be, D*be, U*philippe.waroquiers X-HELO: mailsec118.isp.belgacom.be Received: from mailsec118.isp.belgacom.be (HELO mailsec118.isp.belgacom.be) (195.238.20.114) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 05 Jun 2018 20:49:30 +0000 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A2BAHABz9hZb/2wz8VFcHgEGDINDZ2gSK?= =?us-ascii?q?IxbjBABgikBQ483hCGBeAsrAYMsgRQCgh8iNRcBAgEBAQEBAQIBayhCAQEDBwS?= =?us-ascii?q?BYyKCUgYnLyMQPxI5HhmDIoIFqTkzhFiDaoFoihY/gQ6CWIp8Aph0BwKBZ4x2C?= =?us-ascii?q?4E9i2MrhzqJQYFDATWBUm2DFpBQPTB4ARoBgk2GKYJ6K4IaAQE?= X-IPAS-Result: =?us-ascii?q?A2BAHABz9hZb/2wz8VFcHgEGDINDZ2gSKIxbjBABgikBQ48?= =?us-ascii?q?3hCGBeAsrAYMsgRQCgh8iNRcBAgEBAQEBAQIBayhCAQEDBwSBYyKCUgYnLyMQP?= =?us-ascii?q?xI5HhmDIoIFqTkzhFiDaoFoihY/gQ6CWIp8Aph0BwKBZ4x2C4E9i2MrhzqJQYF?= =?us-ascii?q?DATWBUm2DFpBQPTB4ARoBgk2GKYJ6K4IaAQE?= Received: from 108.51-241-81.adsl-dyn.isp.belgacom.be (HELO md.home) ([81.241.51.108]) by relay.skynet.be with ESMTP/TLS/DHE-RSA-AES128-GCM-SHA256; 05 Jun 2018 22:49:23 +0200 From: Philippe Waroquiers To: gdb-patches@sourceware.org Cc: Philippe Waroquiers Subject: [RFA_v2 1/8] Add helper functions check_for_flags and check_for_flags_vqcs Date: Tue, 5 Jun 2018 22:48:58 +0200 Message-Id: <20180605204905.30612-2-philippe.waroquiers@skynet.be> In-Reply-To: <20180605204905.30612-1-philippe.waroquiers@skynet.be> References: <20180605204905.30612-1-philippe.waroquiers@skynet.be> X-IsSubscribed: yes Add helper functions check_for_flags and check_for_flags_vqcs check_for_flags helper function allows to look for a set of flags at the start of a string. Each flag must be given individually. 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... arguments to thread apply ID... [FLAGS...] COMMAND The error message for 'thread apply -$unknownconvvar p 1' is now the more clear: Convenience variable must have integer value. Invalid thread ID: -$unknownconvvar p 1 instead of previously: negative value gdb/ChangeLog 2018-06-05 Philippe Waroquiers * cli-utils.c (number_or_range_parser::get_number): Only handle numbers or convenience var as numbers. (check_for_flags): New function. (check_for_flags_vqcs): New function. * cli-utils.h (check_for_flags): New function. (check_for_flags_vqcs): New function. --- gdb/cli/cli-utils.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++- gdb/cli/cli-utils.h | 30 +++++++++++++ 2 files changed, 150 insertions(+), 2 deletions(-) diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c index c55b5035e4..7ce923a060 100644 --- a/gdb/cli/cli-utils.c +++ b/gdb/cli/cli-utils.c @@ -169,7 +169,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 +199,17 @@ number_or_range_parser::get_number () } } else - error (_("negative value")); + { + 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")); + } + } m_finished = *m_cur_tok == '\0'; return m_last_retval; } @@ -304,3 +317,108 @@ check_for_argument (const char **str, const char *arg, int arg_len) } return 0; } + +/* See documentation in cli-utils.h. */ + +int +check_for_flags (const char **str, const char *flags, + int *flags_counts) +{ + const char *p = skip_spaces (*str); + bool flag_found = false; + bool all_valid = true; + + /* First set the flags_counts to 0. */ + memset (flags_counts, 0, sizeof (flags_counts[0]) * strlen (flags)); + + while (*p == '-' && all_valid) + { + const char pf = *(p + 1); + + /* If - is followed by anything else than an alpha (including \0), + then we do not have a flag. This also cover the case of a command + that accepts optional flags followed by a negative integer. + In such a case, we will not handle a negative integer as invalid + flags : rather let the caller handle the negative integer. */ + if (!isalpha (pf)) + break; + + /* Check that what follows pf is the end of string, or a space. */ + if (*(p + 2) != '\0' && !isspace (*(p + 2))) + { + all_valid = false; + break; + } + + /* We have an alpha pf flag : validate the flag, and update + flags_counts for a valid flag. */ + const char *f = flags; + bool valid = false; + + while (*f != '\0') + { + valid = *f == pf; + if (valid) + { + flags_counts[f - flags]++; + flag_found = true; + p += 2; + p = skip_spaces (p); + break; + } + f++; + } + + all_valid = all_valid && valid; + } + + if (all_valid) + { + if (flag_found) + { + *str = p; + return 1; + } + else + return 0; + } + else + return -1; +} + +/* See documentation in cli-utils.h. */ + +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[strlen (flags)]; + 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 given individually"), + 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: flags c and s are mutually exclusive"), + which_command); + + return res; +} diff --git a/gdb/cli/cli-utils.h b/gdb/cli/cli-utils.h index e34ee0df37..9e74725393 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. + A flag in STR must 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 flag. */ +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 */