Disabled external gits

This commit is contained in:
2022-04-07 18:46:57 +02:00
parent 88cb3426ad
commit 15e7120d6d
5316 changed files with 4563444 additions and 6 deletions

5
cs440-acg/ext/filesystem/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
CMakeCache.txt
CMakeFiles
Makefile
cmake_install.cmake
path_demo

View File

@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 2.8)
project(path)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
# Enable C++11 mode on GCC / Clang
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
add_executable(path_demo path_demo.cpp filesystem/path.h filesystem/resolver.h)

View File

@@ -0,0 +1,36 @@
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>, All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You are under no obligation whatsoever to provide any bug fixes, patches, or
upgrades to the features, functionality or performance of the source code
("Enhancements") to anyone; however, if you choose to make your Enhancements
available either publicly, or directly to the author of this software, without
imposing a separate written license agreement for such Enhancements, then you
hereby grant the following license: a non-exclusive, royalty-free perpetual
license to install, use, modify, prepare derivative works, incorporate into
other computer software, distribute, and sublicense such enhancements or
derivative works thereof, in binary and source code form.

View File

@@ -0,0 +1,5 @@
#### filesystem/path.h: A simple class for manipulating paths on Linux/Windows/Mac OS
This class is just a temporary workaround to avoid the heavy boost dependency
until `boost::filesystem` is integrated into the standard template library at
some point in the future.

View File

@@ -0,0 +1,24 @@
/*
fwd.h -- Forward declarations for path.h and resolver.h
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE file.
*/
#pragma once
#if !defined(NAMESPACE_BEGIN)
#define NAMESPACE_BEGIN(name) namespace name {
#endif
#if !defined(NAMESPACE_END)
#define NAMESPACE_END(name) }
#endif
NAMESPACE_BEGIN(filesystem)
class path;
class resolver;
NAMESPACE_END(filesystem)

View File

@@ -0,0 +1,434 @@
/*
path.h -- A simple class for manipulating paths on Linux/Windows/Mac OS
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE file.
*/
#pragma once
#include "fwd.h"
#include <algorithm>
#include <string>
#include <vector>
#include <stdexcept>
#include <sstream>
#include <cctype>
#include <cstdlib>
#include <cerrno>
#include <cstring>
#if defined(_WIN32)
# include <windows.h>
# include <ShlObj.h>
#else
# include <unistd.h>
#endif
#include <sys/stat.h>
#if defined(__linux)
# include <linux/limits.h>
#endif
NAMESPACE_BEGIN(filesystem)
/**
* \brief Simple class for manipulating paths on Linux/Windows/Mac OS
*
* This class is just a temporary workaround to avoid the heavy boost
* dependency until boost::filesystem is integrated into the standard template
* library at some point in the future.
*/
class path {
public:
enum path_type {
windows_path = 0,
posix_path = 1,
#if defined(_WIN32)
native_path = windows_path
#else
native_path = posix_path
#endif
};
path() : m_type(native_path), m_absolute(false), m_smb(false) { }
path(const path &path)
: m_type(path.m_type), m_path(path.m_path), m_absolute(path.m_absolute), m_smb(path.m_smb) {}
path(path &&path)
: m_type(path.m_type), m_path(std::move(path.m_path)),
m_absolute(path.m_absolute), m_smb(path.m_smb) {}
path(const char *string) { set(string); }
path(const std::string &string) { set(string); }
#if defined(_WIN32)
path(const std::wstring &wstring) { set(wstring); }
path(const wchar_t *wstring) { set(wstring); }
#endif
size_t length() const { return m_path.size(); }
bool empty() const { return m_path.empty(); }
bool is_absolute() const { return m_absolute; }
path make_absolute() const {
#if !defined(_WIN32)
char temp[PATH_MAX];
if (realpath(str().c_str(), temp) == NULL)
throw std::runtime_error("Internal error in realpath(): " + std::string(strerror(errno)));
return path(temp);
#else
std::wstring value = wstr(), out(MAX_PATH_WINDOWS, '\0');
DWORD length = GetFullPathNameW(value.c_str(), MAX_PATH_WINDOWS, &out[0], NULL);
if (length == 0)
throw std::runtime_error("Internal error in realpath(): " + std::to_string(GetLastError()));
return path(out.substr(0, length));
#endif
}
bool exists() const {
#if defined(_WIN32)
return GetFileAttributesW(wstr().c_str()) != INVALID_FILE_ATTRIBUTES;
#else
struct stat sb;
return stat(str().c_str(), &sb) == 0;
#endif
}
size_t file_size() const {
#if defined(_WIN32)
struct _stati64 sb;
if (_wstati64(wstr().c_str(), &sb) != 0)
throw std::runtime_error("path::file_size(): cannot stat file \"" + str() + "\"!");
#else
struct stat sb;
if (stat(str().c_str(), &sb) != 0)
throw std::runtime_error("path::file_size(): cannot stat file \"" + str() + "\"!");
#endif
return (size_t) sb.st_size;
}
bool is_directory() const {
#if defined(_WIN32)
DWORD result = GetFileAttributesW(wstr().c_str());
if (result == INVALID_FILE_ATTRIBUTES)
return false;
return (result & FILE_ATTRIBUTE_DIRECTORY) != 0;
#else
struct stat sb;
if (stat(str().c_str(), &sb))
return false;
return S_ISDIR(sb.st_mode);
#endif
}
bool is_file() const {
#if defined(_WIN32)
DWORD attr = GetFileAttributesW(wstr().c_str());
return (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY) == 0);
#else
struct stat sb;
if (stat(str().c_str(), &sb))
return false;
return S_ISREG(sb.st_mode);
#endif
}
std::string extension() const {
const std::string &name = filename();
size_t pos = name.find_last_of(".");
if (pos == std::string::npos)
return "";
return name.substr(pos+1);
}
std::string filename() const {
if (empty())
return "";
const std::string &last = m_path[m_path.size()-1];
return last;
}
path parent_path() const {
path result;
result.m_absolute = m_absolute;
result.m_smb = m_smb;
if (m_path.empty()) {
if (!m_absolute)
result.m_path.push_back("..");
} else {
size_t until = m_path.size() - 1;
for (size_t i = 0; i < until; ++i)
result.m_path.push_back(m_path[i]);
}
return result;
}
path operator/(const path &other) const {
if (other.m_absolute)
throw std::runtime_error("path::operator/(): expected a relative path!");
if (m_type != other.m_type)
throw std::runtime_error("path::operator/(): expected a path of the same type!");
path result(*this);
for (size_t i=0; i<other.m_path.size(); ++i)
result.m_path.push_back(other.m_path[i]);
return result;
}
std::string str(path_type type = native_path) const {
std::ostringstream oss;
if (m_absolute) {
if (m_type == posix_path)
oss << "/";
else {
size_t length = 0;
for (size_t i = 0; i < m_path.size(); ++i)
// No special case for the last segment to count the NULL character
length += m_path[i].length() + 1;
if (m_smb)
length += 2;
// Windows requires a \\?\ prefix to handle paths longer than MAX_PATH
// (including their null character). NOTE: relative paths >MAX_PATH are
// not supported at all in Windows.
if (length > MAX_PATH_WINDOWS_LEGACY) {
if (m_smb)
oss << "\\\\?\\UNC\\";
else
oss << "\\\\?\\";
} else if (m_smb)
oss << "\\\\";
}
}
for (size_t i=0; i<m_path.size(); ++i) {
oss << m_path[i];
if (i+1 < m_path.size()) {
if (type == posix_path)
oss << '/';
else
oss << '\\';
}
}
return oss.str();
}
void set(const std::string &str, path_type type = native_path) {
m_type = type;
if (type == windows_path) {
std::string tmp = str;
// Long windows paths (sometimes) begin with the prefix \\?\. It should only
// be used when the path is >MAX_PATH characters long, so we remove it
// for convenience and add it back (if necessary) in str()/wstr().
static const std::string LONG_PATH_PREFIX = "\\\\?\\";
if (tmp.length() >= LONG_PATH_PREFIX.length()
&& std::mismatch(std::begin(LONG_PATH_PREFIX), std::end(LONG_PATH_PREFIX), std::begin(tmp)).first == std::end(LONG_PATH_PREFIX)) {
tmp.erase(0, LONG_PATH_PREFIX.length());
}
// Special-case handling of absolute SMB paths, which start with the prefix "\\".
if (tmp.length() >= 2 && tmp[0] == '\\' && tmp[1] == '\\') {
m_path = {};
tmp.erase(0, 2);
// Interestingly, there is a special-special case where relative paths may be specified as beginning with a "\\"
// when a non-SMB file with a more-than-260-characters-long absolute _local_ path is double-clicked. This seems to
// only happen with single-segment relative paths, so we can check for this condition by making sure no further
// path separators are present.
if (tmp.find_first_of("/\\") != std::string::npos)
m_absolute = m_smb = true;
else
m_absolute = m_smb = false;
// Special-case handling of absolute SMB paths, which start with the prefix "UNC\"
} else if (tmp.length() >= 4 && tmp[0] == 'U' && tmp[1] == 'N' && tmp[2] == 'C' && tmp[3] == '\\') {
m_path = {};
tmp.erase(0, 4);
m_absolute = true;
m_smb = true;
// Special-case handling of absolute local paths, which start with the drive letter and a colon "X:\"
} else if (tmp.length() >= 3 && std::isalpha(tmp[0]) && tmp[1] == ':' && (tmp[2] == '\\' || tmp[2] == '/')) {
m_path = {tmp.substr(0, 2)};
tmp.erase(0, 3);
m_absolute = true;
m_smb = false;
// Relative path
} else {
m_path = {};
m_absolute = false;
m_smb = false;
}
std::vector<std::string> tokenized = tokenize(tmp, "/\\");
m_path.insert(std::end(m_path), std::begin(tokenized), std::end(tokenized));
} else {
m_path = tokenize(str, "/");
m_absolute = !str.empty() && str[0] == '/';
}
}
path &operator=(const path &path) {
m_type = path.m_type;
m_path = path.m_path;
m_absolute = path.m_absolute;
m_smb = path.m_smb;
return *this;
}
path &operator=(path &&path) {
if (this != &path) {
m_type = path.m_type;
m_path = std::move(path.m_path);
m_absolute = path.m_absolute;
m_smb = path.m_smb;
}
return *this;
}
friend std::ostream &operator<<(std::ostream &os, const path &path) {
os << path.str();
return os;
}
bool remove_file() {
#if !defined(_WIN32)
return std::remove(str().c_str()) == 0;
#else
return DeleteFileW(wstr().c_str()) != 0;
#endif
}
bool resize_file(size_t target_length) {
#if !defined(_WIN32)
return ::truncate(str().c_str(), (off_t) target_length) == 0;
#else
HANDLE handle = CreateFileW(wstr().c_str(), GENERIC_WRITE, 0, nullptr, 0, FILE_ATTRIBUTE_NORMAL, nullptr);
if (handle == INVALID_HANDLE_VALUE)
return false;
LARGE_INTEGER size;
size.QuadPart = (LONGLONG) target_length;
if (SetFilePointerEx(handle, size, NULL, FILE_BEGIN) == 0) {
CloseHandle(handle);
return false;
}
if (SetEndOfFile(handle) == 0) {
CloseHandle(handle);
return false;
}
CloseHandle(handle);
return true;
#endif
}
static path getcwd() {
#if !defined(_WIN32)
char temp[PATH_MAX];
if (::getcwd(temp, PATH_MAX) == NULL)
throw std::runtime_error("Internal error in getcwd(): " + std::string(strerror(errno)));
return path(temp);
#else
std::wstring temp(MAX_PATH_WINDOWS, '\0');
if (!_wgetcwd(&temp[0], MAX_PATH_WINDOWS))
throw std::runtime_error("Internal error in getcwd(): " + std::to_string(GetLastError()));
return path(temp.c_str());
#endif
}
#if defined(_WIN32)
std::wstring wstr(path_type type = native_path) const {
std::string temp = str(type);
int size = MultiByteToWideChar(CP_UTF8, 0, &temp[0], (int)temp.size(), NULL, 0);
std::wstring result(size, 0);
MultiByteToWideChar(CP_UTF8, 0, &temp[0], (int)temp.size(), &result[0], size);
return result;
}
void set(const std::wstring &wstring, path_type type = native_path) {
std::string string;
if (!wstring.empty()) {
int size = WideCharToMultiByte(CP_UTF8, 0, &wstring[0], (int)wstring.size(),
NULL, 0, NULL, NULL);
string.resize(size, 0);
WideCharToMultiByte(CP_UTF8, 0, &wstring[0], (int)wstring.size(),
&string[0], size, NULL, NULL);
}
set(string, type);
}
path &operator=(const std::wstring &str) { set(str); return *this; }
#endif
bool operator==(const path &p) const { return p.m_path == m_path; }
bool operator!=(const path &p) const { return p.m_path != m_path; }
protected:
static std::vector<std::string> tokenize(const std::string &string, const std::string &delim) {
std::string::size_type lastPos = 0, pos = string.find_first_of(delim, lastPos);
std::vector<std::string> tokens;
while (lastPos != std::string::npos) {
if (pos != lastPos)
tokens.push_back(string.substr(lastPos, pos - lastPos));
lastPos = pos;
if (lastPos == std::string::npos || lastPos + 1 == string.length())
break;
pos = string.find_first_of(delim, ++lastPos);
}
return tokens;
}
protected:
#if defined(_WIN32)
static const size_t MAX_PATH_WINDOWS = 32767;
#endif
static const size_t MAX_PATH_WINDOWS_LEGACY = 260;
path_type m_type;
std::vector<std::string> m_path;
bool m_absolute;
bool m_smb; // Unused, except for on Windows
};
inline bool create_directory(const path& p) {
#if defined(_WIN32)
return CreateDirectoryW(p.wstr().c_str(), NULL) != 0;
#else
return mkdir(p.str().c_str(), S_IRWXU) == 0;
#endif
}
inline bool create_directories(const path& p) {
#if defined(_WIN32)
return SHCreateDirectory(nullptr, p.make_absolute().wstr().c_str()) == ERROR_SUCCESS;
#else
if (create_directory(p.str().c_str()))
return true;
if (p.empty())
return false;
if (errno == ENOENT) {
if (create_directory(p.parent_path()))
return mkdir(p.str().c_str(), S_IRWXU) == 0;
else
return false;
}
return false;
#endif
}
NAMESPACE_END(filesystem)

View File

@@ -0,0 +1,72 @@
/*
resolver.h -- A simple class for cross-platform path resolution
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE file.
*/
#pragma once
#include "path.h"
NAMESPACE_BEGIN(filesystem)
/**
* \brief Simple class for resolving paths on Linux/Windows/Mac OS
*
* This convenience class looks for a file or directory given its name
* and a set of search paths. The implementation walks through the
* search paths in order and stops once the file is found.
*/
class resolver {
public:
typedef std::vector<path>::iterator iterator;
typedef std::vector<path>::const_iterator const_iterator;
resolver() {
m_paths.push_back(path::getcwd());
}
size_t size() const { return m_paths.size(); }
iterator begin() { return m_paths.begin(); }
iterator end() { return m_paths.end(); }
const_iterator begin() const { return m_paths.begin(); }
const_iterator end() const { return m_paths.end(); }
void erase(iterator it) { m_paths.erase(it); }
void prepend(const path &path) { m_paths.insert(m_paths.begin(), path); }
void append(const path &path) { m_paths.push_back(path); }
const path &operator[](size_t index) const { return m_paths[index]; }
path &operator[](size_t index) { return m_paths[index]; }
path resolve(const path &value) const {
for (const_iterator it = m_paths.begin(); it != m_paths.end(); ++it) {
path combined = *it / value;
if (combined.exists())
return combined;
}
return value;
}
friend std::ostream &operator<<(std::ostream &os, const resolver &r) {
os << "resolver[" << std::endl;
for (size_t i = 0; i < r.m_paths.size(); ++i) {
os << " \"" << r.m_paths[i] << "\"";
if (i + 1 < r.m_paths.size())
os << ",";
os << std::endl;
}
os << "]";
return os;
}
private:
std::vector<path> m_paths;
};
NAMESPACE_END(filesystem)

View File

@@ -0,0 +1,48 @@
#include <iostream>
#include "filesystem/path.h"
#include "filesystem/resolver.h"
using namespace std;
using namespace filesystem;
int main(int argc, char **argv) {
#if !defined(WIN32)
path path1("/dir 1/dir 2/");
#else
path path1("C:\\dir 1\\dir 2\\");
#endif
path path2("dir 3");
cout << path1.exists() << endl;
cout << path1 << endl;
cout << (path1/path2) << endl;
cout << (path1/path2).parent_path() << endl;
cout << (path1/path2).parent_path().parent_path() << endl;
cout << (path1/path2).parent_path().parent_path().parent_path() << endl;
cout << (path1/path2).parent_path().parent_path().parent_path().parent_path() << endl;
cout << path().parent_path() << endl;
cout << "some/path.ext:operator==() = " << (path("some/path.ext") == path("some/path.ext")) << endl;
cout << "some/path.ext:operator==() (unequal) = " << (path("some/path.ext") == path("another/path.ext")) << endl;
cout << "nonexistant:exists = " << path("nonexistant").exists() << endl;
cout << "nonexistant:is_file = " << path("nonexistant").is_file() << endl;
cout << "nonexistant:is_directory = " << path("nonexistant").is_directory() << endl;
cout << "nonexistant:filename = " << path("nonexistant").filename() << endl;
cout << "nonexistant:extension = " << path("nonexistant").extension() << endl;
cout << "filesystem/path.h:exists = " << path("filesystem/path.h").exists() << endl;
cout << "filesystem/path.h:is_file = " << path("filesystem/path.h").is_file() << endl;
cout << "filesystem/path.h:is_directory = " << path("filesystem/path.h").is_directory() << endl;
cout << "filesystem/path.h:filename = " << path("filesystem/path.h").filename() << endl;
cout << "filesystem/path.h:extension = " << path("filesystem/path.h").extension() << endl;
cout << "filesystem/path.h:make_absolute = " << path("filesystem/path.h").make_absolute() << endl;
cout << "../filesystem:exists = " << path("../filesystem").exists() << endl;
cout << "../filesystem:is_file = " << path("../filesystem").is_file() << endl;
cout << "../filesystem:is_directory = " << path("../filesystem").is_directory() << endl;
cout << "../filesystem:extension = " << path("../filesystem").extension() << endl;
cout << "../filesystem:filename = " << path("../filesystem").filename() << endl;
cout << "../filesystem:make_absolute = " << path("../filesystem").make_absolute() << endl;
cout << "resolve(filesystem/path.h) = " << resolver().resolve("filesystem/path.h") << endl;
cout << "resolve(nonexistant) = " << resolver().resolve("nonexistant") << endl;
return 0;
}