From patchwork Fri Jul 26 13:34:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 33809 Received: (qmail 121233 invoked by alias); 26 Jul 2019 13:34:42 -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 121046 invoked by uid 89); 26 Jul 2019 13:34:42 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=H*Ad:U*tromey, latent X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 26 Jul 2019 13:34:40 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 4117D116FE6; Fri, 26 Jul 2019 09:34:39 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 0Ubi1OFXBV10; Fri, 26 Jul 2019 09:34:39 -0400 (EDT) Received: from murgatroyd.Home (97-122-178-82.hlrn.qwest.net [97.122.178.82]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPSA id E0E97116E46; Fri, 26 Jul 2019 09:34:38 -0400 (EDT) From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 1/4] Fix latent bug in source cache Date: Fri, 26 Jul 2019 07:34:20 -0600 Message-Id: <20190726133422.5896-2-tromey@adacore.com> In-Reply-To: <20190726133422.5896-1-tromey@adacore.com> References: <20190726133422.5896-1-tromey@adacore.com> MIME-Version: 1.0 The source cache was not returning the final \n of the requested range of lines. This caused regressions with later patches in this series, so this patch pre-emptively fixes the bug. This adds a self-test of "extract_lines" to the source cache code. To make it simpler to test, I changed extract_lines to be a static function, and changed it's API a bit. gdb/ChangeLog 2019-07-26 Tom Tromey * source-cache.c (extract_lines): No longer a method. Changed type of parameter. Include final newline. (selftests::extract_lines_test): New function. (_initialize_source_cache): Likewise. * source-cache.h (class source_cache) : Don't declare. --- gdb/ChangeLog | 9 +++++++++ gdb/source-cache.c | 49 +++++++++++++++++++++++++++++++++++----------- gdb/source-cache.h | 6 ------ 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/gdb/source-cache.c b/gdb/source-cache.c index f5bb641a22b..f0cb6b80059 100644 --- a/gdb/source-cache.c +++ b/gdb/source-cache.c @@ -22,6 +22,7 @@ #include "source.h" #include "cli/cli-style.h" #include "symtab.h" +#include "gdbsupport/selftest.h" #ifdef HAVE_SOURCE_HIGHLIGHT /* If Gnulib redirects 'open' and 'close' to its replacements @@ -80,11 +81,12 @@ source_cache::get_plain_source_lines (struct symtab *s, int first_line, return true; } -/* See source-cache.h. */ - -std::string -source_cache::extract_lines (const struct source_text &text, int first_line, - int last_line) +/* A helper function for get_plain_source_lines that extracts the + desired source lines from TEXT, putting them into LINES_OUT. The + arguments are as for get_source_lines. The return value is the + desired lines. */ +static std::string +extract_lines (const std::string &text, int first_line, int last_line) { int lineno = 1; std::string::size_type pos = 0; @@ -92,7 +94,7 @@ source_cache::extract_lines (const struct source_text &text, int first_line, while (pos != std::string::npos && lineno <= last_line) { - std::string::size_type new_pos = text.contents.find ('\n', pos); + std::string::size_type new_pos = text.find ('\n', pos); if (lineno == first_line) first_pos = pos; @@ -103,8 +105,10 @@ source_cache::extract_lines (const struct source_text &text, int first_line, if (first_pos == std::string::npos) return {}; if (pos == std::string::npos) - pos = text.contents.size (); - return text.contents.substr (first_pos, pos - first_pos); + pos = text.size (); + else + ++pos; + return text.substr (first_pos, pos - first_pos); } ++lineno; ++pos; @@ -187,7 +191,7 @@ source_cache::get_source_lines (struct symtab *s, int first_line, { if (item.fullname == fullname) { - *lines = extract_lines (item, first_line, last_line); + *lines = extract_lines (item.contents, first_line, last_line); return true; } } @@ -233,8 +237,8 @@ source_cache::get_source_lines (struct symtab *s, int first_line, if (m_source_map.size () > MAX_ENTRIES) m_source_map.erase (m_source_map.begin ()); - *lines = extract_lines (m_source_map.back (), first_line, - last_line); + *lines = extract_lines (m_source_map.back ().contents, + first_line, last_line); return true; } } @@ -243,3 +247,26 @@ source_cache::get_source_lines (struct symtab *s, int first_line, return get_plain_source_lines (s, first_line, last_line, lines); } + +#if GDB_SELF_TEST +namespace selftests +{ +static void extract_lines_test () +{ + std::string input_text = "abc\ndef\nghi\njkl\n"; + + SELF_CHECK (extract_lines (input_text, 1, 1) == "abc\n"); + SELF_CHECK (extract_lines (input_text, 2, 1) == ""); + SELF_CHECK (extract_lines (input_text, 1, 2) == "abc\ndef\n"); + SELF_CHECK (extract_lines ("abc", 1, 1) == "abc"); +} +} +#endif + +void +_initialize_source_cache () +{ +#if GDB_SELF_TEST + selftests::register_test ("source-cache", selftests::extract_lines_test); +#endif +} diff --git a/gdb/source-cache.h b/gdb/source-cache.h index e2e25a170fd..a00efbf3fba 100644 --- a/gdb/source-cache.h +++ b/gdb/source-cache.h @@ -63,12 +63,6 @@ private: are as for get_source_lines. */ bool get_plain_source_lines (struct symtab *s, int first_line, int last_line, std::string *lines_out); - /* A helper function for get_plain_source_lines that extracts the - desired source lines from TEXT, putting them into LINES_OUT. The - arguments are as for get_source_lines. The return value is the - desired lines. */ - std::string extract_lines (const struct source_text &text, int first_line, - int last_line); /* The contents of the cache. */ std::vector m_source_map;