Retro68/gcc/libstdc++-v3/testsuite/util/testsuite_fs.h

125 lines
3.6 KiB
C
Raw Normal View History

2017-04-10 11:32:00 +00:00
// -*- C++ -*-
// Filesystem utils for the C++ library testsuite.
//
2018-12-28 15:30:48 +00:00
// Copyright (C) 2014-2018 Free Software Foundation, Inc.
2017-04-10 11:32:00 +00:00
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
#ifndef _TESTSUITE_FS_H
#define _TESTSUITE_FS_H 1
2018-12-28 15:30:48 +00:00
// Assume we want std::filesystem in C++17, unless USE_FILESYSTEM_TS defined:
#if __cplusplus >= 201703L && ! defined USE_FILESYSTEM_TS
#include <filesystem>
namespace test_fs = std::filesystem;
#else
2017-04-10 11:32:00 +00:00
#include <experimental/filesystem>
2018-12-28 15:30:48 +00:00
namespace test_fs = std::experimental::filesystem;
#endif
2017-04-10 11:32:00 +00:00
#include <fstream>
#include <string>
#include <cstdio>
#include <stdlib.h>
#include <unistd.h>
namespace __gnu_test
{
#define PATH_CHK(p1, p2, fn) \
if ( p1.fn() != p2.fn() ) \
2018-12-28 15:30:48 +00:00
throw test_fs::filesystem_error("comparing '" #fn "' failed", p1, p2, \
2017-04-10 11:32:00 +00:00
std::make_error_code(std::errc::invalid_argument) )
void
2018-12-28 15:30:48 +00:00
compare_paths(const test_fs::path& p1,
const test_fs::path& p2)
2017-04-10 11:32:00 +00:00
{
2018-12-28 15:30:48 +00:00
PATH_CHK( p1, p2, native );
2017-04-10 11:32:00 +00:00
PATH_CHK( p1, p2, string );
PATH_CHK( p1, p2, empty );
PATH_CHK( p1, p2, has_root_path );
PATH_CHK( p1, p2, has_root_name );
PATH_CHK( p1, p2, has_root_directory );
PATH_CHK( p1, p2, has_relative_path );
PATH_CHK( p1, p2, has_parent_path );
PATH_CHK( p1, p2, has_filename );
PATH_CHK( p1, p2, has_stem );
PATH_CHK( p1, p2, has_extension );
PATH_CHK( p1, p2, is_absolute );
PATH_CHK( p1, p2, is_relative );
auto d1 = std::distance(p1.begin(), p1.end());
auto d2 = std::distance(p2.begin(), p2.end());
if( d1 != d2 )
2018-12-28 15:30:48 +00:00
throw test_fs::filesystem_error(
2017-04-10 11:32:00 +00:00
"distance(begin, end)", p1, p2,
std::make_error_code(std::errc::invalid_argument) );
}
const std::string test_paths[] = {
"", "/", "//", "/.", "/./", "/a", "/a/", "/a//", "/a/b/c/d", "/a//b",
"a", "a/b", "a/b/", "a/b/c", "a/b/c.d", "a/b/..", "a/b/c.", "a/b/.c"
};
// This is NOT supposed to be a secure way to get a unique name!
// We just need a path that doesn't exist for testing purposes.
2018-12-28 15:30:48 +00:00
test_fs::path
2017-04-10 11:32:00 +00:00
nonexistent_path()
{
2018-12-28 15:30:48 +00:00
test_fs::path p;
2017-04-10 11:32:00 +00:00
#if defined(_GNU_SOURCE) || _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L
2018-12-28 15:30:48 +00:00
char tmp[] = "filesystem-test.XXXXXX";
2017-04-10 11:32:00 +00:00
int fd = ::mkstemp(tmp);
if (fd == -1)
2018-12-28 15:30:48 +00:00
throw test_fs::filesystem_error("mkstemp failed",
2017-04-10 11:32:00 +00:00
std::error_code(errno, std::generic_category()));
::unlink(tmp);
::close(fd);
p = tmp;
#else
char buf[64];
static int counter;
#if _GLIBCXX_USE_C99_STDIO
std::snprintf(buf, 64,
#else
std::sprintf(buf,
#endif
2018-12-28 15:30:48 +00:00
"filesystem-test.%d.%lu", counter++, (unsigned long) ::getpid());
2017-04-10 11:32:00 +00:00
p = buf;
#endif
return p;
}
// RAII helper to remove a file on scope exit.
struct scoped_file
{
2018-12-28 15:30:48 +00:00
using path_type = test_fs::path;
2017-04-10 11:32:00 +00:00
enum adopt_file_t { adopt_file };
explicit
scoped_file(const path_type& p = nonexistent_path()) : path(p)
{ std::ofstream{p.native()}; }
scoped_file(path_type p, adopt_file_t) : path(p) { }
~scoped_file() { if (!path.empty()) remove(path); }
path_type path;
};
} // namespace __gnu_test
#endif