From patchwork Thu Nov 3 19:59:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 1699162 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=KIe0Z4in; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4N3F2n2g6Yz20KC for ; Fri, 4 Nov 2022 06:59:29 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0A8EE3858412 for ; Thu, 3 Nov 2022 19:59:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0A8EE3858412 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1667505567; bh=zQ4afx7uaOwPvv0clfFTKyLH/qazzhJ9n2JC4H+dZhM=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=KIe0Z4inVJaTe0SFmEiigQc+O2eCaiA7dSAhw9KognILLbIDqSs/yVl+luP+Z7hgH ATz8HHDU9cfYDl259rkoyjucPKoyQ/mk0dxWfs6XuFWArXaS4zH7Ba7uA8vzzJygvU MkuVEuA8MEgE/xv3u8nErgymHp/CqSB8HXq0tJqM= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 694F33858D1E for ; Thu, 3 Nov 2022 19:59:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 694F33858D1E Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-231-r4rfpr3iMNqQvaGkQvqDnQ-1; Thu, 03 Nov 2022 15:59:06 -0400 X-MC-Unique: r4rfpr3iMNqQvaGkQvqDnQ-1 Received: by mail-qt1-f199.google.com with SMTP id gc12-20020a05622a59cc00b003a5444280e1so2555042qtb.13 for ; Thu, 03 Nov 2022 12:59:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=zQ4afx7uaOwPvv0clfFTKyLH/qazzhJ9n2JC4H+dZhM=; b=FbiSCojW2z02CGLLDqHK0XD56c7LkLS5NXbo6k0oLxIpFURJhy+OEKTzazlpoM/NIf frS0XGpI99ywfLSn45UZvt5IMY8wb3i4zMVVhnVi527BM4i1ouAzCE5b8hQSjijBmd9Q LBaS5dUCHRxB9w2LdTF84awb8O6V5MNqNmAMMDbNQW+fTIGaMbSiZmD9/p2vONZSifA9 iUPUYXPXGfzj1OH8kNUv5WnLg8jfqrAX8WxMZWvVPI+pX+iVH53IcA0ug3IucYed5Bwm XWb7yv0xH9nRCC3lf/k7RNr9wsLHjgLxCiBW03VjJteYlJjv7+ZsQK+jGLKbVEvrMsMO 2ndA== X-Gm-Message-State: ACrzQf1Fd+3hkIh7ECjLgiXhp7+zMUA3Iw1Qa/+937mqma4kVSDUKNeE hcxNkAkePNN/KzdTNGotOQbb52XT2mRjr8DwOI1nkgsCJOHytTrftG5CgT47GXRZ4/TTQxL+w89 FXWYiR56sheq4PRQHCcn+z1WJMSZrudWeirXeOj/QXq7qH7AwcAw5+OCK/66jzSYtpw== X-Received: by 2002:a05:6214:2b06:b0:4bb:5716:d1c3 with SMTP id jx6-20020a0562142b0600b004bb5716d1c3mr28714601qvb.85.1667505545171; Thu, 03 Nov 2022 12:59:05 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6Orehl+z9dhPXk5I5lgn3OPGiUreUBU/Gjwz9tBPU/SdO6FAcMFyHFhcNPiSzEQw8TzjAGZQ== X-Received: by 2002:a05:6214:2b06:b0:4bb:5716:d1c3 with SMTP id jx6-20020a0562142b0600b004bb5716d1c3mr28714586qvb.85.1667505544774; Thu, 03 Nov 2022 12:59:04 -0700 (PDT) Received: from barrymore.redhat.com (130-44-159-43.s15913.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.159.43]) by smtp.gmail.com with ESMTPSA id fa3-20020a05622a4cc300b003a4f14378d1sm1069636qtb.33.2022.11.03.12.59.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Nov 2022 12:59:04 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH RFA] input: add get_source_text_between Date: Thu, 3 Nov 2022 15:59:02 -0400 Message-Id: <20221103195902.2114479-1-jason@redhat.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jason Merrill via Gcc-patches From: Jason Merrill Reply-To: Jason Merrill Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Tested x86_64-pc-linux-gnu, OK for trunk? -- >8 -- The c++-contracts branch uses this to retrieve the source form of the contract predicate, to be returned by contract_violation::comment(). gcc/ChangeLog: * input.cc (get_source_text_between): New fn. * input.h (get_source_text_between): Declare. --- gcc/input.h | 1 + gcc/input.cc | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) base-commit: a4cd2389276a30c39034a83d640ce68fa407bac1 prerequisite-patch-id: 329bc16a88dc9a3b13cd3fcecb3678826cc592dc prerequisite-patch-id: 49e922c10f6da687d9da3f6a0fd20f324bd352d6 diff --git a/gcc/input.h b/gcc/input.h index 11c571d076f..f18769950b5 100644 --- a/gcc/input.h +++ b/gcc/input.h @@ -111,6 +111,7 @@ class char_span }; extern char_span location_get_source_line (const char *file_path, int line); +extern char *get_source_text_between (location_t, location_t); extern bool location_missing_trailing_newline (const char *file_path); diff --git a/gcc/input.cc b/gcc/input.cc index a28abfac5ac..9b36356338a 100644 --- a/gcc/input.cc +++ b/gcc/input.cc @@ -949,6 +949,82 @@ location_get_source_line (const char *file_path, int line) return char_span (buffer, len); } +/* Return a copy of the source text between two locations. The caller is + responsible for freeing the return value. */ + +char * +get_source_text_between (location_t start, location_t end) +{ + expanded_location expstart = + expand_location_to_spelling_point (start, LOCATION_ASPECT_START); + expanded_location expend = + expand_location_to_spelling_point (end, LOCATION_ASPECT_FINISH); + + /* If the locations are in different files or the end comes before the + start, abort and return nothing. */ + if (!expstart.file || !expend.file) + return NULL; + if (strcmp (expstart.file, expend.file) != 0) + return NULL; + if (expstart.line > expend.line) + return NULL; + if (expstart.line == expend.line + && expstart.column > expend.column) + return NULL; + + /* For a single line we need to trim both edges. */ + if (expstart.line == expend.line) + { + char_span line = location_get_source_line (expstart.file, expstart.line); + if (line.length () < 1) + return NULL; + int s = expstart.column - 1; + int l = expend.column - s; + if (line.length () < (size_t)expend.column) + return NULL; + return line.subspan (s, l).xstrdup (); + } + + struct obstack buf_obstack; + obstack_init (&buf_obstack); + + /* Loop through all lines in the range and append each to buf; may trim + parts of the start and end lines off depending on column values. */ + for (int l = expstart.line; l <= expend.line; ++l) + { + char_span line = location_get_source_line (expstart.file, l); + if (line.length () < 1 && (l != expstart.line && l != expend.line)) + continue; + + /* For the first line in the range, only start at expstart.column */ + if (l == expstart.line) + { + if (expstart.column == 0) + return NULL; + if (line.length () < (size_t)expstart.column - 1) + return NULL; + line = line.subspan (expstart.column - 1, + line.length() - expstart.column + 1); + } + /* For the last line, don't go past expend.column */ + else if (l == expend.line) + { + if (line.length () < (size_t)expend.column) + return NULL; + line = line.subspan (0, expend.column); + } + + obstack_grow (&buf_obstack, line.get_buffer (), line.length ()); + } + + /* NUL-terminate and finish the buf obstack. */ + obstack_1grow (&buf_obstack, 0); + const char *buf = (const char *) obstack_finish (&buf_obstack); + + /* TODO should we collapse/trim newlines and runs of spaces? */ + return xstrdup (buf); +} + /* Determine if FILE_PATH missing a trailing newline on its final line. Only valid to call once all of the file has been loaded, by requesting a line number beyond the end of the file. */