From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 41339 invoked by alias); 15 Nov 2019 19:57:00 -0000 Mailing-List: contact libstdc++-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libstdc++-owner@gcc.gnu.org Received: (qmail 41330 invoked by uid 89); 15 Nov 2019 19:57:00 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-17.1 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS autolearn=ham version=3.3.1 spammy=HX-Languages-Length:3606 X-HELO: us-smtp-1.mimecast.com Received: from us-smtp-delivery-1.mimecast.com (HELO us-smtp-1.mimecast.com) (207.211.31.120) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 15 Nov 2019 19:56:59 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573847817; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type; bh=DJdGN/pBqi4TIWNuCtz89bCjaT+MX6ttYtgvYGwndMg=; b=SY+8dcDHVlW63intVtBU1SXLeraMl+DvPnX6HevYylPHRyARyXO1F+W9OyCY8UA+sJFQne kqwhREmBEP1lypATX9pTqpl7urDdR1Sbk4gwulLCZmO0X2572GHwDa7Ousan8w0JrnunYu FiOlvFpArGYvMyHHqln50hDq5UraQU0= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-237-PyKXN5lyOMWNYVJw_XWQnw-1; Fri, 15 Nov 2019 14:56:55 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id A1ECC1007282; Fri, 15 Nov 2019 19:56:54 +0000 (UTC) Received: from localhost (unknown [10.33.36.113]) by smtp.corp.redhat.com (Postfix) with ESMTP id 39B8B1036C80; Fri, 15 Nov 2019 19:56:54 +0000 (UTC) Date: Fri, 15 Nov 2019 19:57:00 -0000 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] libstdc++: Implement LWG 3070 in path::lexically_relative Message-ID: <20191115195654.GA3572@redhat.com> MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.12.1 (2019-06-15) X-Mimecast-Spam-Score: 0 Content-Type: multipart/mixed; boundary="G4iJoqBmSsgzjUCe" Content-Disposition: inline X-IsSubscribed: yes X-SW-Source: 2019-11/txt/msg00039.txt.bz2 --G4iJoqBmSsgzjUCe Content-Type: text/plain; charset=WINDOWS-1252; format=flowed Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-length: 395 * src/c++17/fs_path.cc [_GLIBCXX_FILESYSTEM_IS_WINDOWS] (is_disk_designator): New helper function. (path::_Parser::root_path()): Use is_disk_designator. (path::lexically_relative(const path&)): Implement resolution of LWG 3070. * testsuite/27_io/filesystem/path/generation/relative.cc: Check with path components that look like a root-name. Tested x86_64-mingw-w64, committed to trunk. --G4iJoqBmSsgzjUCe Content-Type: text/plain; charset=WINDOWS-1252 Content-Disposition: attachment; filename="patch.txt" Content-Transfer-Encoding: quoted-printable Content-length: 3418 commit 737cef7acaa65e12e106073e8a7dbdf91356a484 Author: Jonathan Wakely Date: Fri Nov 15 15:24:23 2019 +0000 libstdc++: Implement LWG 3070 in path::lexically_relative =20=20=20=20 * src/c++17/fs_path.cc [_GLIBCXX_FILESYSTEM_IS_WINDOWS] (is_disk_designator): New helper function. (path::_Parser::root_path()): Use is_disk_designator. (path::lexically_relative(const path&)): Implement resolution of LWG 3070. * testsuite/27_io/filesystem/path/generation/relative.cc: Check= with path components that look like a root-name. diff --git a/libstdc++-v3/src/c++17/fs_path.cc b/libstdc++-v3/src/c++17/fs_= path.cc index 14842452354..5fba971fef6 100644 --- a/libstdc++-v3/src/c++17/fs_path.cc +++ b/libstdc++-v3/src/c++17/fs_path.cc @@ -47,6 +47,13 @@ static inline bool is_dir_sep(path::value_type ch) #endif } =20 +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS +static inline bool is_disk_designator(std::wstring_view s) +{ + return s.length() =3D=3D 2 && s[1] =3D=3D L':'; +} +#endif + struct path::_Parser { using string_view_type =3D std::basic_string_view; @@ -117,7 +124,7 @@ struct path::_Parser ++pos; } #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - else if (len > 1 && input[1] =3D=3D L':') + else if (is_disk_designator(input.substr(0, 2))) { // got disk designator root.first.str =3D input.substr(0, 2); @@ -1747,6 +1754,19 @@ path::lexically_relative(const path& base) const if (!has_root_directory() && base.has_root_directory()) return ret; auto [a, b] =3D std::mismatch(begin(), end(), base.begin(), base.end()); +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3070. path::lexically_relative causes surprising results if a filename + // can also be a root-name + if (!empty()) + for (auto& p : _M_cmpts) + if (p._M_type() =3D=3D _Type::_Filename && is_disk_designator(p.nati= ve())) + return ret; + if (!base.empty()) + for (auto i =3D b, end =3D base.end(); i !=3D end; ++i) + if (i->_M_type() =3D=3D _Type::_Filename && is_disk_designator(i->na= tive())) + return ret; +#endif if (a =3D=3D end() && b =3D=3D base.end()) ret =3D "."; else diff --git a/libstdc++-v3/testsuite/27_io/filesystem/path/generation/relati= ve.cc b/libstdc++-v3/testsuite/27_io/filesystem/path/generation/relative.cc index dde08d46f2c..b2ac27293b2 100644 --- a/libstdc++-v3/testsuite/27_io/filesystem/path/generation/relative.cc +++ b/libstdc++-v3/testsuite/27_io/filesystem/path/generation/relative.cc @@ -77,10 +77,26 @@ test03() compare_paths( path("/dir/.").lexically_relative("/dir/."), "." ); } =20 +void +test04() +{ +#if defined(__MING32__) || defined(__MINGW64__) + // DR 3070 + compare_paths(path("c:/f:o/bar").lexically_relative("c:/f:o/bar"), "."); + compare_paths(path("c:/foo/bar").lexically_relative("c:/foo/b:r"), "..\\= bar"); + compare_paths(path("c:/foo/b:r").lexically_relative("c:/foo/bar"), "..\\= b:r"); + compare_paths(path("c:/foo/b:").lexically_relative("c:/foo/b:"), ""); + compare_paths(path("c:/foo/bar").lexically_relative("c:/foo/b:"), ""); + compare_paths(path("c:/f:/bar").lexically_relative("c:/foo/bar"), ""); + compare_paths(path("foo/bar").lexically_relative("foo/b:/bar"), ""); +#endif +} + int main() { test01(); test02(); test03(); + test04(); } --G4iJoqBmSsgzjUCe--