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