]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/Utility/FileSpec.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / include / lldb / Utility / FileSpec.h
1 //===-- FileSpec.h ----------------------------------------------*- 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 #ifndef liblldb_FileSpec_h_
11 #define liblldb_FileSpec_h_
12
13 #include <functional>
14 #include <string>
15
16 #include "lldb/Utility/ConstString.h"
17
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Support/FileSystem.h"
20 #include "llvm/Support/FormatVariadic.h"
21 #include "llvm/Support/Path.h"
22
23 #include <stddef.h>
24 #include <stdint.h>
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 //----------------------------------------------------------------------
42 /// @class FileSpec FileSpec.h "lldb/Host/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.
57 //----------------------------------------------------------------------
58 class FileSpec {
59 public:
60   using Style = llvm::sys::path::Style;
61
62   FileSpec();
63
64   //------------------------------------------------------------------
65   /// Constructor with path.
66   ///
67   /// Takes a path to a file which can be just a filename, or a full path. If
68   /// \a path is not nullptr or empty, this function will call
69   /// FileSpec::SetFile (const char *path).
70   ///
71   /// @param[in] path
72   ///     The full or partial path to a file.
73   ///
74   /// @param[in] style
75   ///     The style of the path
76   ///
77   /// @see FileSpec::SetFile (const char *path)
78   //------------------------------------------------------------------
79   explicit FileSpec(llvm::StringRef path, Style style = Style::native);
80
81   explicit FileSpec(llvm::StringRef path, const llvm::Triple &Triple);
82
83   //------------------------------------------------------------------
84   /// Copy constructor
85   ///
86   /// Makes a copy of the uniqued directory and filename strings from \a rhs.
87   ///
88   /// @param[in] rhs
89   ///     A const FileSpec object reference to copy.
90   //------------------------------------------------------------------
91   FileSpec(const FileSpec &rhs);
92
93   //------------------------------------------------------------------
94   /// Copy constructor
95   ///
96   /// Makes a copy of the uniqued directory and filename strings from \a rhs
97   /// if it is not nullptr.
98   ///
99   /// @param[in] rhs
100   ///     A const FileSpec object pointer to copy if non-nullptr.
101   //------------------------------------------------------------------
102   FileSpec(const FileSpec *rhs);
103
104   //------------------------------------------------------------------
105   /// Destructor.
106   //------------------------------------------------------------------
107   ~FileSpec();
108
109   bool DirectoryEquals(const FileSpec &other) const;
110
111   bool FileEquals(const FileSpec &other) const;
112
113   //------------------------------------------------------------------
114   /// Assignment operator.
115   ///
116   /// Makes a copy of the uniqued directory and filename strings from \a rhs.
117   ///
118   /// @param[in] rhs
119   ///     A const FileSpec object reference to assign to this object.
120   ///
121   /// @return
122   ///     A const reference to this object.
123   //------------------------------------------------------------------
124   const FileSpec &operator=(const FileSpec &rhs);
125
126   //------------------------------------------------------------------
127   /// Equal to operator
128   ///
129   /// Tests if this object is equal to \a rhs.
130   ///
131   /// @param[in] rhs
132   ///     A const FileSpec object reference to compare this object
133   ///     to.
134   ///
135   /// @return
136   ///     \b true if this object is equal to \a rhs, \b false
137   ///     otherwise.
138   //------------------------------------------------------------------
139   bool operator==(const FileSpec &rhs) const;
140
141   //------------------------------------------------------------------
142   /// Not equal to operator
143   ///
144   /// Tests if this object is not equal to \a rhs.
145   ///
146   /// @param[in] rhs
147   ///     A const FileSpec object reference to compare this object
148   ///     to.
149   ///
150   /// @return
151   ///     \b true if this object is equal to \a rhs, \b false
152   ///     otherwise.
153   //------------------------------------------------------------------
154   bool operator!=(const FileSpec &rhs) const;
155
156   //------------------------------------------------------------------
157   /// Less than to operator
158   ///
159   /// Tests if this object is less than \a rhs.
160   ///
161   /// @param[in] rhs
162   ///     A const FileSpec object reference to compare this object
163   ///     to.
164   ///
165   /// @return
166   ///     \b true if this object is less than \a rhs, \b false
167   ///     otherwise.
168   //------------------------------------------------------------------
169   bool operator<(const FileSpec &rhs) const;
170
171   //------------------------------------------------------------------
172   /// Convert to pointer operator.
173   ///
174   /// This allows code to check a FileSpec object to see if it contains
175   /// anything valid using code such as:
176   ///
177   /// @code
178   /// FileSpec file_spec(...);
179   /// if (file_spec)
180   /// { ...
181   /// @endcode
182   ///
183   /// @return
184   ///     A pointer to this object if either the directory or filename
185   ///     is valid, nullptr otherwise.
186   //------------------------------------------------------------------
187   explicit operator bool() const;
188
189   //------------------------------------------------------------------
190   /// Logical NOT operator.
191   ///
192   /// This allows code to check a FileSpec object to see if it is invalid
193   /// using code such as:
194   ///
195   /// @code
196   /// FileSpec file_spec(...);
197   /// if (!file_spec)
198   /// { ...
199   /// @endcode
200   ///
201   /// @return
202   ///     Returns \b true if the object has an empty directory and
203   ///     filename, \b false otherwise.
204   //------------------------------------------------------------------
205   bool operator!() const;
206
207   //------------------------------------------------------------------
208   /// Clears the object state.
209   ///
210   /// Clear this object by releasing both the directory and filename string
211   /// values and reverting them to empty strings.
212   //------------------------------------------------------------------
213   void Clear();
214
215   //------------------------------------------------------------------
216   /// Compare two FileSpec objects.
217   ///
218   /// If \a full is true, then both the directory and the filename must match.
219   /// If \a full is false, then the directory names for \a lhs and \a rhs are
220   /// only compared if they are both not empty. This allows a FileSpec object
221   /// to only contain a filename and it can match FileSpec objects that have
222   /// matching filenames with different paths.
223   ///
224   /// @param[in] lhs
225   ///     A const reference to the Left Hand Side object to compare.
226   ///
227   /// @param[in] rhs
228   ///     A const reference to the Right Hand Side object to compare.
229   ///
230   /// @param[in] full
231   ///     If true, then both the directory and filenames will have to
232   ///     match for a compare to return zero (equal to). If false
233   ///     and either directory from \a lhs or \a rhs is empty, then
234   ///     only the filename will be compared, else a full comparison
235   ///     is done.
236   ///
237   /// @return
238   ///     @li -1 if \a lhs is less than \a rhs
239   ///     @li 0 if \a lhs is equal to \a rhs
240   ///     @li 1 if \a lhs is greater than \a rhs
241   //------------------------------------------------------------------
242   static int Compare(const FileSpec &lhs, const FileSpec &rhs, bool full);
243
244   static bool Equal(const FileSpec &a, const FileSpec &b, bool full);
245
246   //------------------------------------------------------------------
247   /// Case sensitivity of path.
248   ///
249   /// @return
250   ///     \b true if the file path is case sensitive (POSIX), false
251   ///           if case insensitive (Windows).
252   //------------------------------------------------------------------
253   bool IsCaseSensitive() const { return m_style != Style::windows; }
254
255   //------------------------------------------------------------------
256   /// Dump this object to a Stream.
257   ///
258   /// Dump the object to the supplied stream \a s. If the object contains a
259   /// valid directory name, it will be displayed followed by a directory
260   /// delimiter, and the filename.
261   ///
262   /// @param[in] s
263   ///     The stream to which to dump the object description.
264   //------------------------------------------------------------------
265   void Dump(Stream *s) const;
266
267   Style GetPathStyle() const;
268
269   //------------------------------------------------------------------
270   /// Directory string get accessor.
271   ///
272   /// @return
273   ///     A reference to the directory string object.
274   //------------------------------------------------------------------
275   ConstString &GetDirectory();
276
277   //------------------------------------------------------------------
278   /// Directory string const get accessor.
279   ///
280   /// @return
281   ///     A const reference to the directory string object.
282   //------------------------------------------------------------------
283   const ConstString &GetDirectory() const;
284
285   //------------------------------------------------------------------
286   /// Filename string get accessor.
287   ///
288   /// @return
289   ///     A reference to the filename string object.
290   //------------------------------------------------------------------
291   ConstString &GetFilename();
292
293   //------------------------------------------------------------------
294   /// Filename string const get accessor.
295   ///
296   /// @return
297   ///     A const reference to the filename string object.
298   //------------------------------------------------------------------
299   const ConstString &GetFilename() const;
300
301   //------------------------------------------------------------------
302   /// Returns true if the filespec represents an implementation source file
303   /// (files with a ".c", ".cpp", ".m", ".mm" (many more) extension).
304   ///
305   /// @return
306   ///     \b true if the filespec represents an implementation source
307   ///     file, \b false otherwise.
308   //------------------------------------------------------------------
309   bool IsSourceImplementationFile() const;
310
311   //------------------------------------------------------------------
312   /// Returns true if the filespec represents a relative path.
313   ///
314   /// @return
315   ///     \b true if the filespec represents a relative path,
316   ///     \b false otherwise.
317   //------------------------------------------------------------------
318   bool IsRelative() const;
319
320   //------------------------------------------------------------------
321   /// Returns true if the filespec represents an absolute path.
322   ///
323   /// @return
324   ///     \b true if the filespec represents an absolute path,
325   ///     \b false otherwise.
326   //------------------------------------------------------------------
327   bool IsAbsolute() const;
328
329   /// Temporary helper for FileSystem change.
330   void SetPath(llvm::StringRef p) { SetFile(p); }
331
332   //------------------------------------------------------------------
333   /// Extract the full path to the file.
334   ///
335   /// Extract the directory and path into a fixed buffer. This is needed as
336   /// the directory and path are stored in separate string values.
337   ///
338   /// @param[out] path
339   ///     The buffer in which to place the extracted full path.
340   ///
341   /// @param[in] max_path_length
342   ///     The maximum length of \a path.
343   ///
344   /// @return
345   ///     Returns the number of characters that would be needed to
346   ///     properly copy the full path into \a path. If the returned
347   ///     number is less than \a max_path_length, then the path is
348   ///     properly copied and terminated. If the return value is
349   ///     >= \a max_path_length, then the path was truncated (but is
350   ///     still NULL terminated).
351   //------------------------------------------------------------------
352   size_t GetPath(char *path, size_t max_path_length,
353                  bool denormalize = true) const;
354
355   //------------------------------------------------------------------
356   /// Extract the full path to the file.
357   ///
358   /// Extract the directory and path into a std::string, which is returned.
359   ///
360   /// @return
361   ///     Returns a std::string with the directory and filename
362   ///     concatenated.
363   //------------------------------------------------------------------
364   std::string GetPath(bool denormalize = true) const;
365
366   const char *GetCString(bool denormalize = true) const;
367
368   //------------------------------------------------------------------
369   /// Extract the full path to the file.
370   ///
371   /// Extract the directory and path into an llvm::SmallVectorImpl<>
372   ///
373   /// @return
374   ///     Returns a std::string with the directory and filename
375   ///     concatenated.
376   //------------------------------------------------------------------
377   void GetPath(llvm::SmallVectorImpl<char> &path,
378                bool denormalize = true) const;
379
380   //------------------------------------------------------------------
381   /// Extract the extension of the file.
382   ///
383   /// Returns a ConstString that represents the extension of the filename for
384   /// this FileSpec object. If this object does not represent a file, or the
385   /// filename has no extension, ConstString(nullptr) is returned. The dot
386   /// ('.') character is not returned as part of the extension
387   ///
388   /// @return
389   ///     Returns the extension of the file as a ConstString object.
390   //------------------------------------------------------------------
391   ConstString GetFileNameExtension() const;
392
393   //------------------------------------------------------------------
394   /// Return the filename without the extension part
395   ///
396   /// Returns a ConstString that represents the filename of this object
397   /// without the extension part (e.g. for a file named "foo.bar", "foo" is
398   /// returned)
399   ///
400   /// @return
401   ///     Returns the filename without extension
402   ///     as a ConstString object.
403   //------------------------------------------------------------------
404   ConstString GetFileNameStrippingExtension() const;
405
406   //------------------------------------------------------------------
407   /// Get the memory cost of this object.
408   ///
409   /// Return the size in bytes that this object takes in memory. This returns
410   /// the size in bytes of this object, not any shared string values it may
411   /// refer to.
412   ///
413   /// @return
414   ///     The number of bytes that this object occupies in memory.
415   ///
416   /// @see ConstString::StaticMemorySize ()
417   //------------------------------------------------------------------
418   size_t MemorySize() const;
419
420   //------------------------------------------------------------------
421   /// Change the file specified with a new path.
422   ///
423   /// Update the contents of this object with a new path. The path will be
424   /// split up into a directory and filename and stored as uniqued string
425   /// values for quick comparison and efficient memory usage.
426   ///
427   /// @param[in] path
428   ///     A full, partial, or relative path to a file.
429   ///
430   /// @param[in] resolve_path
431   ///     If \b true, then we will try to resolve links the path using
432   ///     the static FileSpec::Resolve.
433   //------------------------------------------------------------------
434   void SetFile(llvm::StringRef path, Style style);
435
436   void SetFile(llvm::StringRef path, const llvm::Triple &Triple);
437
438   bool IsResolved() const { return m_is_resolved; }
439
440   //------------------------------------------------------------------
441   /// Set if the file path has been resolved or not.
442   ///
443   /// If you know a file path is already resolved and avoided passing a \b
444   /// true parameter for any functions that take a "bool resolve_path"
445   /// parameter, you can set the value manually using this call to make sure
446   /// we don't try and resolve it later, or try and resolve a path that has
447   /// already been resolved.
448   ///
449   /// @param[in] is_resolved
450   ///     A boolean value that will replace the current value that
451   ///     indicates if the paths in this object have been resolved.
452   //------------------------------------------------------------------
453   void SetIsResolved(bool is_resolved) { m_is_resolved = is_resolved; }
454
455   FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const;
456   FileSpec CopyByRemovingLastPathComponent() const;
457
458   void PrependPathComponent(llvm::StringRef component);
459   void PrependPathComponent(const FileSpec &new_path);
460
461   void AppendPathComponent(llvm::StringRef component);
462   void AppendPathComponent(const FileSpec &new_path);
463
464   //------------------------------------------------------------------
465   /// Removes the last path component by replacing the current path with its
466   /// parent. When the current path has no parent, this is a no-op.
467   ///
468   /// @return
469   ///     A boolean value indicating whether the path was updated.
470   //------------------------------------------------------------------
471   bool RemoveLastPathComponent();
472
473   ConstString GetLastPathComponent() const;
474
475 protected:
476   //------------------------------------------------------------------
477   // Convenience method for setting the file without changing the style.
478   //------------------------------------------------------------------
479   void SetFile(llvm::StringRef path);
480
481   //------------------------------------------------------------------
482   // Member variables
483   //------------------------------------------------------------------
484   ConstString m_directory;            ///< The uniqued directory path
485   ConstString m_filename;             ///< The uniqued filename path
486   mutable bool m_is_resolved = false; ///< True if this path has been resolved.
487   Style m_style; ///< The syntax that this path uses (e.g. Windows / Posix)
488 };
489
490 //----------------------------------------------------------------------
491 /// Dump a FileSpec object to a stream
492 //----------------------------------------------------------------------
493 Stream &operator<<(Stream &s, const FileSpec &f);
494
495 } // namespace lldb_private
496
497 namespace llvm {
498
499 /// Implementation of format_provider<T> for FileSpec.
500 ///
501 /// The options string of a FileSpec has the grammar:
502 ///
503 ///   file_spec_options   :: (empty) | F | D
504 ///
505 ///   =======================================================
506 ///   |  style  |     Meaning          |      Example       |
507 ///   -------------------------------------------------------
508 ///   |         |                      |  Input   |  Output |
509 ///   =======================================================
510 ///   |    F    | Only print filename  | /foo/bar |   bar   |
511 ///   |    D    | Only print directory | /foo/bar |  /foo/  |
512 ///   | (empty) | Print file and dir   |          |         |
513 ///   =======================================================
514 ///
515 /// Any other value is considered an invalid format string.
516 ///
517 template <> struct format_provider<lldb_private::FileSpec> {
518   static void format(const lldb_private::FileSpec &F, llvm::raw_ostream &Stream,
519                      StringRef Style);
520 };
521 } // namespace llvm
522
523 #endif // liblldb_FileSpec_h_