| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- /*
- * Copyright (c) 2012-2014 Daniele Bartolini and individual contributors.
- * License: https://github.com/taylor001/crown/blob/master/LICENSE
- */
- #include "path.h"
- #include "platform.h"
- #include "string_utils.h"
- #include <ctype.h> // isalpha
- namespace crown
- {
- namespace path
- {
- #if CROWN_PLATFORM_POSIX
- const char SEPARATOR = '/';
- #elif CROWN_PLATFORM_WINDOWS
- const char SEPARATOR = '\\';
- #endif // CROWN_PLATFORM_POSIX
- bool is_absolute_path(const char* path)
- {
- CE_ASSERT(path != NULL, "Path must be != NULL");
- #if CROWN_PLATFORM_POSIX
- return strlen(path) > 0 && path[0] == SEPARATOR;
- #elif CROWN_PLATFORM_WINDOWS
- return strlen(path) > 2 && isalpha(path[0]) && path[1] == ':' && path[2] == SEPARATOR;
- #endif
- }
- bool is_root_path(const char* path)
- {
- CE_ASSERT(path != NULL, "Path must be != NULL");
- #if CROWN_PLATFORM_POSIX
- return is_absolute_path(path) && strlen(path) == 1;
- #elif CROWN_PLATFORM_WINDOWS
- return is_absolute_path(path) && strlen(path) == 3;
- #endif
- }
- void join(const char* p1, const char* p2, DynamicString& path)
- {
- path += p1;
- path += SEPARATOR;
- path += p2;
- }
- const char* normalize_path(const char* path)
- {
- #if CROWN_PLATFORM_POSIX
- static char norm[1024];
- char* cur = norm;
- while ((*path) != '\0')
- {
- if ((*path) == '\\')
- {
- (*cur) = SEPARATOR;
- }
- else
- {
- (*cur) = (*path);
- }
- path++;
- cur++;
- }
- return norm;
- #elif CROWN_PLATFORM_WINDOWS
- static char norm[1024];
- for (uint32_t i = 0; i < strlen(path)+1; i++)
- {
- if (path[i] == '/')
- {
- norm[i] = SEPARATOR;
- }
- else
- {
- norm[i] = path[i];
- }
- }
- return norm;
- #endif
- }
- /// Returns the pathname of the path.
- /// @note
- /// e.g. "/home/project/texture.tga" -> "/home/project"
- /// e.g. "/home/project" -> "/home"
- /// e.g. "/home" -> "/"
- /// e.g. "home" -> ""
- ///
- /// The @a path must be valid.
- void pathname(const char* path, char* str, size_t len)
- {
- CE_ASSERT(path != NULL, "Path must be != NULL");
- CE_ASSERT(str != NULL, "Str must be != NULL");
- const char* last_separator = find_last(path, '/');
- if (last_separator == end(path))
- {
- strncpy(str, "", len);
- }
- else
- {
- substring(begin(path), last_separator, str, len);
- }
- }
- /// Returns the filename of the path.
- /// @note
- /// e.g. "/home/project/texture.tga" -> "texture.tga"
- /// e.g. "/home/project/texture" -> "texture"
- /// e.g. "/home -> "home"
- /// e.g. "/" -> ""
- ///
- /// The @a path must be valid.
- void filename(const char* path, char* str, size_t len)
- {
- CE_ASSERT(path != NULL, "Path must be != NULL");
- CE_ASSERT(str != NULL, "Str must be != NULL");
- const char* last_separator = find_last(path, '/');
- if (last_separator == end(path))
- {
- strncpy(str, "", len);
- }
- else
- {
- substring(last_separator + 1, end(path), str, len);
- }
- }
- /// Returns the basename of the path.
- /// @note
- /// e.g. "/home/project/texture.tga" -> "texture"
- /// e.g. "/home/project" -> "project"
- /// e.g. "/" -> ""
- ///
- /// The @a path must be valid.
- void basename(const char* path, char* str, size_t len)
- {
- CE_ASSERT(path != NULL, "Path must be != NULL");
- CE_ASSERT(str != NULL, "Str must be != NULL");
- const char* last_separator = find_last(path, '/');
- const char* last_dot = find_last(path, '.');
- if (last_separator == end(path) && last_dot != end(path))
- {
- substring(begin(path), last_dot, str, len);
- }
- else if (last_separator != end(path) && last_dot == end(path))
- {
- substring(last_separator + 1, end(path), str, len);
- }
- else if (last_separator == end(path) && last_dot == end(path))
- {
- strncpy(str, path, len);
- }
- else
- {
- substring(last_separator + 1, last_dot, str, len);
- }
- }
- /// Returns the extension of the path.
- /// @note
- /// e.g. "/home/project/texture.tga" -> "tga"
- /// e.g. "/home/project.x/texture" -> ""
- ///
- /// The @a path must be valid.
- void extension(const char* path, char* str, size_t len)
- {
- CE_ASSERT(path != NULL, "Path must be != NULL");
- CE_ASSERT(str != NULL, "Str must be != NULL");
- const char* last_dot = find_last(path, '.');
- if (last_dot == end(path))
- {
- strncpy(str, "", len);
- }
- else
- {
- substring(last_dot + 1, end(path), str, len);
- }
- }
- /// Returns the filename without the extension.
- /// @note
- /// e.g. "/home/project/texture.tga" -> "/home/project/texture"
- /// e.g. "/home/project/texture" -> "/home/project/texture"
- ///
- /// The @a path must be valid.
- void filename_without_extension(const char* path, char* str, size_t len)
- {
- CE_ASSERT(path != NULL, "Path must be != NULL");
- CE_ASSERT(str != NULL, "Str must be != NULL");
- const char* last_dot = find_last(path, '.');
- substring(begin(path), last_dot, str, len);
- }
- /// Fills 'ret' with the same path but without the trailing directory separator.
- /// @note
- /// e.g. "/home/project/texture.tga/" -> "/home/project/texture.tga"
- /// e.g. "/home/project/texture.tga" -> "/home/project/texture.tga"
- ///
- /// The @a path must be valid.
- void strip_trailing_separator(const char* path, char* str, size_t len)
- {
- CE_ASSERT(path != NULL, "Path must be != NULL");
- CE_ASSERT(str != NULL, "Str must be != NULL");
- size_t path_len = strlen(path);
- if (path[path_len - 1] == '/')
- {
- substring(begin(path), end(path) - 2, str, len);
- }
- else
- {
- substring(begin(path), end(path), str, len);
- }
- }
- } // namespace path
- } // namespace crown
|