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