From patchwork Mon May 21 11:06:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Philippe Waroquiers X-Patchwork-Id: 27345 Received: (qmail 85313 invoked by alias); 21 May 2018 11:07:10 -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 85208 invoked by uid 89); 21 May 2018 11:07:10 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-27.6 required=5.0 tests=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=H*Ad:D*be, solo, mutually X-HELO: mailsec110.isp.belgacom.be Received: from mailsec110.isp.belgacom.be (HELO mailsec110.isp.belgacom.be) (195.238.20.106) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 21 May 2018 11:07:08 +0000 IronPort-PHdr: =?us-ascii?q?9a23=3ABvIpThFS3zQxdJnUfb/cS51GYnF86YWxBRYc798d?= =?us-ascii?q?s5kLTJ7zo8SwAkXT6L1XgUPTWs2DsrQY07GQ6/iocFdDyK7JiGoFfp1IWk1Nou?= =?us-ascii?q?QttCtkPvS4D1bmJuXhdS0wEZcKflZk+3amLRodQ56mNBXdrXKo8DEdBAj0OxZr?= =?us-ascii?q?KeTpAI7SiNm82/yv95HJbAhEmDSwbaluIBmqsA7cqtQYjYx+J6gr1xDHuGFIe+?= =?us-ascii?q?NYxWNpIVKcgRPx7dqu8ZBg7ipdpesv+9ZPXqvmcas4S6dYDCk9PGAu+MLrrxjD?= =?us-ascii?q?QhCR6XYaT24bjwBHAwnB7BH9Q5fxri73vfdz1SWGIcH7S60/VDK/5KlpVRDokj?= =?us-ascii?q?8KOT4n/m/KhMJ+j6VVrxCvpxFk34LYfJuYOOZkc6/BYd8XQ3dKUMZLVyxGB4Ox?= =?us-ascii?q?d5EBD+oAPeZcron9v0MOogWjDgasHuzv0DhIhmbr3a07zeshCxrG1xEnEtIWsH?= =?us-ascii?q?TUrdH1NKYKUeCt0qbE1zvCYOlM2Tf68YjIbxEhru+WXbJrasfR0kovFgPDjlqO?= =?us-ascii?q?tYzpJSia2foUvmWd8uFuVvqvhnY6pw1tpjWj3Nogh4fVio4P11zI6yR0zJwrKd?= =?us-ascii?q?C2VkJ2Z8OvHoFKuCGALYR2R9svQ2RvuCkn1LILoYW7fC0WyJQ/wB7fduCHf5CI?= =?us-ascii?q?4h39UOaRJi91hHd4d76lhxay9k2gxfPkWsm11lZFsDZFn8HRunwR0xHf8NWLR/?= =?us-ascii?q?Vh8ku7xDqDyQHe5vtaLU06i6bXM5shzaQxlpoXv0TDBCj2mEDuga+OdkUk++yo?= =?us-ascii?q?6+X/YrX+uJCQLYF1hRvkMqQpg8y/HOU4PRYUX2iA4um8z77j/E3/QLpUkv06iL?= =?us-ascii?q?LWv47CKcQBuqG5GxNV0pok6xunADepzc8XkWAfLF1fZBKIk4jpNE/VIP3jFve/?= =?us-ascii?q?hEmskC13yP/YMLzuGI/NIWbZnLfmZ7Z95FZWyBAvwtBH+5JUFrYBLerrWk/xtd?= =?us-ascii?q?zYCh45MxSsw+n5Etl82JkRWXiIAq+ALaPSsEGH5vg0I+SXf48Vuzb8K/476P7y?= =?us-ascii?q?l3M2gkESLuGV2s4YZHr9Bv16KEWUelL3hcobGmoVtxAzCuvwhw6sSzlWMk6yXq?= =?us-ascii?q?Y9/ik2QL2vF4DaW4GgmqfJiD+7H5lXfnhLTE+FC3DxaoSJQewkcyGDJMJ91DYJ?= =?us-ascii?q?A+vyA7Q93A2j4Vepg4FsKfDZr3UV?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A2AKDABwpwJb/+h+gm1cHgEGDINDgV6NA?= =?us-ascii?q?IwTAYIpAUMajxaGGAsrAYMsgRQCghUiNxUBAgEBAQEBAQIBayiCNSKCUgYnLyM?= =?us-ascii?q?QPxI5HoM7ggWoPzOEWINmgg+KCT+BDoJYinwCmEwHAoFnjGULgTeLRiuHI4kpg?= =?us-ascii?q?SUyIoFSbYMXkE89gSgBGgGMWyuCGQEB?= X-IPAS-Result: =?us-ascii?q?A2AKDABwpwJb/+h+gm1cHgEGDINDgV6NAIwTAYIpAUMajxa?= =?us-ascii?q?GGAsrAYMsgRQCghUiNxUBAgEBAQEBAQIBayiCNSKCUgYnLyMQPxI5HoM7ggWoP?= =?us-ascii?q?zOEWINmgg+KCT+BDoJYinwCmEwHAoFnjGULgTeLRiuHI4kpgSUyIoFSbYMXkE8?= =?us-ascii?q?9gSgBGgGMWyuCGQEB?= Received: from 232.126-130-109.adsl-dyn.isp.belgacom.be (HELO md.home) ([109.130.126.232]) by relay.skynet.be with ESMTP/TLS/DHE-RSA-AES128-GCM-SHA256; 21 May 2018 13:07:00 +0200 From: Philippe Waroquiers To: gdb-patches@sourceware.org Cc: Philippe Waroquiers Subject: [RFA 1/8] Add helper functions check_for_flags and check_for_flags_vqcs Date: Mon, 21 May 2018 13:06:44 +0200 Message-Id: <20180521110651.13842-2-philippe.waroquiers@skynet.be> In-Reply-To: <20180521110651.13842-1-philippe.waroquiers@skynet.be> References: <20180521110651.13842-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. 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 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/cli/cli-utils.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++- gdb/cli/cli-utils.h | 30 ++++++++++++++ 2 files changed, 138 insertions(+), 2 deletions(-) diff --git a/gdb/cli/cli-utils.c b/gdb/cli/cli-utils.c index c55b5035e4..de2220c21a 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,96 @@ 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 = *str; + bool all_valid = true; + + /* First set the flags_counts to 0. */ + memset (flags_counts, 0, sizeof (flags_counts[0]) * strlen (flags)); + + if (*p != '-') + return 0; + + p++; + /* If - is followed by anything else than an alpha (including \0), + then we do not have flags. 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 handler the negative integer. */ + if (!isalpha (*p)) + 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 != '\0') + { + valid = *f == *p; + if (valid) + { + flags_counts[f - flags]++; + break; + } + f++; + } + all_valid = all_valid && valid; + p++; + } + + /* Skip the space(s). */ + p = skip_spaces (p); + + if (all_valid) + { + *str = p; + return 1; + } + 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"), 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..7b94b82844 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 */