Nix 2.26.3
Nix, the purely functional package manager; unstable internal interfaces
 
Loading...
Searching...
No Matches
file-path-impl.hh
Go to the documentation of this file.
1#pragma once
8#include <string>
9#include <string_view>
10
11namespace nix {
12
20{
21 using CharT = char;
22
23 using String = std::string;
24
25 using StringView = std::string_view;
26
27 constexpr static char preferredSep = '/';
28
29 static inline bool isPathSep(char c)
30 {
31 return c == '/';
32 }
33
34 static inline size_t findPathSep(StringView path, size_t from = 0)
35 {
36 return path.find('/', from);
37 }
38
39 static inline size_t rfindPathSep(StringView path, size_t from = StringView::npos)
40 {
41 return path.rfind('/', from);
42 }
43};
44
45
58template<class CharT0>
60{
61 using CharT = CharT0;
62
63 using String = std::basic_string<CharT>;
64
65 using StringView = std::basic_string_view<CharT>;
66
67 constexpr static CharT preferredSep = '\\';
68
69 static inline bool isPathSep(CharT c)
70 {
71 return c == '/' || c == preferredSep;
72 }
73
74 static size_t findPathSep(StringView path, size_t from = 0)
75 {
76 size_t p1 = path.find('/', from);
77 size_t p2 = path.find(preferredSep, from);
78 return p1 == String::npos ? p2 :
79 p2 == String::npos ? p1 :
80 std::min(p1, p2);
81 }
82
83 static size_t rfindPathSep(StringView path, size_t from = String::npos)
84 {
85 size_t p1 = path.rfind('/', from);
86 size_t p2 = path.rfind(preferredSep, from);
87 return p1 == String::npos ? p2 :
88 p2 == String::npos ? p1 :
89 std::max(p1, p2);
90 }
91};
92
93
94template<typename CharT>
95using OsPathTrait =
96#ifdef _WIN32
98#else
100#endif
101 ;
102
103
118template<class PathDict>
119typename PathDict::String canonPathInner(
120 typename PathDict::StringView remaining,
121 auto && hookComponent)
122{
123 assert(remaining != "");
124
125 typename PathDict::String result;
126 result.reserve(256);
127
128 while (true) {
129
130 /* Skip slashes. */
131 while (!remaining.empty() && PathDict::isPathSep(remaining[0]))
132 remaining.remove_prefix(1);
133
134 if (remaining.empty()) break;
135
136 auto nextComp = ({
137 auto nextPathSep = PathDict::findPathSep(remaining);
138 nextPathSep == remaining.npos ? remaining : remaining.substr(0, nextPathSep);
139 });
140
141 /* Ignore `.'. */
142 if (nextComp == ".")
143 remaining.remove_prefix(1);
144
145 /* If `..', delete the last component. */
146 else if (nextComp == "..")
147 {
148 if (!result.empty()) result.erase(PathDict::rfindPathSep(result));
149 remaining.remove_prefix(2);
150 }
151
152 /* Normal component; copy it. */
153 else {
154 result += PathDict::preferredSep;
155 if (const auto slash = PathDict::findPathSep(remaining); slash == result.npos) {
156 result += remaining;
157 remaining = {};
158 } else {
159 result += remaining.substr(0, slash);
160 remaining = remaining.substr(slash);
161 }
162
163 hookComponent(result, remaining);
164 }
165 }
166
167 if (result.empty())
168 result = typename PathDict::String { PathDict::preferredSep };
169
170 return result;
171}
172
173}
PathDict::String canonPathInner(typename PathDict::StringView remaining, auto &&hookComponent)
Definition file-path-impl.hh:119
char
Definition lexer.l:3739
std::string std::string_view from
Definition lexer.l:2591
Definition file-path-impl.hh:20
Definition file-path-impl.hh:60