Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- llvm/Support/Path.h - Path Operating System Concept ------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file declares the llvm::sys::path namespace. It is designed after
10
// TR2/boost filesystem (v3), but modified to remove exception handling and the
11
// path class.
12
//
13
//===----------------------------------------------------------------------===//
14
 
15
#ifndef LLVM_SUPPORT_PATH_H
16
#define LLVM_SUPPORT_PATH_H
17
 
18
#include "llvm/ADT/Twine.h"
19
#include "llvm/ADT/iterator.h"
20
#include "llvm/Support/DataTypes.h"
21
#include <iterator>
22
 
23
namespace llvm {
24
namespace sys {
25
namespace path {
26
 
27
enum class Style {
28
  native,
29
  posix,
30
  windows_slash,
31
  windows_backslash,
32
  windows = windows_backslash, // deprecated
33
};
34
 
35
/// Check if \p S uses POSIX path rules.
36
constexpr bool is_style_posix(Style S) {
37
  if (S == Style::posix)
38
    return true;
39
  if (S != Style::native)
40
    return false;
41
#if defined(_WIN32)
42
  return false;
43
#else
44
  return true;
45
#endif
46
}
47
 
48
/// Check if \p S uses Windows path rules.
49
constexpr bool is_style_windows(Style S) { return !is_style_posix(S); }
50
 
51
/// @name Lexical Component Iterator
52
/// @{
53
 
54
/// Path iterator.
55
///
56
/// This is an input iterator that iterates over the individual components in
57
/// \a path. The traversal order is as follows:
58
/// * The root-name element, if present.
59
/// * The root-directory element, if present.
60
/// * Each successive filename element, if present.
61
/// * Dot, if one or more trailing non-root slash characters are present.
62
/// Traversing backwards is possible with \a reverse_iterator
63
///
64
/// Iteration examples. Each component is separated by ',':
65
/// @code
66
///   /          => /
67
///   /foo       => /,foo
68
///   foo/       => foo,.
69
///   /foo/bar   => /,foo,bar
70
///   ../        => ..,.
71
///   C:\foo\bar => C:,\,foo,bar
72
/// @endcode
73
class const_iterator
74
    : public iterator_facade_base<const_iterator, std::input_iterator_tag,
75
                                  const StringRef> {
76
  StringRef Path;          ///< The entire path.
77
  StringRef Component;     ///< The current component. Not necessarily in Path.
78
  size_t    Position = 0;  ///< The iterators current position within Path.
79
  Style S = Style::native; ///< The path style to use.
80
 
81
  // An end iterator has Position = Path.size() + 1.
82
  friend const_iterator begin(StringRef path, Style style);
83
  friend const_iterator end(StringRef path);
84
 
85
public:
86
  reference operator*() const { return Component; }
87
  const_iterator &operator++();    // preincrement
88
  bool operator==(const const_iterator &RHS) const;
89
 
90
  /// Difference in bytes between this and RHS.
91
  ptrdiff_t operator-(const const_iterator &RHS) const;
92
};
93
 
94
/// Reverse path iterator.
95
///
96
/// This is an input iterator that iterates over the individual components in
97
/// \a path in reverse order. The traversal order is exactly reversed from that
98
/// of \a const_iterator
99
class reverse_iterator
100
    : public iterator_facade_base<reverse_iterator, std::input_iterator_tag,
101
                                  const StringRef> {
102
  StringRef Path;          ///< The entire path.
103
  StringRef Component;     ///< The current component. Not necessarily in Path.
104
  size_t    Position = 0;  ///< The iterators current position within Path.
105
  Style S = Style::native; ///< The path style to use.
106
 
107
  friend reverse_iterator rbegin(StringRef path, Style style);
108
  friend reverse_iterator rend(StringRef path);
109
 
110
public:
111
  reference operator*() const { return Component; }
112
  reverse_iterator &operator++();    // preincrement
113
  bool operator==(const reverse_iterator &RHS) const;
114
 
115
  /// Difference in bytes between this and RHS.
116
  ptrdiff_t operator-(const reverse_iterator &RHS) const;
117
};
118
 
119
/// Get begin iterator over \a path.
120
/// @param path Input path.
121
/// @returns Iterator initialized with the first component of \a path.
122
const_iterator begin(StringRef path, Style style = Style::native);
123
 
124
/// Get end iterator over \a path.
125
/// @param path Input path.
126
/// @returns Iterator initialized to the end of \a path.
127
const_iterator end(StringRef path);
128
 
129
/// Get reverse begin iterator over \a path.
130
/// @param path Input path.
131
/// @returns Iterator initialized with the first reverse component of \a path.
132
reverse_iterator rbegin(StringRef path, Style style = Style::native);
133
 
134
/// Get reverse end iterator over \a path.
135
/// @param path Input path.
136
/// @returns Iterator initialized to the reverse end of \a path.
137
reverse_iterator rend(StringRef path);
138
 
139
/// @}
140
/// @name Lexical Modifiers
141
/// @{
142
 
143
/// Remove the last component from \a path unless it is the root dir.
144
///
145
/// Similar to the POSIX "dirname" utility.
146
///
147
/// @code
148
///   directory/filename.cpp => directory/
149
///   directory/             => directory
150
///   filename.cpp           => <empty>
151
///   /                      => /
152
/// @endcode
153
///
154
/// @param path A path that is modified to not have a file component.
155
void remove_filename(SmallVectorImpl<char> &path, Style style = Style::native);
156
 
157
/// Replace the file extension of \a path with \a extension.
158
///
159
/// @code
160
///   ./filename.cpp => ./filename.extension
161
///   ./filename     => ./filename.extension
162
///   ./             => ./.extension
163
/// @endcode
164
///
165
/// @param path A path that has its extension replaced with \a extension.
166
/// @param extension The extension to be added. It may be empty. It may also
167
///                  optionally start with a '.', if it does not, one will be
168
///                  prepended.
169
void replace_extension(SmallVectorImpl<char> &path, const Twine &extension,
170
                       Style style = Style::native);
171
 
172
/// Replace matching path prefix with another path.
173
///
174
/// @code
175
///   /foo, /old, /new => /foo
176
///   /old, /old, /new => /new
177
///   /old, /old/, /new => /old
178
///   /old/foo, /old, /new => /new/foo
179
///   /old/foo, /old/, /new => /new/foo
180
///   /old/foo, /old/, /new/ => /new/foo
181
///   /oldfoo, /old, /new => /oldfoo
182
///   /foo, <empty>, /new => /new/foo
183
///   /foo, <empty>, new => new/foo
184
///   /old/foo, /old, <empty> => /foo
185
/// @endcode
186
///
187
/// @param Path If \a Path starts with \a OldPrefix modify to instead
188
///        start with \a NewPrefix.
189
/// @param OldPrefix The path prefix to strip from \a Path.
190
/// @param NewPrefix The path prefix to replace \a NewPrefix with.
191
/// @param style The style used to match the prefix. Exact match using
192
/// Posix style, case/separator insensitive match for Windows style.
193
/// @result true if \a Path begins with OldPrefix
194
bool replace_path_prefix(SmallVectorImpl<char> &Path, StringRef OldPrefix,
195
                         StringRef NewPrefix,
196
                         Style style = Style::native);
197
 
198
/// Remove redundant leading "./" pieces and consecutive separators.
199
///
200
/// @param path Input path.
201
/// @result The cleaned-up \a path.
202
StringRef remove_leading_dotslash(StringRef path, Style style = Style::native);
203
 
204
/// In-place remove any './' and optionally '../' components from a path.
205
///
206
/// @param path processed path
207
/// @param remove_dot_dot specify if '../' (except for leading "../") should be
208
/// removed
209
/// @result True if path was changed
210
bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot = false,
211
                 Style style = Style::native);
212
 
213
/// Append to path.
214
///
215
/// @code
216
///   /foo  + bar/f => /foo/bar/f
217
///   /foo/ + bar/f => /foo/bar/f
218
///   foo   + bar/f => foo/bar/f
219
/// @endcode
220
///
221
/// @param path Set to \a path + \a component.
222
/// @param a The component to be appended to \a path.
223
void append(SmallVectorImpl<char> &path, const Twine &a,
224
                                         const Twine &b = "",
225
                                         const Twine &c = "",
226
                                         const Twine &d = "");
227
 
228
void append(SmallVectorImpl<char> &path, Style style, const Twine &a,
229
            const Twine &b = "", const Twine &c = "", const Twine &d = "");
230
 
231
/// Append to path.
232
///
233
/// @code
234
///   /foo  + [bar,f] => /foo/bar/f
235
///   /foo/ + [bar,f] => /foo/bar/f
236
///   foo   + [bar,f] => foo/bar/f
237
/// @endcode
238
///
239
/// @param path Set to \a path + [\a begin, \a end).
240
/// @param begin Start of components to append.
241
/// @param end One past the end of components to append.
242
void append(SmallVectorImpl<char> &path, const_iterator begin,
243
            const_iterator end, Style style = Style::native);
244
 
245
/// @}
246
/// @name Transforms (or some other better name)
247
/// @{
248
 
249
/// Convert path to the native form. This is used to give paths to users and
250
/// operating system calls in the platform's normal way. For example, on Windows
251
/// all '/' are converted to '\'. On Unix, it converts all '\' to '/'.
252
///
253
/// @param path A path that is transformed to native format.
254
/// @param result Holds the result of the transformation.
255
void native(const Twine &path, SmallVectorImpl<char> &result,
256
            Style style = Style::native);
257
 
258
/// Convert path to the native form in place. This is used to give paths to
259
/// users and operating system calls in the platform's normal way. For example,
260
/// on Windows all '/' are converted to '\'.
261
///
262
/// @param path A path that is transformed to native format.
263
void native(SmallVectorImpl<char> &path, Style style = Style::native);
264
 
265
/// For Windows path styles, convert path to use the preferred path separators.
266
/// For other styles, do nothing.
267
///
268
/// @param path A path that is transformed to preferred format.
269
inline void make_preferred(SmallVectorImpl<char> &path,
270
                           Style style = Style::native) {
271
  if (!is_style_windows(style))
272
    return;
273
  native(path, style);
274
}
275
 
276
/// Replaces backslashes with slashes if Windows.
277
///
278
/// @param path processed path
279
/// @result The result of replacing backslashes with forward slashes if Windows.
280
/// On Unix, this function is a no-op because backslashes are valid path
281
/// chracters.
282
std::string convert_to_slash(StringRef path, Style style = Style::native);
283
 
284
/// @}
285
/// @name Lexical Observers
286
/// @{
287
 
288
/// Get root name.
289
///
290
/// @code
291
///   //net/hello => //net
292
///   c:/hello    => c: (on Windows, on other platforms nothing)
293
///   /hello      => <empty>
294
/// @endcode
295
///
296
/// @param path Input path.
297
/// @result The root name of \a path if it has one, otherwise "".
298
StringRef root_name(StringRef path, Style style = Style::native);
299
 
300
/// Get root directory.
301
///
302
/// @code
303
///   /goo/hello => /
304
///   c:/hello   => /
305
///   d/file.txt => <empty>
306
/// @endcode
307
///
308
/// @param path Input path.
309
/// @result The root directory of \a path if it has one, otherwise
310
///               "".
311
StringRef root_directory(StringRef path, Style style = Style::native);
312
 
313
/// Get root path.
314
///
315
/// Equivalent to root_name + root_directory.
316
///
317
/// @param path Input path.
318
/// @result The root path of \a path if it has one, otherwise "".
319
StringRef root_path(StringRef path, Style style = Style::native);
320
 
321
/// Get relative path.
322
///
323
/// @code
324
///   C:\hello\world => hello\world
325
///   foo/bar        => foo/bar
326
///   /foo/bar       => foo/bar
327
/// @endcode
328
///
329
/// @param path Input path.
330
/// @result The path starting after root_path if one exists, otherwise "".
331
StringRef relative_path(StringRef path, Style style = Style::native);
332
 
333
/// Get parent path.
334
///
335
/// @code
336
///   /          => <empty>
337
///   /foo       => /
338
///   foo/../bar => foo/..
339
/// @endcode
340
///
341
/// @param path Input path.
342
/// @result The parent path of \a path if one exists, otherwise "".
343
StringRef parent_path(StringRef path, Style style = Style::native);
344
 
345
/// Get filename.
346
///
347
/// @code
348
///   /foo.txt    => foo.txt
349
///   .          => .
350
///   ..         => ..
351
///   /          => /
352
/// @endcode
353
///
354
/// @param path Input path.
355
/// @result The filename part of \a path. This is defined as the last component
356
///         of \a path. Similar to the POSIX "basename" utility.
357
StringRef filename(StringRef path, Style style = Style::native);
358
 
359
/// Get stem.
360
///
361
/// If filename contains a dot but not solely one or two dots, result is the
362
/// substring of filename ending at (but not including) the last dot. Otherwise
363
/// it is filename.
364
///
365
/// @code
366
///   /foo/bar.txt => bar
367
///   /foo/bar     => bar
368
///   /foo/.txt    => <empty>
369
///   /foo/.       => .
370
///   /foo/..      => ..
371
/// @endcode
372
///
373
/// @param path Input path.
374
/// @result The stem of \a path.
375
StringRef stem(StringRef path, Style style = Style::native);
376
 
377
/// Get extension.
378
///
379
/// If filename contains a dot but not solely one or two dots, result is the
380
/// substring of filename starting at (and including) the last dot, and ending
381
/// at the end of \a path. Otherwise "".
382
///
383
/// @code
384
///   /foo/bar.txt => .txt
385
///   /foo/bar     => <empty>
386
///   /foo/.txt    => .txt
387
/// @endcode
388
///
389
/// @param path Input path.
390
/// @result The extension of \a path.
391
StringRef extension(StringRef path, Style style = Style::native);
392
 
393
/// Check whether the given char is a path separator on the host OS.
394
///
395
/// @param value a character
396
/// @result true if \a value is a path separator character on the host OS
397
bool is_separator(char value, Style style = Style::native);
398
 
399
/// Return the preferred separator for this platform.
400
///
401
/// @result StringRef of the preferred separator, null-terminated.
402
StringRef get_separator(Style style = Style::native);
403
 
404
/// Get the typical temporary directory for the system, e.g.,
405
/// "/var/tmp" or "C:/TEMP"
406
///
407
/// @param erasedOnReboot Whether to favor a path that is erased on reboot
408
/// rather than one that potentially persists longer. This parameter will be
409
/// ignored if the user or system has set the typical environment variable
410
/// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory.
411
///
412
/// @param result Holds the resulting path name.
413
void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result);
414
 
415
/// Get the user's home directory.
416
///
417
/// @param result Holds the resulting path name.
418
/// @result True if a home directory is set, false otherwise.
419
bool home_directory(SmallVectorImpl<char> &result);
420
 
421
/// Get the directory where packages should read user-specific configurations.
422
/// e.g. $XDG_CONFIG_HOME.
423
///
424
/// @param result Holds the resulting path name.
425
/// @result True if the appropriate path was determined, it need not exist.
426
bool user_config_directory(SmallVectorImpl<char> &result);
427
 
428
/// Get the directory where installed packages should put their
429
/// machine-local cache, e.g. $XDG_CACHE_HOME.
430
///
431
/// @param result Holds the resulting path name.
432
/// @result True if the appropriate path was determined, it need not exist.
433
bool cache_directory(SmallVectorImpl<char> &result);
434
 
435
/// Has root name?
436
///
437
/// root_name != ""
438
///
439
/// @param path Input path.
440
/// @result True if the path has a root name, false otherwise.
441
bool has_root_name(const Twine &path, Style style = Style::native);
442
 
443
/// Has root directory?
444
///
445
/// root_directory != ""
446
///
447
/// @param path Input path.
448
/// @result True if the path has a root directory, false otherwise.
449
bool has_root_directory(const Twine &path, Style style = Style::native);
450
 
451
/// Has root path?
452
///
453
/// root_path != ""
454
///
455
/// @param path Input path.
456
/// @result True if the path has a root path, false otherwise.
457
bool has_root_path(const Twine &path, Style style = Style::native);
458
 
459
/// Has relative path?
460
///
461
/// relative_path != ""
462
///
463
/// @param path Input path.
464
/// @result True if the path has a relative path, false otherwise.
465
bool has_relative_path(const Twine &path, Style style = Style::native);
466
 
467
/// Has parent path?
468
///
469
/// parent_path != ""
470
///
471
/// @param path Input path.
472
/// @result True if the path has a parent path, false otherwise.
473
bool has_parent_path(const Twine &path, Style style = Style::native);
474
 
475
/// Has filename?
476
///
477
/// filename != ""
478
///
479
/// @param path Input path.
480
/// @result True if the path has a filename, false otherwise.
481
bool has_filename(const Twine &path, Style style = Style::native);
482
 
483
/// Has stem?
484
///
485
/// stem != ""
486
///
487
/// @param path Input path.
488
/// @result True if the path has a stem, false otherwise.
489
bool has_stem(const Twine &path, Style style = Style::native);
490
 
491
/// Has extension?
492
///
493
/// extension != ""
494
///
495
/// @param path Input path.
496
/// @result True if the path has a extension, false otherwise.
497
bool has_extension(const Twine &path, Style style = Style::native);
498
 
499
/// Is path absolute?
500
///
501
/// According to cppreference.com, C++17 states: "An absolute path is a path
502
/// that unambiguously identifies the location of a file without reference to
503
/// an additional starting location."
504
///
505
/// In other words, the rules are:
506
/// 1) POSIX style paths with nonempty root directory are absolute.
507
/// 2) Windows style paths with nonempty root name and root directory are
508
///    absolute.
509
/// 3) No other paths are absolute.
510
///
511
/// \see has_root_name
512
/// \see has_root_directory
513
///
514
/// @param path Input path.
515
/// @result True if the path is absolute, false if it is not.
516
bool is_absolute(const Twine &path, Style style = Style::native);
517
 
518
/// Is path absolute using GNU rules?
519
///
520
/// GNU rules are:
521
/// 1) Paths starting with a path separator are absolute.
522
/// 2) Windows style paths are also absolute if they start with a character
523
///    followed by ':'.
524
/// 3) No other paths are absolute.
525
///
526
/// On Windows style the path "C:\Users\Default" has "C:" as root name and "\"
527
/// as root directory.
528
///
529
/// Hence "C:" on Windows is absolute under GNU rules and not absolute under
530
/// C++17 because it has no root directory. Likewise "/" and "\" on Windows are
531
/// absolute under GNU and are not absolute under C++17 due to empty root name.
532
///
533
/// \see has_root_name
534
/// \see has_root_directory
535
///
536
/// @param path Input path.
537
/// @param style The style of \p path (e.g. Windows or POSIX). "native" style
538
/// means to derive the style from the host.
539
/// @result True if the path is absolute following GNU rules, false if it is
540
/// not.
541
bool is_absolute_gnu(const Twine &path, Style style = Style::native);
542
 
543
/// Is path relative?
544
///
545
/// @param path Input path.
546
/// @result True if the path is relative, false if it is not.
547
bool is_relative(const Twine &path, Style style = Style::native);
548
 
549
} // end namespace path
550
} // end namespace sys
551
} // end namespace llvm
552
 
553
#endif