mirror of
https://github.com/id-Software/GtkRadiant.git
synced 2026-03-20 08:59:32 +01:00
The GtkRadiant sources as originally released under the GPL license.
This commit is contained in:
23
libs/os/dir.cpp
Normal file
23
libs/os/dir.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "dir.h"
|
||||
|
||||
75
libs/os/dir.h
Normal file
75
libs/os/dir.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(INCLUDED_OS_DIR_H)
|
||||
#define INCLUDED_OS_DIR_H
|
||||
|
||||
/// \file
|
||||
/// \brief OS directory-listing object.
|
||||
|
||||
#include <glib/gdir.h>
|
||||
|
||||
typedef GDir Directory;
|
||||
|
||||
inline bool directory_good(Directory* directory)
|
||||
{
|
||||
return directory != 0;
|
||||
}
|
||||
|
||||
inline Directory* directory_open(const char* name)
|
||||
{
|
||||
return g_dir_open(name, 0, 0);
|
||||
}
|
||||
|
||||
inline void directory_close(Directory* directory)
|
||||
{
|
||||
g_dir_close(directory);
|
||||
}
|
||||
|
||||
inline const char* directory_read_and_increment(Directory* directory)
|
||||
{
|
||||
return g_dir_read_name(directory);
|
||||
}
|
||||
|
||||
template<typename Functor>
|
||||
void Directory_forEach(const char* path, const Functor& functor)
|
||||
{
|
||||
Directory* dir = directory_open(path);
|
||||
|
||||
if(directory_good(dir))
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
const char* name = directory_read_and_increment(dir);
|
||||
if(name == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
functor(name);
|
||||
}
|
||||
|
||||
directory_close(dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
23
libs/os/file.cpp
Normal file
23
libs/os/file.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "file.h"
|
||||
|
||||
143
libs/os/file.h
Normal file
143
libs/os/file.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined(INCLUDED_OS_FILE_H)
|
||||
#define INCLUDED_OS_FILE_H
|
||||
|
||||
/// \file
|
||||
/// \brief OS file-system querying and manipulation.
|
||||
|
||||
#if defined( WIN32 )
|
||||
#define S_ISDIR(mode) (mode & _S_IFDIR)
|
||||
#include <io.h> // access()
|
||||
#define F_OK 0x00
|
||||
#define W_OK 0x02
|
||||
#define R_OK 0x04
|
||||
#else
|
||||
#include <unistd.h> // access()
|
||||
#endif
|
||||
|
||||
#include <stdio.h> // rename(), remove()
|
||||
#include <sys/stat.h> // stat()
|
||||
#include <sys/types.h> // this is included by stat.h on win32
|
||||
#include <cstddef>
|
||||
#include <ctime>
|
||||
|
||||
/// \brief Attempts to move the file identified by \p from to \p to and returns true if the operation was successful.
|
||||
///
|
||||
/// The operation will fail unless:
|
||||
/// - The path \p from identifies an existing file which is accessible for writing.
|
||||
/// - The directory component of \p from identifies an existing directory which is accessible for writing.
|
||||
/// - The path \p to does not identify an existing file or directory.
|
||||
/// - The directory component of \p to identifies an existing directory which is accessible for writing.
|
||||
inline bool file_move(const char* from, const char* to)
|
||||
{
|
||||
return rename(from, to) == 0;
|
||||
}
|
||||
|
||||
/// \brief Attempts to remove the file identified by \p path and returns true if the operation was successful.
|
||||
///
|
||||
/// The operation will fail unless:
|
||||
/// - The \p path identifies an existing file.
|
||||
/// - The parent-directory component of \p path identifies an existing directory which is accessible for writing.
|
||||
inline bool file_remove(const char* path)
|
||||
{
|
||||
return remove(path) == 0;
|
||||
}
|
||||
|
||||
namespace FileAccess
|
||||
{
|
||||
enum Mode
|
||||
{
|
||||
Read = R_OK,
|
||||
Write = W_OK,
|
||||
ReadWrite = Read | Write,
|
||||
Exists = F_OK
|
||||
};
|
||||
}
|
||||
|
||||
/// \brief Returns true if the file or directory identified by \p path exists and/or may be accessed for reading, writing or both, depending on the value of \p mode.
|
||||
inline bool file_accessible(const char* path, FileAccess::Mode mode)
|
||||
{
|
||||
return access(path, static_cast<int>(mode)) == 0;
|
||||
}
|
||||
|
||||
/// \brief Returns true if the file or directory identified by \p path exists and may be opened for reading.
|
||||
inline bool file_readable(const char* path)
|
||||
{
|
||||
return file_accessible(path, FileAccess::Read);
|
||||
}
|
||||
|
||||
/// \brief Returns true if the file or directory identified by \p path exists and may be opened for writing.
|
||||
inline bool file_writeable(const char* path)
|
||||
{
|
||||
return file_accessible(path, FileAccess::Write);
|
||||
}
|
||||
|
||||
/// \brief Returns true if the file or directory identified by \p path exists.
|
||||
inline bool file_exists(const char* path)
|
||||
{
|
||||
return file_accessible(path, FileAccess::Exists);
|
||||
}
|
||||
|
||||
/// \brief Returns true if the file or directory identified by \p path exists and is a directory.
|
||||
inline bool file_is_directory(const char* path)
|
||||
{
|
||||
struct stat st;
|
||||
if(stat(path, &st) == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return S_ISDIR (st.st_mode) != 0;
|
||||
}
|
||||
|
||||
typedef std::size_t FileSize;
|
||||
|
||||
/// \brief Returns the size in bytes of the file identified by \p path, or 0 if the file was not found.
|
||||
inline FileSize file_size(const char* path)
|
||||
{
|
||||
struct stat st;
|
||||
if(stat(path, &st) == -1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
/// Seconds elapsed since Jan 1, 1970
|
||||
typedef std::time_t FileTime;
|
||||
/// No file can have been modified earlier than this time.
|
||||
const FileTime c_invalidFileTime = -1;
|
||||
|
||||
/// \brief Returns the time that the file identified by \p path was last modified, or c_invalidFileTime if the file was not found.
|
||||
inline FileTime file_modified(const char* path)
|
||||
{
|
||||
struct stat st;
|
||||
if(stat(path, &st) == -1)
|
||||
{
|
||||
return c_invalidFileTime;
|
||||
}
|
||||
return st.st_mtime;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
22
libs/os/path.cpp
Normal file
22
libs/os/path.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "path.h"
|
||||
283
libs/os/path.h
Normal file
283
libs/os/path.h
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
Copyright (C) 2001-2006, William Joseph.
|
||||
All Rights Reserved.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if !defined (INCLUDED_OS_PATH_H)
|
||||
#define INCLUDED_OS_PATH_H
|
||||
|
||||
/// \file
|
||||
/// \brief OS file-system path comparison, decomposition and manipulation.
|
||||
///
|
||||
/// - Paths are c-style null-terminated-character-arrays.
|
||||
/// - Path separators must be forward slashes (unix style).
|
||||
/// - Directory paths must end in a separator.
|
||||
/// - Paths must not contain the ascii characters \\ : * ? " < > or |.
|
||||
/// - Paths may be encoded in UTF-8 or any extended-ascii character set.
|
||||
|
||||
#include "string/string.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#define OS_CASE_INSENSITIVE
|
||||
#endif
|
||||
|
||||
/// \brief Returns true if \p path is lexicographically sorted before \p other.
|
||||
/// If both \p path and \p other refer to the same file, neither will be sorted before the other.
|
||||
/// O(n)
|
||||
inline bool path_less(const char* path, const char* other)
|
||||
{
|
||||
#if defined(OS_CASE_INSENSITIVE)
|
||||
return string_less_nocase(path, other);
|
||||
#else
|
||||
return string_less(path, other);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// \brief Returns <0 if \p path is lexicographically less than \p other.
|
||||
/// Returns >0 if \p path is lexicographically greater than \p other.
|
||||
/// Returns 0 if both \p path and \p other refer to the same file.
|
||||
/// O(n)
|
||||
inline int path_compare(const char* path, const char* other)
|
||||
{
|
||||
#if defined(OS_CASE_INSENSITIVE)
|
||||
return string_compare_nocase(path, other);
|
||||
#else
|
||||
return string_compare(path, other);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// \brief Returns true if \p path and \p other refer to the same file or directory.
|
||||
/// O(n)
|
||||
inline bool path_equal(const char* path, const char* other)
|
||||
{
|
||||
#if defined(OS_CASE_INSENSITIVE)
|
||||
return string_equal_nocase(path, other);
|
||||
#else
|
||||
return string_equal(path, other);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// \brief Returns true if the first \p n bytes of \p path and \p other form paths that refer to the same file or directory.
|
||||
/// If the paths are UTF-8 encoded, [\p path, \p path + \p n) must be a complete path.
|
||||
/// O(n)
|
||||
inline bool path_equal_n(const char* path, const char* other, std::size_t n)
|
||||
{
|
||||
#if defined(OS_CASE_INSENSITIVE)
|
||||
return string_equal_nocase_n(path, other, n);
|
||||
#else
|
||||
return string_equal_n(path, other, n);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// \brief Returns true if \p path is a fully qualified file-system path.
|
||||
/// O(1)
|
||||
inline bool path_is_absolute(const char* path)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
return path[0] == '/'
|
||||
|| (path[0] != '\0' && path[1] == ':'); // local drive
|
||||
#elif defined(__linux__) || defined(__APPLE__)
|
||||
return path[0] == '/';
|
||||
#endif
|
||||
}
|
||||
|
||||
/// \brief Returns true if \p path is a directory.
|
||||
/// O(n)
|
||||
inline bool path_is_directory(const char* path)
|
||||
{
|
||||
std::size_t length = strlen(path);
|
||||
if(length > 0)
|
||||
{
|
||||
return path[length-1] == '/';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief Returns a pointer to the first character of the component of \p path following the first directory component.
|
||||
/// O(n)
|
||||
inline const char* path_remove_directory(const char* path)
|
||||
{
|
||||
const char* first_separator = strchr(path, '/');
|
||||
if(first_separator != 0)
|
||||
{
|
||||
return ++first_separator;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/// \brief Returns a pointer to the first character of the filename component of \p path.
|
||||
/// O(n)
|
||||
inline const char* path_get_filename_start(const char* path)
|
||||
{
|
||||
{
|
||||
const char* last_forward_slash = strrchr(path, '/');
|
||||
if(last_forward_slash != 0)
|
||||
{
|
||||
return last_forward_slash + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// not strictly necessary,since paths should not contain '\'
|
||||
{
|
||||
const char* last_backward_slash = strrchr(path, '\\');
|
||||
if(last_backward_slash != 0)
|
||||
{
|
||||
return last_backward_slash + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/// \brief Returns a pointer to the character after the end of the filename component of \p path - either the extension separator or the terminating null character.
|
||||
/// O(n)
|
||||
inline const char* path_get_filename_base_end(const char* path)
|
||||
{
|
||||
const char* last_period = strrchr(path_get_filename_start(path), '.');
|
||||
return (last_period != 0) ? last_period : path + string_length(path);
|
||||
}
|
||||
|
||||
/// \brief Returns the length of the filename component (not including extension) of \p path.
|
||||
/// O(n)
|
||||
inline std::size_t path_get_filename_base_length(const char* path)
|
||||
{
|
||||
return path_get_filename_base_end(path) - path;
|
||||
}
|
||||
|
||||
/// \brief If \p path is a child of \p base, returns the subpath relative to \p base, else returns \p path.
|
||||
/// O(n)
|
||||
inline const char* path_make_relative(const char* path, const char* base)
|
||||
{
|
||||
const std::size_t length = string_length(base);
|
||||
if(path_equal_n(path, base, length))
|
||||
{
|
||||
return path + length;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/// \brief Returns a pointer to the first character of the file extension of \p path, or "" if not found.
|
||||
/// O(n)
|
||||
inline const char* path_get_extension(const char* path)
|
||||
{
|
||||
const char* last_period = strrchr(path_get_filename_start(path), '.');
|
||||
if(last_period != 0)
|
||||
{
|
||||
return ++last_period;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/// \brief Returns true if \p extension is of the same type as \p other.
|
||||
/// O(n)
|
||||
inline bool extension_equal(const char* extension, const char* other)
|
||||
{
|
||||
return path_equal(extension, other);
|
||||
}
|
||||
|
||||
template<typename Functor>
|
||||
class MatchFileExtension
|
||||
{
|
||||
const char* m_extension;
|
||||
const Functor& m_functor;
|
||||
public:
|
||||
MatchFileExtension(const char* extension, const Functor& functor) : m_extension(extension), m_functor(functor)
|
||||
{
|
||||
}
|
||||
void operator()(const char* name) const
|
||||
{
|
||||
const char* extension = path_get_extension(name);
|
||||
if(extension_equal(extension, m_extension))
|
||||
{
|
||||
m_functor(name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A functor which invokes its contained \p functor if the \p name argument matches its \p extension.
|
||||
template<typename Functor>
|
||||
inline MatchFileExtension<Functor> matchFileExtension(const char* extension, const Functor& functor)
|
||||
{
|
||||
return MatchFileExtension<Functor>(extension, functor);
|
||||
}
|
||||
|
||||
class PathCleaned
|
||||
{
|
||||
public:
|
||||
const char* m_path;
|
||||
PathCleaned(const char* path) : m_path(path)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Writes \p path to \p ostream with dos-style separators replaced by unix-style separators.
|
||||
template<typename TextOutputStreamType>
|
||||
TextOutputStreamType& ostream_write(TextOutputStreamType& ostream, const PathCleaned& path)
|
||||
{
|
||||
const char* i = path.m_path;
|
||||
for(; *i != '\0'; ++i)
|
||||
{
|
||||
if(*i == '\\')
|
||||
{
|
||||
ostream << '/';
|
||||
}
|
||||
else
|
||||
{
|
||||
ostream << *i;
|
||||
}
|
||||
}
|
||||
return ostream;
|
||||
}
|
||||
|
||||
class DirectoryCleaned
|
||||
{
|
||||
public:
|
||||
const char* m_path;
|
||||
DirectoryCleaned(const char* path) : m_path(path)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Writes \p path to \p ostream with dos-style separators replaced by unix-style separators, and appends a separator if necessary.
|
||||
template<typename TextOutputStreamType>
|
||||
TextOutputStreamType& ostream_write(TextOutputStreamType& ostream, const DirectoryCleaned& path)
|
||||
{
|
||||
const char* i = path.m_path;
|
||||
for(; *i != '\0'; ++i)
|
||||
{
|
||||
if(*i == '\\')
|
||||
{
|
||||
ostream << '/';
|
||||
}
|
||||
else
|
||||
{
|
||||
ostream << *i;
|
||||
}
|
||||
}
|
||||
char c = *(i - 1);
|
||||
if(c != '/' && c != '\\')
|
||||
{
|
||||
ostream << '/';
|
||||
}
|
||||
return ostream;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user