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