From patchwork Fri Jan 13 12:59:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rainer Orth X-Patchwork-Id: 91398 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp176912qgi; Fri, 13 Jan 2017 04:59:51 -0800 (PST) X-Received: by 10.99.226.83 with SMTP id y19mr23953145pgj.147.1484312391689; Fri, 13 Jan 2017 04:59:51 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id p23si12700935pfl.37.2017.01.13.04.59.51 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 13 Jan 2017 04:59:51 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-446080-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-446080-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-446080-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type; q=dns; s=default; b=nZvU93pIRkgopAZWTf0REbiPbUMyf34twJ3Py7BijrlHqiw22a 9MSmjMGKt7Ex/Fx3R4N/PEI6XgBkupUnF26BdvfVTOBI8ArAS4UHIoGQjztCtBrE Z0RN39xUeGxY6PX85MQwgyD9laJiAPFmbnANr47mON17obJ/WvJ6PdYgQ= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type; s= default; bh=oaGQwNxTRa1Cvt18XlJEx56MnqM=; b=Dl7adyk2RPlvV6I+zt53 KSHgovsULZr1UQ8s0B5UKFoq+rFPcN4Mo7wzIwOMr7k2f9Sziu4IL7j+XQGpDYoO GEhhBZPpABB4kTUgQrNpX5Wp58S5gx0DwLd5iytGxzi5JZUJwYXOq7s+wbyEKA/r rp+DdhmmntllX8ouQRiC/OA= Received: (qmail 119312 invoked by alias); 13 Jan 2017 12:59:38 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 119296 invoked by uid 89); 13 Jan 2017 12:59:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.9 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=sk:startfi, braced, sk:STARTFI, Trailing X-HELO: smtp.CeBiTec.Uni-Bielefeld.DE Received: from smtp.CeBiTec.Uni-Bielefeld.DE (HELO smtp.CeBiTec.Uni-Bielefeld.DE) (129.70.160.84) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 13 Jan 2017 12:59:26 +0000 Received: from localhost (localhost.CeBiTec.Uni-Bielefeld.DE [127.0.0.1]) by smtp.CeBiTec.Uni-Bielefeld.DE (Postfix) with ESMTP id 4F4DD92A; Fri, 13 Jan 2017 13:59:24 +0100 (CET) Received: from smtp.CeBiTec.Uni-Bielefeld.DE ([127.0.0.1]) by localhost (malfoy.CeBiTec.Uni-Bielefeld.DE [127.0.0.1]) (amavisd-new, port 10024) with LMTP id FSIGfw7oHdWR; Fri, 13 Jan 2017 13:59:20 +0100 (CET) Received: from lokon.CeBiTec.Uni-Bielefeld.DE (lokon.CeBiTec.Uni-Bielefeld.DE [129.70.161.152]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.CeBiTec.Uni-Bielefeld.DE (Postfix) with ESMTPS id BE6B8924; Fri, 13 Jan 2017 13:59:20 +0100 (CET) Received: (from ro@localhost) by lokon.CeBiTec.Uni-Bielefeld.DE (8.15.2+Sun/8.15.2/Submit) id v0DCxJtZ000407; Fri, 13 Jan 2017 13:59:19 +0100 (MET) From: Rainer Orth To: gcc-patches@gcc.gnu.org Cc: "Joseph S. Myers" , Sandra Loosemore , Jeff Downs Subject: [driver, doc] Support escaping special characters in specs Date: Fri, 13 Jan 2017 13:59:19 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1 (usg-unix-v) MIME-Version: 1.0 X-IsSubscribed: yes As a prerequisite for (a corner case in) fixing PR target/40411, we need the ability to escape special characters in specs. Case at hand: we want to match -std=iso9899:199409 which doesn't work right now. The option isn't an alias but the canonical form (though in theory one could introduce -std=c94 and make the above an alias for that), so we can only match it directly. The goal is to have this work: #define STARTFILE_ARCH_SPEC \ "%{ansi|std=c90|std=iso9899\\:199409:values-Xc.o%s; :values-Xa.o%s} \ %{std=c90|std=gnu90:values-xpg4.o%s; :values-xpg6.o%s}" Jeff submitted a patch for this in the PR almost 8 years ago, and I've just updated it slightly so it applies to mainline, and copied the docs snippet to invoke.texi with the necessary markup. Bootstrapped (together with the current proposed patch to fix the PR above) on i386-pc-solaris2.12 and sparc-sun-solaris2.12. I'm unsure if the patch is large enough to need a copyright assignment (in which case it's almost certainly too late for GCC 7), and even if not if it's appropriate at this point in the release cycle. How should we deal with this? Thanks. Rainer -- ----------------------------------------------------------------------------- Rainer Orth, Center for Biotechnology, Bielefeld University 2017-01-10 Jeff Downs Rainer Orth gcc: * gcc.c (handle_braces): Support escaping in switch matching text. * doc/invoke.texi (Spec Files): Document it. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -26391,6 +26391,13 @@ be as many clauses as you need. This ma @end table +The switch matching text @code{S} in a %@{@code{S}@}, +%@{@code{S}:@code{X}@} or similar construct can use a backslash to +ignore the special meaning of the character following it, thus allowing +literal matching of a character that is otherwise specially treated. +For example, %@{@code{std=iso9899\:1999}:@code{X}@} would substitute +@code{X} if the @option{-std=iso9899:1999} option were given. + The conditional text @code{X} in a %@{@code{S}:@code{X}@} or similar construct may contain other nested @samp{%} constructs or spaces, or even newlines. They are processed as usual, as described above. diff --git a/gcc/gcc.c b/gcc/gcc.c --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -583,6 +583,12 @@ or with constant text in a single argume %(Spec) processes a specification defined in a specs file as *Spec: +The switch matching text S in a %{S}, %{S:X}, or similar construct can use a +backslash to ignore the special meaning of the character following it, thus +allowing literal matching of a character that is otherwise specially treated. +For example, %{std=iso9899\:1999:X} would substitute X if the +-std=iso9899:1999 option were given. + The conditional text X in a %{S:X} or similar construct may contain other nested % constructs or spaces, or even newlines. They are processed as usual, as described above. Trailing white space in X is @@ -6228,6 +6234,8 @@ handle_braces (const char *p) { const char *atom, *end_atom; const char *d_atom = NULL, *d_end_atom = NULL; + char *esc_buf = NULL, *d_esc_buf = NULL; + int esc; const char *orig = p; bool a_is_suffix; @@ -6278,11 +6286,41 @@ handle_braces (const char *p) p++, a_is_spectype = true; atom = p; + esc = 0; while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '=' - || *p == ',' || *p == '.' || *p == '@') - p++; + || *p == ',' || *p == '.' || *p == '@' || *p == '\\') + { + if (*p == '\\') + { + p++; + if (!*p) + fatal_error (input_location, + "braced spec %qs ends in escape", orig); + esc++; + } + p++; + } end_atom = p; + if (esc) + { + const char *ap; + char *ep; + if (esc_buf && esc_buf != d_esc_buf) + free(esc_buf); + esc_buf = NULL; + ep = esc_buf = (char *)xmalloc (end_atom - atom - esc + 1); + for (ap = atom; ap != end_atom; ap++, ep++) + { + if (*ap == '\\') + ap++; + *ep = *ap; + } + *ep = '\0'; + atom = esc_buf; + end_atom = ep; + } + if (*p == '*') p++, a_is_starred = 1; } @@ -6349,6 +6387,7 @@ handle_braces (const char *p) disj_matched = true; d_atom = atom; d_end_atom = end_atom; + d_esc_buf = esc_buf; } } } @@ -6360,7 +6399,7 @@ handle_braces (const char *p) p = process_brace_body (p + 1, d_atom, d_end_atom, disj_starred, disj_matched && !n_way_matched); if (p == 0) - return 0; + goto done; /* If we have an N-way choice, reset state for the next disjunction. */ @@ -6381,6 +6420,12 @@ handle_braces (const char *p) } while (*p++ != '}'); + done: + if (d_esc_buf && d_esc_buf != esc_buf) + free(d_esc_buf); + if (esc_buf) + free(esc_buf); + return p; invalid: