/src/keystone/llvm/include/llvm/Support/Path.h
Line | Count | Source |
1 | | //===- llvm/Support/Path.h - Path Operating System Concept ------*- C++ -*-===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file declares the llvm_ks::sys::path namespace. It is designed after |
11 | | // TR2/boost filesystem (v3), but modified to remove exception handling and the |
12 | | // path class. |
13 | | // |
14 | | //===----------------------------------------------------------------------===// |
15 | | |
16 | | #ifndef LLVM_SUPPORT_PATH_H |
17 | | #define LLVM_SUPPORT_PATH_H |
18 | | |
19 | | #include "llvm/ADT/SmallString.h" |
20 | | #include "llvm/ADT/Twine.h" |
21 | | #include "llvm/Support/DataTypes.h" |
22 | | #include <iterator> |
23 | | |
24 | | namespace llvm_ks { |
25 | | namespace sys { |
26 | | namespace path { |
27 | | |
28 | | /// @name Lexical Component Iterator |
29 | | /// @{ |
30 | | |
31 | | /// @brief Path iterator. |
32 | | /// |
33 | | /// This is an input iterator that iterates over the individual components in |
34 | | /// \a path. The traversal order is as follows: |
35 | | /// * The root-name element, if present. |
36 | | /// * The root-directory element, if present. |
37 | | /// * Each successive filename element, if present. |
38 | | /// * Dot, if one or more trailing non-root slash characters are present. |
39 | | /// Traversing backwards is possible with \a reverse_iterator |
40 | | /// |
41 | | /// Iteration examples. Each component is separated by ',': |
42 | | /// @code |
43 | | /// / => / |
44 | | /// /foo => /,foo |
45 | | /// foo/ => foo,. |
46 | | /// /foo/bar => /,foo,bar |
47 | | /// ../ => ..,. |
48 | | /// C:\foo\bar => C:,/,foo,bar |
49 | | /// @endcode |
50 | | class const_iterator |
51 | | : public std::iterator<std::input_iterator_tag, const StringRef> { |
52 | | StringRef Path; ///< The entire path. |
53 | | StringRef Component; ///< The current component. Not necessarily in Path. |
54 | | size_t Position; ///< The iterators current position within Path. |
55 | | |
56 | | // An end iterator has Position = Path.size() + 1. |
57 | | friend const_iterator begin(StringRef path); |
58 | | friend const_iterator end(StringRef path); |
59 | | |
60 | | public: |
61 | 262k | reference operator*() const { return Component; } |
62 | 131k | pointer operator->() const { return &Component; } |
63 | | const_iterator &operator++(); // preincrement |
64 | | bool operator==(const const_iterator &RHS) const; |
65 | 131k | bool operator!=(const const_iterator &RHS) const { return !(*this == RHS); } |
66 | | |
67 | | /// @brief Difference in bytes between this and RHS. |
68 | | ptrdiff_t operator-(const const_iterator &RHS) const; |
69 | | }; |
70 | | |
71 | | /// @brief Reverse path iterator. |
72 | | /// |
73 | | /// This is an input iterator that iterates over the individual components in |
74 | | /// \a path in reverse order. The traversal order is exactly reversed from that |
75 | | /// of \a const_iterator |
76 | | class reverse_iterator |
77 | | : public std::iterator<std::input_iterator_tag, const StringRef> { |
78 | | StringRef Path; ///< The entire path. |
79 | | StringRef Component; ///< The current component. Not necessarily in Path. |
80 | | size_t Position; ///< The iterators current position within Path. |
81 | | |
82 | | friend reverse_iterator rbegin(StringRef path); |
83 | | friend reverse_iterator rend(StringRef path); |
84 | | |
85 | | public: |
86 | 0 | reference operator*() const { return Component; } |
87 | 0 | pointer operator->() const { return &Component; } |
88 | | reverse_iterator &operator++(); // preincrement |
89 | | bool operator==(const reverse_iterator &RHS) const; |
90 | 0 | bool operator!=(const reverse_iterator &RHS) const { return !(*this == RHS); } |
91 | | }; |
92 | | |
93 | | /// @brief Get begin iterator over \a path. |
94 | | /// @param path Input path. |
95 | | /// @returns Iterator initialized with the first component of \a path. |
96 | | const_iterator begin(StringRef path); |
97 | | |
98 | | /// @brief Get end iterator over \a path. |
99 | | /// @param path Input path. |
100 | | /// @returns Iterator initialized to the end of \a path. |
101 | | const_iterator end(StringRef path); |
102 | | |
103 | | /// @brief Get reverse begin iterator over \a path. |
104 | | /// @param path Input path. |
105 | | /// @returns Iterator initialized with the first reverse component of \a path. |
106 | | reverse_iterator rbegin(StringRef path); |
107 | | |
108 | | /// @brief Get reverse end iterator over \a path. |
109 | | /// @param path Input path. |
110 | | /// @returns Iterator initialized to the reverse end of \a path. |
111 | | reverse_iterator rend(StringRef path); |
112 | | |
113 | | /// @} |
114 | | /// @name Lexical Modifiers |
115 | | /// @{ |
116 | | |
117 | | /// @brief Remove the last component from \a path unless it is the root dir. |
118 | | /// |
119 | | /// @code |
120 | | /// directory/filename.cpp => directory/ |
121 | | /// directory/ => directory |
122 | | /// filename.cpp => <empty> |
123 | | /// / => / |
124 | | /// @endcode |
125 | | /// |
126 | | /// @param path A path that is modified to not have a file component. |
127 | | void remove_filename(SmallVectorImpl<char> &path); |
128 | | |
129 | | /// @brief Replace the file extension of \a path with \a extension. |
130 | | /// |
131 | | /// @code |
132 | | /// ./filename.cpp => ./filename.extension |
133 | | /// ./filename => ./filename.extension |
134 | | /// ./ => ./.extension |
135 | | /// @endcode |
136 | | /// |
137 | | /// @param path A path that has its extension replaced with \a extension. |
138 | | /// @param extension The extension to be added. It may be empty. It may also |
139 | | /// optionally start with a '.', if it does not, one will be |
140 | | /// prepended. |
141 | | void replace_extension(SmallVectorImpl<char> &path, const Twine &extension); |
142 | | |
143 | | /// @brief Append to path. |
144 | | /// |
145 | | /// @code |
146 | | /// /foo + bar/f => /foo/bar/f |
147 | | /// /foo/ + bar/f => /foo/bar/f |
148 | | /// foo + bar/f => foo/bar/f |
149 | | /// @endcode |
150 | | /// |
151 | | /// @param path Set to \a path + \a component. |
152 | | /// @param a The component to be appended to \a path. |
153 | | void append(SmallVectorImpl<char> &path, const Twine &a, |
154 | | const Twine &b = "", |
155 | | const Twine &c = "", |
156 | | const Twine &d = ""); |
157 | | |
158 | | /// @brief Append to path. |
159 | | /// |
160 | | /// @code |
161 | | /// /foo + [bar,f] => /foo/bar/f |
162 | | /// /foo/ + [bar,f] => /foo/bar/f |
163 | | /// foo + [bar,f] => foo/bar/f |
164 | | /// @endcode |
165 | | /// |
166 | | /// @param path Set to \a path + [\a begin, \a end). |
167 | | /// @param begin Start of components to append. |
168 | | /// @param end One past the end of components to append. |
169 | | void append(SmallVectorImpl<char> &path, |
170 | | const_iterator begin, const_iterator end); |
171 | | |
172 | | /// @} |
173 | | /// @name Transforms (or some other better name) |
174 | | /// @{ |
175 | | |
176 | | /// Convert path to the native form. This is used to give paths to users and |
177 | | /// operating system calls in the platform's normal way. For example, on Windows |
178 | | /// all '/' are converted to '\'. |
179 | | /// |
180 | | /// @param path A path that is transformed to native format. |
181 | | /// @param result Holds the result of the transformation. |
182 | | void native(const Twine &path, SmallVectorImpl<char> &result); |
183 | | |
184 | | /// Convert path to the native form in place. This is used to give paths to |
185 | | /// users and operating system calls in the platform's normal way. For example, |
186 | | /// on Windows all '/' are converted to '\'. |
187 | | /// |
188 | | /// @param path A path that is transformed to native format. |
189 | | void native(SmallVectorImpl<char> &path); |
190 | | |
191 | | /// @} |
192 | | /// @name Lexical Observers |
193 | | /// @{ |
194 | | |
195 | | /// @brief Get root name. |
196 | | /// |
197 | | /// @code |
198 | | /// //net/hello => //net |
199 | | /// c:/hello => c: (on Windows, on other platforms nothing) |
200 | | /// /hello => <empty> |
201 | | /// @endcode |
202 | | /// |
203 | | /// @param path Input path. |
204 | | /// @result The root name of \a path if it has one, otherwise "". |
205 | | StringRef root_name(StringRef path); |
206 | | |
207 | | /// @brief Get root directory. |
208 | | /// |
209 | | /// @code |
210 | | /// /goo/hello => / |
211 | | /// c:/hello => / |
212 | | /// d/file.txt => <empty> |
213 | | /// @endcode |
214 | | /// |
215 | | /// @param path Input path. |
216 | | /// @result The root directory of \a path if it has one, otherwise |
217 | | /// "". |
218 | | StringRef root_directory(StringRef path); |
219 | | |
220 | | /// @brief Get root path. |
221 | | /// |
222 | | /// Equivalent to root_name + root_directory. |
223 | | /// |
224 | | /// @param path Input path. |
225 | | /// @result The root path of \a path if it has one, otherwise "". |
226 | | StringRef root_path(StringRef path); |
227 | | |
228 | | /// @brief Get relative path. |
229 | | /// |
230 | | /// @code |
231 | | /// C:\hello\world => hello\world |
232 | | /// foo/bar => foo/bar |
233 | | /// /foo/bar => foo/bar |
234 | | /// @endcode |
235 | | /// |
236 | | /// @param path Input path. |
237 | | /// @result The path starting after root_path if one exists, otherwise "". |
238 | | StringRef relative_path(StringRef path); |
239 | | |
240 | | /// @brief Get parent path. |
241 | | /// |
242 | | /// @code |
243 | | /// / => <empty> |
244 | | /// /foo => / |
245 | | /// foo/../bar => foo/.. |
246 | | /// @endcode |
247 | | /// |
248 | | /// @param path Input path. |
249 | | /// @result The parent path of \a path if one exists, otherwise "". |
250 | | StringRef parent_path(StringRef path); |
251 | | |
252 | | /// @brief Get filename. |
253 | | /// |
254 | | /// @code |
255 | | /// /foo.txt => foo.txt |
256 | | /// . => . |
257 | | /// .. => .. |
258 | | /// / => / |
259 | | /// @endcode |
260 | | /// |
261 | | /// @param path Input path. |
262 | | /// @result The filename part of \a path. This is defined as the last component |
263 | | /// of \a path. |
264 | | StringRef filename(StringRef path); |
265 | | |
266 | | /// @brief Get stem. |
267 | | /// |
268 | | /// If filename contains a dot but not solely one or two dots, result is the |
269 | | /// substring of filename ending at (but not including) the last dot. Otherwise |
270 | | /// it is filename. |
271 | | /// |
272 | | /// @code |
273 | | /// /foo/bar.txt => bar |
274 | | /// /foo/bar => bar |
275 | | /// /foo/.txt => <empty> |
276 | | /// /foo/. => . |
277 | | /// /foo/.. => .. |
278 | | /// @endcode |
279 | | /// |
280 | | /// @param path Input path. |
281 | | /// @result The stem of \a path. |
282 | | StringRef stem(StringRef path); |
283 | | |
284 | | /// @brief Get extension. |
285 | | /// |
286 | | /// If filename contains a dot but not solely one or two dots, result is the |
287 | | /// substring of filename starting at (and including) the last dot, and ending |
288 | | /// at the end of \a path. Otherwise "". |
289 | | /// |
290 | | /// @code |
291 | | /// /foo/bar.txt => .txt |
292 | | /// /foo/bar => <empty> |
293 | | /// /foo/.txt => .txt |
294 | | /// @endcode |
295 | | /// |
296 | | /// @param path Input path. |
297 | | /// @result The extension of \a path. |
298 | | StringRef extension(StringRef path); |
299 | | |
300 | | /// @brief Check whether the given char is a path separator on the host OS. |
301 | | /// |
302 | | /// @param value a character |
303 | | /// @result true if \a value is a path separator character on the host OS |
304 | | bool is_separator(char value); |
305 | | |
306 | | /// @brief Return the preferred separator for this platform. |
307 | | /// |
308 | | /// @result StringRef of the preferred separator, null-terminated. |
309 | | StringRef get_separator(); |
310 | | |
311 | | /// @brief Get the typical temporary directory for the system, e.g., |
312 | | /// "/var/tmp" or "C:/TEMP" |
313 | | /// |
314 | | /// @param erasedOnReboot Whether to favor a path that is erased on reboot |
315 | | /// rather than one that potentially persists longer. This parameter will be |
316 | | /// ignored if the user or system has set the typical environment variable |
317 | | /// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory. |
318 | | /// |
319 | | /// @param result Holds the resulting path name. |
320 | | void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result); |
321 | | |
322 | | /// @brief Get the user's home directory. |
323 | | /// |
324 | | /// @param result Holds the resulting path name. |
325 | | /// @result True if a home directory is set, false otherwise. |
326 | | bool home_directory(SmallVectorImpl<char> &result); |
327 | | |
328 | | /// @brief Get the user's cache directory. |
329 | | /// |
330 | | /// Expect the resulting path to be a directory shared with other |
331 | | /// applications/services used by the user. Params \p Path1 to \p Path3 can be |
332 | | /// used to append additional directory names to the resulting path. Recommended |
333 | | /// pattern is <user_cache_directory>/<vendor>/<application>. |
334 | | /// |
335 | | /// @param Result Holds the resulting path. |
336 | | /// @param Path1 Additional path to be appended to the user's cache directory |
337 | | /// path. "" can be used to append nothing. |
338 | | /// @param Path2 Second additional path to be appended. |
339 | | /// @param Path3 Third additional path to be appended. |
340 | | /// @result True if a cache directory path is set, false otherwise. |
341 | | bool user_cache_directory(SmallVectorImpl<char> &Result, const Twine &Path1, |
342 | | const Twine &Path2 = "", const Twine &Path3 = ""); |
343 | | |
344 | | /// @brief Has root name? |
345 | | /// |
346 | | /// root_name != "" |
347 | | /// |
348 | | /// @param path Input path. |
349 | | /// @result True if the path has a root name, false otherwise. |
350 | | bool has_root_name(const Twine &path); |
351 | | |
352 | | /// @brief Has root directory? |
353 | | /// |
354 | | /// root_directory != "" |
355 | | /// |
356 | | /// @param path Input path. |
357 | | /// @result True if the path has a root directory, false otherwise. |
358 | | bool has_root_directory(const Twine &path); |
359 | | |
360 | | /// @brief Has root path? |
361 | | /// |
362 | | /// root_path != "" |
363 | | /// |
364 | | /// @param path Input path. |
365 | | /// @result True if the path has a root path, false otherwise. |
366 | | bool has_root_path(const Twine &path); |
367 | | |
368 | | /// @brief Has relative path? |
369 | | /// |
370 | | /// relative_path != "" |
371 | | /// |
372 | | /// @param path Input path. |
373 | | /// @result True if the path has a relative path, false otherwise. |
374 | | bool has_relative_path(const Twine &path); |
375 | | |
376 | | /// @brief Has parent path? |
377 | | /// |
378 | | /// parent_path != "" |
379 | | /// |
380 | | /// @param path Input path. |
381 | | /// @result True if the path has a parent path, false otherwise. |
382 | | bool has_parent_path(const Twine &path); |
383 | | |
384 | | /// @brief Has filename? |
385 | | /// |
386 | | /// filename != "" |
387 | | /// |
388 | | /// @param path Input path. |
389 | | /// @result True if the path has a filename, false otherwise. |
390 | | bool has_filename(const Twine &path); |
391 | | |
392 | | /// @brief Has stem? |
393 | | /// |
394 | | /// stem != "" |
395 | | /// |
396 | | /// @param path Input path. |
397 | | /// @result True if the path has a stem, false otherwise. |
398 | | bool has_stem(const Twine &path); |
399 | | |
400 | | /// @brief Has extension? |
401 | | /// |
402 | | /// extension != "" |
403 | | /// |
404 | | /// @param path Input path. |
405 | | /// @result True if the path has a extension, false otherwise. |
406 | | bool has_extension(const Twine &path); |
407 | | |
408 | | /// @brief Is path absolute? |
409 | | /// |
410 | | /// @param path Input path. |
411 | | /// @result True if the path is absolute, false if it is not. |
412 | | bool is_absolute(const Twine &path); |
413 | | |
414 | | /// @brief Is path relative? |
415 | | /// |
416 | | /// @param path Input path. |
417 | | /// @result True if the path is relative, false if it is not. |
418 | | bool is_relative(const Twine &path); |
419 | | |
420 | | /// @brief Remove redundant leading "./" pieces and consecutive separators. |
421 | | /// |
422 | | /// @param path Input path. |
423 | | /// @result The cleaned-up \a path. |
424 | | StringRef remove_leading_dotslash(StringRef path); |
425 | | |
426 | | /// @brief In-place remove any './' and optionally '../' components from a path. |
427 | | /// |
428 | | /// @param path processed path |
429 | | /// @param remove_dot_dot specify if '../' should be removed |
430 | | /// @result True if path was changed |
431 | | bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot = false); |
432 | | |
433 | | } // end namespace path |
434 | | } // end namespace sys |
435 | | } // end namespace llvm_ks |
436 | | |
437 | | #endif |