Files
fennec/source/fproc/io/common.cpp
Medusa Slockbower 6ae682aff6 - Removed a bug with attempt to include pure c headers
- Added some more information about the license
 - fennec::file implementation
2025-07-14 05:11:52 -04:00

268 lines
5.5 KiB
C++

// =====================================================================================================================
// fennec, a free and open source game engine
// Copyright © 2025 Medusa Slockbower
//
// This program 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 of the License, or
// (at your option) any later version.
//
// This program 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 program. If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================
#include <fennec/fproc/io/common.h>
#ifdef _WIN32
namespace fennec
{
string getcwd() {
char cstr[MAX_PATH];
if (GetCurrentDirectory(sizeof(str), str) == 0) {
return string("");
}
string result(cstr);
return result;
}
}
#else
#include <unistd.h>
#include <linux/limits.h>
namespace fennec
{
string getcwd() {
char cstr[PATH_MAX];
if (::getcwd(cstr, sizeof(cstr)) == NULL) {
return string("");
}
return string(cstr, strlen(cstr));
}
string absolute(const cstring& path) {
// first determine if this is already an absolute path
#ifdef _WIN32
if (path[1] == ':') {
return path;
}
#else
if (path[0] == '/') {
return path;
}
#endif
string parse = path;
string res = getcwd();
size_t len = res.length();
#ifdef _WIN32
if (res[len - 1] == '/' || res[len - 1] == '\\') {
#else
if (res[len - 1] == '/') {
#endif
res = res.substring(0, len);
}
while (parse.size() > 1) {
// Parse for relative symbols
while (parse[0] == '.') {
#ifdef _WIN32
// up
if (parse[1] == '.' && (parse[2] == '/' || parse[2] == '\\')) {
size_t r = res.rfind('/');
size_t l = res.rfind('\\');
size_t size = res.size();
if (r == size) {
size = l;
}
else if (l == size) {
size = r;
}
else {
size = max(r, l);
}
size = max(size, 1);
res = res.substring(0, size);
}
// rel
else if (parse[1] == '/' || parse[1] == '\\') {
parse = parse.substring(2);
}
#else
// up
if (parse[1] == '.' && parse[2] == '/') {
size_t r = res.rfind('/');
res = res.substring(0, max(res.rfind('/'), static_cast<size_t>(1)));
parse = parse.substring(2);
}
// rel
else if (parse[1] == '/') {
parse = parse.substring(1);
}
#endif
else {
break;
}
}
// get the pos of the first directory separator
#ifdef _WIN32
size_t pos = min(parse.find('\\', 1), parse.find('/', 1));
#else
size_t pos = parse.find('/', 1);
size_t off = 0;
#endif
if (pos != parse.size()) {
if (parse[pos + 1] == '.') {
if (parse[pos + 2] == '/') {
off = 1;
}
else if (parse[pos + 2] == '.' && parse[pos + 3] == '/') {
off = 1;
}
}
else if (parse[pos + 1] == '/') {
off = 1;
}
}
// add this part
string sub = parse.substring(0, pos);
parse = parse.substring(pos + off);
res += sub;
}
return res;
}
string absolute(const string& path) {
// first determine if this is already an absolute path
#ifdef _WIN32
if (path[1] == ':') {
return path;
}
#else
if (path[0] == '/') {
return path;
}
#endif
string parse = path;
string res = getcwd();
size_t len = res.length();
#ifdef _WIN32
if (res[len - 1] == '/' || res[len - 1] == '\\') {
#else
if (res[len - 1] == '/') {
#endif
res = res.substring(0, len);
}
while (parse.size() > 1) {
// Parse for relative symbols
while (parse[0] == '.') {
#ifdef _WIN32
// up
if (parse[1] == '.' && (parse[2] == '/' || parse[2] == '\\')) {
size_t r = res.rfind('/');
size_t l = res.rfind('\\');
size_t size = res.size();
if (r == size) {
size = l;
}
else if (l == size) {
size = r;
}
else {
size = max(r, l);
}
size = max(size, 1);
res = res.substring(0, size);
}
// rel
else if (parse[1] == '/' || parse[1] == '\\') {
parse = parse.substring(2);
}
#else
// up
if (parse[1] == '.' && parse[2] == '/') {
size_t r = res.rfind('/');
res = res.substring(0, max(res.rfind('/'), static_cast<size_t>(1)));
parse = parse.substring(2);
}
// rel
else if (parse[1] == '/') {
parse = parse.substring(1);
}
#endif
else {
break;
}
}
// get the pos of the first directory separator
#ifdef _WIN32
size_t pos = min(parse.find('\\', 1), parse.find('/', 1));
size_t off = 0;
if (pos != parse.size()) {
if (parse[pos + 1] == '.') {
if (parse[pos + 2] == '/' || parse[pos + 2] == '\\') {
off = 1;
}
else if (parse[pos + 2] == '.' && (parse[pos + 3] == '/' || parse[pos + 3] == '\\')) {
off = 1;
}
}
else if (parse[pos + 1] == '/' || parse[pos + 1] == '\\') {
off = 1;
}
}
#else
size_t pos = parse.find('/', 1);
size_t off = 0;
if (pos != parse.size()) {
if (parse[pos + 1] == '.') {
if (parse[pos + 2] == '/') {
off = 1;
}
else if (parse[pos + 2] == '.' && parse[pos + 3] == '/') {
off = 1;
}
}
else if (parse[pos + 1] == '/') {
off = 1;
}
}
#endif
// add this part
string sub = parse.substring(0, pos);
parse = parse.substring(pos + off);
res += sub;
}
return res;
}
#endif
}