1// -*- C++ -*- 2// Filesystem utils for the C++ library testsuite. 3// 4// Copyright (C) 2014-2015 Free Software Foundation, Inc. 5// 6// This file is part of the GNU ISO C++ Library. This library is free 7// software; you can redistribute it and/or modify it under the 8// terms of the GNU General Public License as published by the 9// Free Software Foundation; either version 3, or (at your option) 10// any later version. 11// 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15// GNU General Public License for more details. 16// 17// You should have received a copy of the GNU General Public License along 18// with this library; see the file COPYING3. If not see 19// <http://www.gnu.org/licenses/>. 20// 21 22#ifndef _TESTSUITE_FS_H 23#define _TESTSUITE_FS_H 1 24 25#include <experimental/filesystem> 26#include <iostream> 27#include <string> 28#include <cstdio> 29#include <stdlib.h> 30#include <unistd.h> 31 32namespace __gnu_test 33{ 34#define PATH_CHK(p1, p2, fn) \ 35 if ( p1.fn() != p2.fn() ) \ 36 throw std::experimental::filesystem::filesystem_error( #fn, p1, p2, \ 37 std::make_error_code(std::errc::invalid_argument) ) 38 39 void 40 compare_paths(const std::experimental::filesystem::path& p1, 41 const std::experimental::filesystem::path& p2) 42 { 43 // std::cout << "Comparing " << p1 << " and " << p2 << std::endl; 44 PATH_CHK( p1, p2, string ); 45 PATH_CHK( p1, p2, empty ); 46 PATH_CHK( p1, p2, has_root_path ); 47 PATH_CHK( p1, p2, has_root_name ); 48 PATH_CHK( p1, p2, has_root_directory ); 49 PATH_CHK( p1, p2, has_relative_path ); 50 PATH_CHK( p1, p2, has_parent_path ); 51 PATH_CHK( p1, p2, has_filename ); 52 PATH_CHK( p1, p2, has_stem ); 53 PATH_CHK( p1, p2, has_extension ); 54 PATH_CHK( p1, p2, is_absolute ); 55 PATH_CHK( p1, p2, is_relative ); 56 auto d1 = std::distance(p1.begin(), p1.end()); 57 auto d2 = std::distance(p2.begin(), p2.end()); 58 if( d1 != d2 ) 59 throw std::experimental::filesystem::filesystem_error( 60 "distance(begin, end)", p1, p2, 61 std::make_error_code(std::errc::invalid_argument) ); 62 } 63 64 const std::string test_paths[] = { 65 "", "/", "//", "/.", "/./", "/a", "/a/", "/a//", "/a/b/c/d", "/a//b", 66 "a", "a/b", "a/b/", "a/b/c", "a/b/c.d", "a/b/..", "a/b/c.", "a/b/.c" 67 }; 68 69 // This is NOT supposed to be a secure way to get a unique name! 70 // We just need a path that doesn't exist for testing purposes. 71 std::experimental::filesystem::path 72 nonexistent_path() 73 { 74 std::experimental::filesystem::path p; 75#if defined(_GNU_SOURCE) || _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L 76 char tmp[] = "test.XXXXXX"; 77 int fd = ::mkstemp(tmp); 78 if (fd == -1) 79 throw std::experimental::filesystem::filesystem_error("mkstemp failed", 80 std::error_code(errno, std::generic_category())); 81 ::unlink(tmp); 82 ::close(fd); 83 p = tmp; 84#else 85 char buf[64]; 86 static int counter; 87 std::sprintf(buf, "filesystem-ts-test.%d.%lu", counter++, 88 (unsigned long) ::getpid()); 89 p = buf; 90#endif 91 return p; 92 } 93 94} // namespace __gnu_test 95#endif 96