2
0

path.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * Copyright (c) 2012-2018 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/dbartolini/crown/blob/master/LICENSE
  4. */
  5. #include "core/filesystem/path.h"
  6. #include "core/platform.h"
  7. #include "core/strings/dynamic_string.h"
  8. #include <ctype.h> // isalpha
  9. #include <string.h> // strrchr
  10. namespace crown
  11. {
  12. #if CROWN_PLATFORM_POSIX
  13. const char PATH_SEPARATOR = '/';
  14. #elif CROWN_PLATFORM_WINDOWS
  15. const char PATH_SEPARATOR = '\\';
  16. #endif // CROWN_PLATFORM_POSIX
  17. namespace path
  18. {
  19. bool is_absolute(const char* path)
  20. {
  21. CE_ENSURE(NULL != path);
  22. #if CROWN_PLATFORM_POSIX
  23. return strlen32(path) > 0
  24. && path[0] == PATH_SEPARATOR
  25. ;
  26. #elif CROWN_PLATFORM_WINDOWS
  27. return strlen32(path) > 2
  28. && isalpha(path[0])
  29. && path[1] == ':'
  30. && path[2] == PATH_SEPARATOR
  31. ;
  32. #endif
  33. }
  34. bool is_relative(const char* path)
  35. {
  36. CE_ENSURE(NULL != path);
  37. return !is_absolute(path);
  38. }
  39. bool is_root(const char* path)
  40. {
  41. CE_ENSURE(NULL != path);
  42. #if CROWN_PLATFORM_POSIX
  43. return is_absolute(path) && strlen32(path) == 1;
  44. #elif CROWN_PLATFORM_WINDOWS
  45. return is_absolute(path) && strlen32(path) == 3;
  46. #endif
  47. }
  48. void join(DynamicString& path, const char* path_a, const char* path_b)
  49. {
  50. CE_ENSURE(NULL != path_a);
  51. CE_ENSURE(NULL != path_b);
  52. const u32 la = strlen32(path_a);
  53. const u32 lb = strlen32(path_b);
  54. path.reserve(la + lb + 1);
  55. path = path_a;
  56. if (la != 0 && lb != 0)
  57. path += PATH_SEPARATOR;
  58. path += path_b;
  59. }
  60. const char* basename(const char* path)
  61. {
  62. CE_ENSURE(NULL != path);
  63. const char* ls = strrchr(path, '/');
  64. return ls == NULL ? path : ls + 1;
  65. }
  66. const char* extension(const char* path)
  67. {
  68. CE_ENSURE(NULL != path);
  69. const char* ld = strrchr(path, '.');
  70. return ld == NULL ? NULL : ld + 1;
  71. }
  72. bool has_trailing_separator(const char* path)
  73. {
  74. CE_ENSURE(NULL != path);
  75. return path[strlen32(path) - 1] == PATH_SEPARATOR;
  76. }
  77. inline bool any_separator(char c)
  78. {
  79. return c == '/' || c == '\\';
  80. }
  81. void reduce(DynamicString& clean, const char* path)
  82. {
  83. if (path == NULL)
  84. return;
  85. char cc = any_separator(*path) ? PATH_SEPARATOR : *path;
  86. clean += cc;
  87. ++path;
  88. for (; *path; ++path)
  89. {
  90. if (cc == PATH_SEPARATOR && any_separator(*path))
  91. continue;
  92. cc = any_separator(*path) ? PATH_SEPARATOR : *path;
  93. clean += cc;
  94. }
  95. if (has_trailing_separator(clean.c_str()))
  96. array::pop_back(clean._data);
  97. }
  98. } // namespace path
  99. } // namespace crown