]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/Utility/FileSpec.h
MFV r336942: 9189 Add debug to vdev_label_read_config when txg check fails
[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 // C Includes
14 // C++ Includes
15 #include <functional>
16 #include <string>
17
18 // Other libraries and framework includes
19 // Project includes
20 #include "lldb/Utility/ConstString.h"
21
22 #include "llvm/ADT/StringRef.h" // for StringRef
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/FormatVariadic.h"
25
26 #include <stddef.h> // for size_t
27 #include <stdint.h> // for uint32_t, uint64_t
28
29 namespace lldb_private {
30 class Stream;
31 }
32 namespace llvm {
33 class Triple;
34 }
35 namespace llvm {
36 class raw_ostream;
37 }
38 namespace llvm {
39 template <typename T> class SmallVectorImpl;
40 }
41
42 namespace lldb_private {
43
44 //----------------------------------------------------------------------
45 /// @class FileSpec FileSpec.h "lldb/Host/FileSpec.h"
46 /// @brief A file utility class.
47 ///
48 /// A file specification class that divides paths up into a directory
49 /// and basename. These string values of the paths are put into uniqued
50 /// string pools for fast comparisons and efficient memory usage.
51 ///
52 /// Another reason the paths are split into the directory and basename
53 /// is to allow efficient debugger searching. Often in a debugger the
54 /// user types in the basename of the file, for example setting a
55 /// breakpoint by file and line, or specifying a module (shared library)
56 /// to limit the scope in which to execute a command. The user rarely
57 /// types in a full path. When the paths are already split up, it makes
58 /// it easy for us to compare only the basenames of a lot of file
59 /// specifications without having to split up the file path each time
60 /// to get to the basename.
61 //----------------------------------------------------------------------
62 class FileSpec {
63 public:
64   enum PathSyntax : unsigned char {
65     ePathSyntaxPosix,
66     ePathSyntaxWindows,
67     ePathSyntaxHostNative
68   };
69
70   FileSpec();
71
72   //------------------------------------------------------------------
73   /// Constructor with path.
74   ///
75   /// Takes a path to a file which can be just a filename, or a full
76   /// path. If \a path is not nullptr or empty, this function will call
77   /// FileSpec::SetFile (const char *path, bool resolve).
78   ///
79   /// @param[in] path
80   ///     The full or partial path to a file.
81   ///
82   /// @param[in] resolve_path
83   ///     If \b true, then we resolve the path, removing stray ../.. and so
84   ///     forth,
85   ///     if \b false we trust the path is in canonical form already.
86   ///
87   /// @see FileSpec::SetFile (const char *path, bool resolve)
88   //------------------------------------------------------------------
89   explicit FileSpec(llvm::StringRef path, bool resolve_path,
90                     PathSyntax syntax = ePathSyntaxHostNative);
91
92   explicit FileSpec(llvm::StringRef path, bool resolve_path,
93                     const llvm::Triple &Triple);
94
95   //------------------------------------------------------------------
96   /// Copy constructor
97   ///
98   /// Makes a copy of the uniqued directory and filename strings from
99   /// \a rhs.
100   ///
101   /// @param[in] rhs
102   ///     A const FileSpec object reference to copy.
103   //------------------------------------------------------------------
104   FileSpec(const FileSpec &rhs);
105
106   //------------------------------------------------------------------
107   /// Copy constructor
108   ///
109   /// Makes a copy of the uniqued directory and filename strings from
110   /// \a rhs if it is not nullptr.
111   ///
112   /// @param[in] rhs
113   ///     A const FileSpec object pointer to copy if non-nullptr.
114   //------------------------------------------------------------------
115   FileSpec(const FileSpec *rhs);
116
117   //------------------------------------------------------------------
118   /// Destructor.
119   //------------------------------------------------------------------
120   ~FileSpec();
121
122   bool DirectoryEquals(const FileSpec &other) const;
123
124   bool FileEquals(const FileSpec &other) const;
125
126   //------------------------------------------------------------------
127   /// Assignment operator.
128   ///
129   /// Makes a copy of the uniqued directory and filename strings from
130   /// \a rhs.
131   ///
132   /// @param[in] rhs
133   ///     A const FileSpec object reference to assign to this object.
134   ///
135   /// @return
136   ///     A const reference to this object.
137   //------------------------------------------------------------------
138   const FileSpec &operator=(const FileSpec &rhs);
139
140   //------------------------------------------------------------------
141   /// Equal to operator
142   ///
143   /// Tests if this object is equal to \a rhs.
144   ///
145   /// @param[in] rhs
146   ///     A const FileSpec object reference to compare this object
147   ///     to.
148   ///
149   /// @return
150   ///     \b true if this object is equal to \a rhs, \b false
151   ///     otherwise.
152   //------------------------------------------------------------------
153   bool operator==(const FileSpec &rhs) const;
154
155   //------------------------------------------------------------------
156   /// Not equal to operator
157   ///
158   /// Tests if this object is not equal to \a rhs.
159   ///
160   /// @param[in] rhs
161   ///     A const FileSpec object reference to compare this object
162   ///     to.
163   ///
164   /// @return
165   ///     \b true if this object is equal to \a rhs, \b false
166   ///     otherwise.
167   //------------------------------------------------------------------
168   bool operator!=(const FileSpec &rhs) const;
169
170   //------------------------------------------------------------------
171   /// Less than to operator
172   ///
173   /// Tests if this object is less than \a rhs.
174   ///
175   /// @param[in] rhs
176   ///     A const FileSpec object reference to compare this object
177   ///     to.
178   ///
179   /// @return
180   ///     \b true if this object is less than \a rhs, \b false
181   ///     otherwise.
182   //------------------------------------------------------------------
183   bool operator<(const FileSpec &rhs) const;
184
185   //------------------------------------------------------------------
186   /// Convert to pointer operator.
187   ///
188   /// This allows code to check a FileSpec object to see if it
189   /// contains anything valid using code such as:
190   ///
191   /// @code
192   /// FileSpec file_spec(...);
193   /// if (file_spec)
194   /// { ...
195   /// @endcode
196   ///
197   /// @return
198   ///     A pointer to this object if either the directory or filename
199   ///     is valid, nullptr otherwise.
200   //------------------------------------------------------------------
201   explicit operator bool() const;
202
203   //------------------------------------------------------------------
204   /// Logical NOT operator.
205   ///
206   /// This allows code to check a FileSpec object to see if it is
207   /// invalid using code such as:
208   ///
209   /// @code
210   /// FileSpec file_spec(...);
211   /// if (!file_spec)
212   /// { ...
213   /// @endcode
214   ///
215   /// @return
216   ///     Returns \b true if the object has an empty directory and
217   ///     filename, \b false otherwise.
218   //------------------------------------------------------------------
219   bool operator!() const;
220
221   //------------------------------------------------------------------
222   /// Clears the object state.
223   ///
224   /// Clear this object by releasing both the directory and filename
225   /// string values and reverting them to empty strings.
226   //------------------------------------------------------------------
227   void Clear();
228
229   //------------------------------------------------------------------
230   /// Compare two FileSpec objects.
231   ///
232   /// If \a full is true, then both the directory and the filename
233   /// must match. If \a full is false, then the directory names for
234   /// \a lhs and \a rhs are only compared if they are both not empty.
235   /// This allows a FileSpec object to only contain a filename
236   /// and it can match FileSpec objects that have matching
237   /// filenames with different paths.
238   ///
239   /// @param[in] lhs
240   ///     A const reference to the Left Hand Side object to compare.
241   ///
242   /// @param[in] rhs
243   ///     A const reference to the Right Hand Side object to compare.
244   ///
245   /// @param[in] full
246   ///     If true, then both the directory and filenames will have to
247   ///     match for a compare to return zero (equal to). If false
248   ///     and either directory from \a lhs or \a rhs is empty, then
249   ///     only the filename will be compared, else a full comparison
250   ///     is done.
251   ///
252   /// @return
253   ///     @li -1 if \a lhs is less than \a rhs
254   ///     @li 0 if \a lhs is equal to \a rhs
255   ///     @li 1 if \a lhs is greater than \a rhs
256   //------------------------------------------------------------------
257   static int Compare(const FileSpec &lhs, const FileSpec &rhs, bool full);
258
259   static bool Equal(const FileSpec &a, const FileSpec &b, bool full,
260                     bool remove_backups = false);
261
262   //------------------------------------------------------------------
263   /// Case sensitivity of path.
264   ///
265   /// @return
266   ///     \b true if the file path is case sensitive (POSIX), false
267   ///           if case insensitive (Windows).
268   //------------------------------------------------------------------
269   bool IsCaseSensitive() const { return m_syntax != ePathSyntaxWindows; }
270
271   //------------------------------------------------------------------
272   /// Dump this object to a Stream.
273   ///
274   /// Dump the object to the supplied stream \a s. If the object
275   /// contains a valid directory name, it will be displayed followed
276   /// by a directory delimiter, and the filename.
277   ///
278   /// @param[in] s
279   ///     The stream to which to dump the object description.
280   //------------------------------------------------------------------
281   void Dump(Stream *s) const;
282
283   //------------------------------------------------------------------
284   /// Existence test.
285   ///
286   /// @return
287   ///     \b true if the file exists on disk, \b false otherwise.
288   //------------------------------------------------------------------
289   bool Exists() const;
290
291   //------------------------------------------------------------------
292   /// Check if a file is readable by the current user
293   ///
294   /// @return
295   ///     \b true if the file exists on disk and is readable, \b false
296   ///     otherwise.
297   //------------------------------------------------------------------
298   bool Readable() const;
299
300   //------------------------------------------------------------------
301   /// Expanded existence test.
302   ///
303   /// Call into the Host to see if it can help find the file (e.g. by
304   /// searching paths set in the environment, etc.).
305   ///
306   /// If found, sets the value of m_directory to the directory where
307   /// the file was found.
308   ///
309   /// @return
310   ///     \b true if was able to find the file using expanded search
311   ///     methods, \b false otherwise.
312   //------------------------------------------------------------------
313   bool ResolveExecutableLocation();
314
315   //------------------------------------------------------------------
316   /// Canonicalize this file path (basically running the static
317   /// FileSpec::Resolve method on it). Useful if you asked us not to
318   /// resolve the file path when you set the file.
319   //------------------------------------------------------------------
320   bool ResolvePath();
321
322   uint64_t GetByteSize() const;
323
324   PathSyntax GetPathSyntax() const;
325
326   //------------------------------------------------------------------
327   /// Directory string get accessor.
328   ///
329   /// @return
330   ///     A reference to the directory string object.
331   //------------------------------------------------------------------
332   ConstString &GetDirectory();
333
334   //------------------------------------------------------------------
335   /// Directory string const get accessor.
336   ///
337   /// @return
338   ///     A const reference to the directory string object.
339   //------------------------------------------------------------------
340   const ConstString &GetDirectory() const;
341
342   //------------------------------------------------------------------
343   /// Filename string get accessor.
344   ///
345   /// @return
346   ///     A reference to the filename string object.
347   //------------------------------------------------------------------
348   ConstString &GetFilename();
349
350   //------------------------------------------------------------------
351   /// Filename string const get accessor.
352   ///
353   /// @return
354   ///     A const reference to the filename string object.
355   //------------------------------------------------------------------
356   const ConstString &GetFilename() const;
357
358   //------------------------------------------------------------------
359   /// Returns true if the filespec represents an implementation source
360   /// file (files with a ".c", ".cpp", ".m", ".mm" (many more)
361   /// extension).
362   ///
363   /// @return
364   ///     \b true if the filespec represents an implementation source
365   ///     file, \b false otherwise.
366   //------------------------------------------------------------------
367   bool IsSourceImplementationFile() const;
368
369   //------------------------------------------------------------------
370   /// Returns true if the filespec represents a relative path.
371   ///
372   /// @return
373   ///     \b true if the filespec represents a relative path,
374   ///     \b false otherwise.
375   //------------------------------------------------------------------
376   bool IsRelative() const;
377
378   //------------------------------------------------------------------
379   /// Returns true if the filespec represents an absolute path.
380   ///
381   /// @return
382   ///     \b true if the filespec represents an absolute path,
383   ///     \b false otherwise.
384   //------------------------------------------------------------------
385   bool IsAbsolute() const;
386
387   //------------------------------------------------------------------
388   /// Extract the full path to the file.
389   ///
390   /// Extract the directory and path into a fixed buffer. This is
391   /// needed as the directory and path are stored in separate string
392   /// values.
393   ///
394   /// @param[out] path
395   ///     The buffer in which to place the extracted full path.
396   ///
397   /// @param[in] max_path_length
398   ///     The maximum length of \a path.
399   ///
400   /// @return
401   ///     Returns the number of characters that would be needed to
402   ///     properly copy the full path into \a path. If the returned
403   ///     number is less than \a max_path_length, then the path is
404   ///     properly copied and terminated. If the return value is
405   ///     >= \a max_path_length, then the path was truncated (but is
406   ///     still NULL terminated).
407   //------------------------------------------------------------------
408   size_t GetPath(char *path, size_t max_path_length,
409                  bool denormalize = true) const;
410
411   //------------------------------------------------------------------
412   /// Extract the full path to the file.
413   ///
414   /// Extract the directory and path into a std::string, which is returned.
415   ///
416   /// @return
417   ///     Returns a std::string with the directory and filename
418   ///     concatenated.
419   //------------------------------------------------------------------
420   std::string GetPath(bool denormalize = true) const;
421
422   const char *GetCString(bool denormalize = true) const;
423
424   //------------------------------------------------------------------
425   /// Extract the full path to the file.
426   ///
427   /// Extract the directory and path into an llvm::SmallVectorImpl<>
428   ///
429   /// @return
430   ///     Returns a std::string with the directory and filename
431   ///     concatenated.
432   //------------------------------------------------------------------
433   void GetPath(llvm::SmallVectorImpl<char> &path,
434                bool denormalize = true) const;
435
436   //------------------------------------------------------------------
437   /// Extract the extension of the file.
438   ///
439   /// Returns a ConstString that represents the extension of the filename
440   /// for this FileSpec object. If this object does not represent a file,
441   /// or the filename has no extension, ConstString(nullptr) is returned.
442   /// The dot ('.') character is not returned as part of the extension
443   ///
444   /// @return
445   ///     Returns the extension of the file as a ConstString object.
446   //------------------------------------------------------------------
447   ConstString GetFileNameExtension() const;
448
449   //------------------------------------------------------------------
450   /// Return the filename without the extension part
451   ///
452   /// Returns a ConstString that represents the filename of this object
453   /// without the extension part (e.g. for a file named "foo.bar", "foo"
454   /// is returned)
455   ///
456   /// @return
457   ///     Returns the filename without extension
458   ///     as a ConstString object.
459   //------------------------------------------------------------------
460   ConstString GetFileNameStrippingExtension() const;
461
462   //------------------------------------------------------------------
463   /// Return the current permissions of the path.
464   ///
465   /// Returns a bitmask for the current permissions of the file
466   /// ( zero or more of the permission bits defined in
467   /// File::Permissions).
468   ///
469   /// @return
470   ///     Zero if the file doesn't exist or we are unable to get
471   ///     information for the file, otherwise one or more permission
472   ///     bits from the File::Permissions enumeration.
473   //------------------------------------------------------------------
474   uint32_t GetPermissions() const;
475
476   //------------------------------------------------------------------
477   /// Get the memory cost of this object.
478   ///
479   /// Return the size in bytes that this object takes in memory. This
480   /// returns the size in bytes of this object, not any shared string
481   /// values it may refer to.
482   ///
483   /// @return
484   ///     The number of bytes that this object occupies in memory.
485   ///
486   /// @see ConstString::StaticMemorySize ()
487   //------------------------------------------------------------------
488   size_t MemorySize() const;
489
490   //------------------------------------------------------------------
491   /// Normalize a pathname by collapsing redundant separators and
492   /// up-level references.
493   //------------------------------------------------------------------
494   FileSpec GetNormalizedPath() const;
495
496   //------------------------------------------------------------------
497   /// Change the file specified with a new path.
498   ///
499   /// Update the contents of this object with a new path. The path will
500   /// be split up into a directory and filename and stored as uniqued
501   /// string values for quick comparison and efficient memory usage.
502   ///
503   /// @param[in] path
504   ///     A full, partial, or relative path to a file.
505   ///
506   /// @param[in] resolve_path
507   ///     If \b true, then we will try to resolve links the path using
508   ///     the static FileSpec::Resolve.
509   //------------------------------------------------------------------
510   void SetFile(llvm::StringRef path, bool resolve_path,
511                PathSyntax syntax = ePathSyntaxHostNative);
512
513   void SetFile(llvm::StringRef path, bool resolve_path,
514                const llvm::Triple &Triple);
515
516   bool IsResolved() const { return m_is_resolved; }
517
518   //------------------------------------------------------------------
519   /// Set if the file path has been resolved or not.
520   ///
521   /// If you know a file path is already resolved and avoided passing
522   /// a \b true parameter for any functions that take a "bool
523   /// resolve_path" parameter, you can set the value manually using
524   /// this call to make sure we don't try and resolve it later, or try
525   /// and resolve a path that has already been resolved.
526   ///
527   /// @param[in] is_resolved
528   ///     A boolean value that will replace the current value that
529   ///     indicates if the paths in this object have been resolved.
530   //------------------------------------------------------------------
531   void SetIsResolved(bool is_resolved) { m_is_resolved = is_resolved; }
532
533   //------------------------------------------------------------------
534   /// Resolves user name and links in \a path, and overwrites the input
535   /// argument with the resolved path.
536   ///
537   /// @param[in] path
538   ///     Input path to be resolved, in the form of a llvm::SmallString or
539   ///     similar.
540   //------------------------------------------------------------------
541   static void Resolve(llvm::SmallVectorImpl<char> &path);
542
543   FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const;
544   FileSpec CopyByRemovingLastPathComponent() const;
545
546   void PrependPathComponent(llvm::StringRef component);
547   void PrependPathComponent(const FileSpec &new_path);
548
549   void AppendPathComponent(llvm::StringRef component);
550   void AppendPathComponent(const FileSpec &new_path);
551
552   void RemoveLastPathComponent();
553
554   ConstString GetLastPathComponent() const;
555
556   enum EnumerateDirectoryResult {
557     eEnumerateDirectoryResultNext,  // Enumerate next entry in the current
558                                     // directory
559     eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a
560                                     // directory or symlink, or next if not
561     eEnumerateDirectoryResultQuit   // Stop directory enumerations at any level
562   };
563
564   typedef EnumerateDirectoryResult (*EnumerateDirectoryCallbackType)(
565       void *baton, llvm::sys::fs::file_type file_type, const FileSpec &spec);
566
567   static void EnumerateDirectory(llvm::StringRef dir_path,
568                                  bool find_directories, bool find_files,
569                                  bool find_other,
570                                  EnumerateDirectoryCallbackType callback,
571                                  void *callback_baton);
572
573   typedef std::function<EnumerateDirectoryResult(
574       llvm::sys::fs::file_type file_type, const FileSpec &spec)>
575       DirectoryCallback;
576
577 protected:
578   //------------------------------------------------------------------
579   // Member variables
580   //------------------------------------------------------------------
581   ConstString m_directory;            ///< The uniqued directory path
582   ConstString m_filename;             ///< The uniqued filename path
583   mutable bool m_is_resolved = false; ///< True if this path has been resolved.
584   PathSyntax
585       m_syntax; ///< The syntax that this path uses (e.g. Windows / Posix)
586 };
587
588 //----------------------------------------------------------------------
589 /// Dump a FileSpec object to a stream
590 //----------------------------------------------------------------------
591 Stream &operator<<(Stream &s, const FileSpec &f);
592
593 } // namespace lldb_private
594
595 namespace llvm {
596
597 /// Implementation of format_provider<T> for FileSpec.
598 ///
599 /// The options string of a FileSpec has the grammar:
600 ///
601 ///   file_spec_options   :: (empty) | F | D
602 ///
603 ///   =======================================================
604 ///   |  style  |     Meaning          |      Example       |
605 ///   -------------------------------------------------------
606 ///   |         |                      |  Input   |  Output |
607 ///   =======================================================
608 ///   |    F    | Only print filename  | /foo/bar |   bar   |
609 ///   |    D    | Only print directory | /foo/bar |  /foo/  |
610 ///   | (empty) | Print file and dir   |          |         |
611 ///   =======================================================
612 ///
613 /// Any other value is considered an invalid format string.
614 ///
615 template <> struct format_provider<lldb_private::FileSpec> {
616   static void format(const lldb_private::FileSpec &F, llvm::raw_ostream &Stream,
617                      StringRef Style);
618 };
619 }
620
621 #endif // liblldb_FileSpec_h_