src_root.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #pragma once
  2. #include "compiler.h"
  3. #include "defaults.h"
  4. #include <type_traits>
  5. namespace NPrivate {
  6. struct TStaticBuf {
  7. constexpr TStaticBuf(const char* data, unsigned len) noexcept
  8. : Data(data)
  9. , Len(len)
  10. {
  11. }
  12. template <class T>
  13. constexpr T As() const noexcept {
  14. return T(Data, Len);
  15. }
  16. template <class T>
  17. constexpr operator T() const noexcept {
  18. return this->As<T>();
  19. }
  20. const char* Data;
  21. unsigned Len;
  22. };
  23. #define STATIC_BUF(x) ::NPrivate::TStaticBuf(x, sizeof(x) - 1)
  24. constexpr TStaticBuf ArcRoot = STATIC_BUF(Y_STRINGIZE(ARCADIA_ROOT));
  25. constexpr TStaticBuf BuildRoot = STATIC_BUF(Y_STRINGIZE(ARCADIA_BUILD_ROOT));
  26. constexpr Y_FORCE_INLINE bool IsProperPrefix(const TStaticBuf prefix, const TStaticBuf string) noexcept {
  27. if (prefix.Len < string.Len) {
  28. for (unsigned i = prefix.Len; i-- > 0;) {
  29. if (prefix.Data[i] != string.Data[i]) {
  30. #if defined(_MSC_VER) && !defined(__clang__)
  31. // cl.exe uses back slashes for __FILE__ but ARCADIA_ROOT, ARCADIA_BUILD_ROOT are
  32. // defined with forward slashes
  33. if ((prefix.Data[i] == '/') && (string.Data[i] == '\\')) {
  34. continue;
  35. }
  36. #endif
  37. return false;
  38. }
  39. }
  40. return true;
  41. } else {
  42. return false;
  43. }
  44. }
  45. constexpr unsigned RootPrefixLength(const TStaticBuf& f) noexcept {
  46. if (IsProperPrefix(ArcRoot, f)) {
  47. return ArcRoot.Len + 1;
  48. }
  49. if (IsProperPrefix(BuildRoot, f)) {
  50. return BuildRoot.Len + 1;
  51. }
  52. return 0;
  53. }
  54. constexpr Y_FORCE_INLINE TStaticBuf StripRoot(const TStaticBuf& f, unsigned prefixLength) noexcept {
  55. return TStaticBuf(f.Data + prefixLength, f.Len - prefixLength);
  56. }
  57. //$(SRC_ROOT)/prj/blah.cpp -> prj/blah.cpp
  58. constexpr Y_FORCE_INLINE TStaticBuf StripRoot(const TStaticBuf& f) noexcept {
  59. return StripRoot(f, RootPrefixLength(f));
  60. }
  61. } // namespace NPrivate
  62. #define __SOURCE_FILE_IMPL__ ::NPrivate::StripRoot(STATIC_BUF(__FILE__), std::integral_constant<unsigned, ::NPrivate::RootPrefixLength(STATIC_BUF(__FILE__))>::value)