LLDB  mainline
FileSpec.h
Go to the documentation of this file.
1 //===-- FileSpec.h ----------------------------------------------*- 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 #ifndef LLDB_UTILITY_FILESPEC_H
10 #define LLDB_UTILITY_FILESPEC_H
11 
12 #include <functional>
13 #include <string>
14 
16 
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/FormatVariadic.h"
20 #include "llvm/Support/Path.h"
21 #include "llvm/Support/YAMLTraits.h"
22 
23 #include <cstddef>
24 #include <cstdint>
25 
26 namespace lldb_private {
27 class Stream;
28 }
29 namespace llvm {
30 class Triple;
31 }
32 namespace llvm {
33 class raw_ostream;
34 }
35 namespace llvm {
36 template <typename T> class SmallVectorImpl;
37 }
38 
39 namespace lldb_private {
40 
41 /// \class FileSpec FileSpec.h "lldb/Utility/FileSpec.h"
42 /// A file utility class.
43 ///
44 /// A file specification class that divides paths up into a directory
45 /// and basename. These string values of the paths are put into uniqued string
46 /// pools for fast comparisons and efficient memory usage.
47 ///
48 /// Another reason the paths are split into the directory and basename is to
49 /// allow efficient debugger searching. Often in a debugger the user types in
50 /// the basename of the file, for example setting a breakpoint by file and
51 /// line, or specifying a module (shared library) to limit the scope in which
52 /// to execute a command. The user rarely types in a full path. When the paths
53 /// are already split up, it makes it easy for us to compare only the
54 /// basenames of a lot of file specifications without having to split up the
55 /// file path each time to get to the basename.
56 class FileSpec {
57 public:
58  using Style = llvm::sys::path::Style;
59 
60  FileSpec();
61 
62  /// Constructor with path.
63  ///
64  /// Takes a path to a file which can be just a filename, or a full path. If
65  /// \a path is not nullptr or empty, this function will call
66  /// FileSpec::SetFile (const char *path).
67  ///
68  /// \param[in] path
69  /// The full or partial path to a file.
70  ///
71  /// \param[in] style
72  /// The style of the path
73  ///
74  /// \see FileSpec::SetFile (const char *path)
75  explicit FileSpec(llvm::StringRef path, Style style = Style::native);
76 
77  explicit FileSpec(llvm::StringRef path, const llvm::Triple &triple);
78 
79  bool DirectoryEquals(const FileSpec &other) const;
80 
81  bool FileEquals(const FileSpec &other) const;
82 
83  /// Equal to operator
84  ///
85  /// Tests if this object is equal to \a rhs.
86  ///
87  /// \param[in] rhs
88  /// A const FileSpec object reference to compare this object
89  /// to.
90  ///
91  /// \return
92  /// \b true if this object is equal to \a rhs, \b false
93  /// otherwise.
94  bool operator==(const FileSpec &rhs) const;
95 
96  /// Not equal to operator
97  ///
98  /// Tests if this object is not equal to \a rhs.
99  ///
100  /// \param[in] rhs
101  /// A const FileSpec object reference to compare this object
102  /// to.
103  ///
104  /// \return
105  /// \b true if this object is equal to \a rhs, \b false
106  /// otherwise.
107  bool operator!=(const FileSpec &rhs) const;
108 
109  /// Less than to operator
110  ///
111  /// Tests if this object is less than \a rhs.
112  ///
113  /// \param[in] rhs
114  /// A const FileSpec object reference to compare this object
115  /// to.
116  ///
117  /// \return
118  /// \b true if this object is less than \a rhs, \b false
119  /// otherwise.
120  bool operator<(const FileSpec &rhs) const;
121 
122  /// Convert to pointer operator.
123  ///
124  /// This allows code to check a FileSpec object to see if it contains
125  /// anything valid using code such as:
126  ///
127  /// \code
128  /// FileSpec file_spec(...);
129  /// if (file_spec)
130  /// { ...
131  /// \endcode
132  ///
133  /// \return
134  /// A pointer to this object if either the directory or filename
135  /// is valid, nullptr otherwise.
136  explicit operator bool() const;
137 
138  /// Logical NOT operator.
139  ///
140  /// This allows code to check a FileSpec object to see if it is invalid
141  /// using code such as:
142  ///
143  /// \code
144  /// FileSpec file_spec(...);
145  /// if (!file_spec)
146  /// { ...
147  /// \endcode
148  ///
149  /// \return
150  /// Returns \b true if the object has an empty directory and
151  /// filename, \b false otherwise.
152  bool operator!() const;
153 
154  /// Clears the object state.
155  ///
156  /// Clear this object by releasing both the directory and filename string
157  /// values and reverting them to empty strings.
158  void Clear();
159 
160  /// Compare two FileSpec objects.
161  ///
162  /// If \a full is true, then both the directory and the filename must match.
163  /// If \a full is false, then the directory names for \a lhs and \a rhs are
164  /// only compared if they are both not empty. This allows a FileSpec object
165  /// to only contain a filename and it can match FileSpec objects that have
166  /// matching filenames with different paths.
167  ///
168  /// \param[in] lhs
169  /// A const reference to the Left Hand Side object to compare.
170  ///
171  /// \param[in] rhs
172  /// A const reference to the Right Hand Side object to compare.
173  ///
174  /// \param[in] full
175  /// If true, then both the directory and filenames will have to
176  /// match for a compare to return zero (equal to). If false
177  /// and either directory from \a lhs or \a rhs is empty, then
178  /// only the filename will be compared, else a full comparison
179  /// is done.
180  ///
181  /// \return -1 if \a lhs is less than \a rhs, 0 if \a lhs is equal to \a rhs,
182  /// 1 if \a lhs is greater than \a rhs
183  static int Compare(const FileSpec &lhs, const FileSpec &rhs, bool full);
184 
185  static bool Equal(const FileSpec &a, const FileSpec &b, bool full);
186 
187  /// Match FileSpec \a pattern against FileSpec \a file. If \a pattern has a
188  /// directory component, then the \a file must have the same directory
189  /// component. Otherwise, just it matches just the filename. An empty \a
190  /// pattern matches everything.
191  static bool Match(const FileSpec &pattern, const FileSpec &file);
192 
193  /// Attempt to guess path style for a given path string. It returns a style,
194  /// if it was able to make a reasonable guess, or None if it wasn't. The guess
195  /// will be correct if the input path was a valid absolute path on the system
196  /// which produced it. On other paths the result of this function is
197  /// unreliable (e.g. "c:\foo.txt" is a valid relative posix path).
198  static llvm::Optional<Style> GuessPathStyle(llvm::StringRef absolute_path);
199 
200  /// Case sensitivity of path.
201  ///
202  /// \return
203  /// \b true if the file path is case sensitive (POSIX), false
204  /// if case insensitive (Windows).
205  bool IsCaseSensitive() const { return m_style != Style::windows; }
206 
207  /// Dump this object to a Stream.
208  ///
209  /// Dump the object to the supplied stream \a s. If the object contains a
210  /// valid directory name, it will be displayed followed by a directory
211  /// delimiter, and the filename.
212  ///
213  /// \param[in] s
214  /// The stream to which to dump the object description.
215  void Dump(llvm::raw_ostream &s) const;
216 
217  Style GetPathStyle() const;
218 
219  /// Directory string get accessor.
220  ///
221  /// \return
222  /// A reference to the directory string object.
224 
225  /// Directory string const get accessor.
226  ///
227  /// \return
228  /// A const reference to the directory string object.
229  ConstString GetDirectory() const;
230 
231  /// Filename string get accessor.
232  ///
233  /// \return
234  /// A reference to the filename string object.
236 
237  /// Filename string const get accessor.
238  ///
239  /// \return
240  /// A const reference to the filename string object.
241  ConstString GetFilename() const;
242 
243  /// Returns true if the filespec represents an implementation source file
244  /// (files with a ".c", ".cpp", ".m", ".mm" (many more) extension).
245  ///
246  /// \return
247  /// \b true if the filespec represents an implementation source
248  /// file, \b false otherwise.
249  bool IsSourceImplementationFile() const;
250 
251  /// Returns true if the filespec represents a relative path.
252  ///
253  /// \return
254  /// \b true if the filespec represents a relative path,
255  /// \b false otherwise.
256  bool IsRelative() const;
257 
258  /// Returns true if the filespec represents an absolute path.
259  ///
260  /// \return
261  /// \b true if the filespec represents an absolute path,
262  /// \b false otherwise.
263  bool IsAbsolute() const;
264 
265  /// Make the FileSpec absolute by treating it relative to \a dir. Absolute
266  /// FileSpecs are never changed by this function.
267  void MakeAbsolute(const FileSpec &dir);
268 
269  /// Temporary helper for FileSystem change.
270  void SetPath(llvm::StringRef p) { SetFile(p); }
271 
272  /// Extract the full path to the file.
273  ///
274  /// Extract the directory and path into a fixed buffer. This is needed as
275  /// the directory and path are stored in separate string values.
276  ///
277  /// \param[out] path
278  /// The buffer in which to place the extracted full path.
279  ///
280  /// \param[in] max_path_length
281  /// The maximum length of \a path.
282  ///
283  /// \return
284  /// Returns the number of characters that would be needed to
285  /// properly copy the full path into \a path. If the returned
286  /// number is less than \a max_path_length, then the path is
287  /// properly copied and terminated. If the return value is
288  /// >= \a max_path_length, then the path was truncated (but is
289  /// still NULL terminated).
290  size_t GetPath(char *path, size_t max_path_length,
291  bool denormalize = true) const;
292 
293  /// Extract the full path to the file.
294  ///
295  /// Extract the directory and path into a std::string, which is returned.
296  ///
297  /// \return
298  /// Returns a std::string with the directory and filename
299  /// concatenated.
300  std::string GetPath(bool denormalize = true) const;
301 
302  const char *GetCString(bool denormalize = true) const;
303 
304  /// Extract the full path to the file.
305  ///
306  /// Extract the directory and path into an llvm::SmallVectorImpl<>
308  bool denormalize = true) const;
309 
310  /// Extract the extension of the file.
311  ///
312  /// Returns a ConstString that represents the extension of the filename for
313  /// this FileSpec object. If this object does not represent a file, or the
314  /// filename has no extension, ConstString(nullptr) is returned. The dot
315  /// ('.') character is not returned as part of the extension
316  ///
317  /// \return Returns the extension of the file as a ConstString object.
319 
320  /// Return the filename without the extension part
321  ///
322  /// Returns a ConstString that represents the filename of this object
323  /// without the extension part (e.g. for a file named "foo.bar", "foo" is
324  /// returned)
325  ///
326  /// \return Returns the filename without extension as a ConstString object.
328 
329  /// Get the memory cost of this object.
330  ///
331  /// Return the size in bytes that this object takes in memory. This returns
332  /// the size in bytes of this object, not any shared string values it may
333  /// refer to.
334  ///
335  /// \return
336  /// The number of bytes that this object occupies in memory.
337  ///
338  /// \see ConstString::StaticMemorySize ()
339  size_t MemorySize() const;
340 
341  /// Change the file specified with a new path.
342  ///
343  /// Update the contents of this object with a new path. The path will be
344  /// split up into a directory and filename and stored as uniqued string
345  /// values for quick comparison and efficient memory usage.
346  ///
347  /// \param[in] path
348  /// A full, partial, or relative path to a file.
349  ///
350  /// \param[in] style
351  /// The style for the given path.
352  void SetFile(llvm::StringRef path, Style style);
353 
354  /// Change the file specified with a new path.
355  ///
356  /// Update the contents of this object with a new path. The path will be
357  /// split up into a directory and filename and stored as uniqued string
358  /// values for quick comparison and efficient memory usage.
359  ///
360  /// \param[in] path
361  /// A full, partial, or relative path to a file.
362  ///
363  /// \param[in] triple
364  /// The triple which is used to set the Path style.
365  void SetFile(llvm::StringRef path, const llvm::Triple &triple);
366 
367  bool IsResolved() const { return m_is_resolved; }
368 
369  /// Set if the file path has been resolved or not.
370  ///
371  /// If you know a file path is already resolved and avoided passing a \b
372  /// true parameter for any functions that take a "bool resolve_path"
373  /// parameter, you can set the value manually using this call to make sure
374  /// we don't try and resolve it later, or try and resolve a path that has
375  /// already been resolved.
376  ///
377  /// \param[in] is_resolved
378  /// A boolean value that will replace the current value that
379  /// indicates if the paths in this object have been resolved.
380  void SetIsResolved(bool is_resolved) { m_is_resolved = is_resolved; }
381 
382  FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const;
384 
385  void PrependPathComponent(llvm::StringRef component);
386  void PrependPathComponent(const FileSpec &new_path);
387 
388  void AppendPathComponent(llvm::StringRef component);
389  void AppendPathComponent(const FileSpec &new_path);
390 
391  /// Removes the last path component by replacing the current path with its
392  /// parent. When the current path has no parent, this is a no-op.
393  ///
394  /// \return
395  /// A boolean value indicating whether the path was updated.
397 
399 
400 protected:
401  friend struct llvm::yaml::MappingTraits<FileSpec>;
402 
403  // Convenience method for setting the file without changing the style.
404  void SetFile(llvm::StringRef path);
405 
406  // Member variables
407  ConstString m_directory; ///< The uniqued directory path
408  ConstString m_filename; ///< The uniqued filename path
409  mutable bool m_is_resolved = false; ///< True if this path has been resolved.
410  Style m_style; ///< The syntax that this path uses (e.g. Windows / Posix)
411 };
412 
413 /// Dump a FileSpec object to a stream
414 Stream &operator<<(Stream &s, const FileSpec &f);
415 
416 /// Prevent ODR violations with traits for llvm::sys::path::Style.
417 LLVM_YAML_STRONG_TYPEDEF(FileSpec::Style, FileSpecStyle)
418 } // namespace lldb_private
419 
420 namespace llvm {
421 
422 /// Implementation of format_provider<T> for FileSpec.
423 ///
424 /// The options string of a FileSpec has the grammar:
425 ///
426 /// file_spec_options :: (empty) | F | D
427 ///
428 /// =======================================================
429 /// | style | Meaning | Example |
430 /// -------------------------------------------------------
431 /// | | | Input | Output |
432 /// =======================================================
433 /// | F | Only print filename | /foo/bar | bar |
434 /// | D | Only print directory | /foo/bar | /foo/ |
435 /// | (empty) | Print file and dir | | |
436 /// =======================================================
437 ///
438 /// Any other value is considered an invalid format string.
439 ///
440 template <> struct format_provider<lldb_private::FileSpec> {
441  static void format(const lldb_private::FileSpec &F, llvm::raw_ostream &Stream,
442  StringRef Style);
443 };
444 
445 namespace yaml {
446 template <> struct ScalarEnumerationTraits<lldb_private::FileSpecStyle> {
447  static void enumeration(IO &io, lldb_private::FileSpecStyle &style);
448 };
449 
450 template <> struct MappingTraits<lldb_private::FileSpec> {
451  static void mapping(IO &io, lldb_private::FileSpec &f);
452 };
453 } // namespace yaml
454 } // namespace llvm
455 
456 #endif // LLDB_UTILITY_FILESPEC_H
lldb_private::FileSpec::GetLastPathComponent
ConstString GetLastPathComponent() const
Definition: FileSpec.cpp:415
llvm
Definition: Debugger.h:49
lldb_private::FileSpec::m_filename
ConstString m_filename
The uniqued filename path.
Definition: FileSpec.h:408
lldb_private::FileSpec::operator!
bool operator!() const
Logical NOT operator.
Definition: FileSpec.cpp:228
lldb_private::FileSpec::MemorySize
size_t MemorySize() const
Get the memory cost of this object.
Definition: FileSpec.cpp:395
lldb_private::FileSpec::GetPathStyle
Style GetPathStyle() const
Definition: FileSpec.cpp:332
lldb_private::Stream
Definition: Stream.h:28
lldb_private::FileSpec::MakeAbsolute
void MakeAbsolute(const FileSpec &dir)
Make the FileSpec absolute by treating it relative to dir.
Definition: FileSpec.cpp:494
lldb_private::FileSpec::SetPath
void SetPath(llvm::StringRef p)
Temporary helper for FileSystem change.
Definition: FileSpec.h:270
lldb_private::FileSpec::CopyByRemovingLastPathComponent
FileSpec CopyByRemovingLastPathComponent() const
Definition: FileSpec.cpp:406
lldb_private::FileSpec::PrependPathComponent
void PrependPathComponent(llvm::StringRef component)
Definition: FileSpec.cpp:421
lldb_private::FileSpec::operator!=
bool operator!=(const FileSpec &rhs) const
Not equal to operator.
Definition: FileSpec.cpp:246
lldb_private::FileSpec::GetCString
const char * GetCString(bool denormalize=true) const
Definition: FileSpec.cpp:364
lldb_private::FileSpec
Definition: FileSpec.h:56
lldb_private::FileSpec::Compare
static int Compare(const FileSpec &lhs, const FileSpec &rhs, bool full)
Compare two FileSpec objects.
Definition: FileSpec.cpp:274
lldb_private::FileSpec::operator<
bool operator<(const FileSpec &rhs) const
Less than to operator.
Definition: FileSpec.cpp:249
lldb_private::FileSpec::Match
static bool Match(const FileSpec &pattern, const FileSpec &file)
Match FileSpec pattern against FileSpec file.
Definition: FileSpec.cpp:302
lldb_private::FileSpec::SetIsResolved
void SetIsResolved(bool is_resolved)
Set if the file path has been resolved or not.
Definition: FileSpec.h:380
lldb_private::FileSpec::m_directory
ConstString m_directory
The uniqued directory path.
Definition: FileSpec.h:407
lldb_private::FileSpec::DirectoryEquals
bool DirectoryEquals(const FileSpec &other) const
Definition: FileSpec.cpp:230
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::FileSpec::IsSourceImplementationFile
bool IsSourceImplementationFile() const
Returns true if the filespec represents an implementation source file (files with a "....
Definition: FileSpec.cpp:462
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
lldb_private::FileSpec::CopyByAppendingPathComponent
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
Definition: FileSpec.cpp:400
lldb_private::FileSpec::GuessPathStyle
static llvm::Optional< Style > GuessPathStyle(llvm::StringRef absolute_path)
Attempt to guess path style for a given path string.
Definition: FileSpec.cpp:310
lldb_private::FileSpec::IsAbsolute
bool IsAbsolute() const
Returns true if the filespec represents an absolute path.
Definition: FileSpec.cpp:479
lldb_private::FileSpec::Clear
void Clear()
Clears the object state.
Definition: FileSpec.cpp:261
lldb_private::FileSpec::Style
llvm::sys::path::Style Style
Definition: FileSpec.h:58
lldb_private::FileSpec::FileEquals
bool FileEquals(const FileSpec &other) const
Definition: FileSpec.cpp:235
lldb_private::FileSpec::IsRelative
bool IsRelative() const
Returns true if the filespec represents a relative path.
Definition: FileSpec.cpp:475
lldb_private::operator<<
Stream & operator<<(Stream &s, const SourceLocationSpec &loc)
Dump a SourceLocationSpec object to a stream.
Definition: SourceLocationSpec.cpp:40
lldb_private::FileSpec::RemoveLastPathComponent
bool RemoveLastPathComponent()
Removes the last path component by replacing the current path with its parent.
Definition: FileSpec.cpp:446
lldb_private::FileSpec::FileSpec
FileSpec()
Definition: FileSpec.cpp:68
lldb_private::FileSpec::Dump
void Dump(llvm::raw_ostream &s) const
Dump this object to a Stream.
Definition: FileSpec.cpp:324
lldb_private::FileSpec::IsCaseSensitive
bool IsCaseSensitive() const
Case sensitivity of path.
Definition: FileSpec.h:205
lldb_private::FileSpec::m_is_resolved
bool m_is_resolved
True if this path has been resolved.
Definition: FileSpec.h:409
lldb_private::FileSpec::AppendPathComponent
void AppendPathComponent(llvm::StringRef component)
Definition: FileSpec.cpp:435
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::FileSpec::IsResolved
bool IsResolved() const
Definition: FileSpec.h:367
lldb_private::FileSpec::GetDirectory
ConstString & GetDirectory()
Directory string get accessor.
Definition: FileSpec.cpp:335
ConstString.h
lldb_private::FileSpec::SetFile
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition: FileSpec.cpp:174
llvm::SmallVectorImpl
Definition: Disassembler.h:42
lldb_private::FileSpec::GetPath
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:348
lldb_private::FileSpec::GetFileNameExtension
ConstString GetFileNameExtension() const
Extract the extension of the file.
Definition: FileSpec.cpp:384
lldb_private::FileSpec::GetFilename
ConstString & GetFilename()
Filename string get accessor.
Definition: FileSpec.cpp:341
lldb_private::FileSpec::Equal
static bool Equal(const FileSpec &a, const FileSpec &b, bool full)
Definition: FileSpec.cpp:295
lldb_private::FileSpec::operator==
bool operator==(const FileSpec &rhs) const
Equal to operator.
Definition: FileSpec.cpp:241
lldb_private::FileSpec::m_style
Style m_style
The syntax that this path uses (e.g. Windows / Posix)
Definition: FileSpec.h:410
lldb_private::FileSpec::GetFileNameStrippingExtension
ConstString GetFileNameStrippingExtension() const
Return the filename without the extension part.
Definition: FileSpec.cpp:389