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