// ===================================================================================================================== // 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 . // ===================================================================================================================== #include #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 #include 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(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(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 }