FileSpec.h revision 263367
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#if defined(__cplusplus) 13 14#include "lldb/lldb-private.h" 15#include "lldb/Core/ConstString.h" 16#include "lldb/Core/STLUtils.h" 17#include "lldb/Host/TimeValue.h" 18 19namespace lldb_private { 20 21//---------------------------------------------------------------------- 22/// @class FileSpec FileSpec.h "lldb/Host/FileSpec.h" 23/// @brief A file utility class. 24/// 25/// A file specification class that divides paths up into a directory 26/// and basename. These string values of the paths are put into uniqued 27/// string pools for fast comparisons and efficient memory usage. 28/// 29/// Another reason the paths are split into the directory and basename 30/// is to allow efficient debugger searching. Often in a debugger the 31/// user types in the basename of the file, for example setting a 32/// breakpoint by file and line, or specifying a module (shared library) 33/// to limit the scope in which to execute a command. The user rarely 34/// types in a full path. When the paths are already split up, it makes 35/// it easy for us to compare only the basenames of a lot of file 36/// specifications without having to split up the file path each time 37/// to get to the basename. 38//---------------------------------------------------------------------- 39class FileSpec 40{ 41public: 42 typedef enum FileType 43 { 44 eFileTypeInvalid = -1, 45 eFileTypeUnknown = 0, 46 eFileTypeDirectory, 47 eFileTypePipe, 48 eFileTypeRegular, 49 eFileTypeSocket, 50 eFileTypeSymbolicLink, 51 eFileTypeOther 52 } FileType; 53 54 FileSpec(); 55 56 //------------------------------------------------------------------ 57 /// Constructor with path. 58 /// 59 /// Takes a path to a file which can be just a filename, or a full 60 /// path. If \a path is not NULL or empty, this function will call 61 /// FileSpec::SetFile (const char *path, bool resolve). 62 /// 63 /// @param[in] path 64 /// The full or partial path to a file. 65 /// 66 /// @param[in] resolve_path 67 /// If \b true, then we resolve the path with realpath, 68 /// if \b false we trust the path is in canonical form already. 69 /// 70 /// @see FileSpec::SetFile (const char *path, bool resolve) 71 //------------------------------------------------------------------ 72 explicit FileSpec (const char *path, bool resolve_path); 73 74 //------------------------------------------------------------------ 75 /// Copy constructor 76 /// 77 /// Makes a copy of the uniqued directory and filename strings from 78 /// \a rhs. 79 /// 80 /// @param[in] rhs 81 /// A const FileSpec object reference to copy. 82 //------------------------------------------------------------------ 83 FileSpec (const FileSpec& rhs); 84 85 //------------------------------------------------------------------ 86 /// Copy constructor 87 /// 88 /// Makes a copy of the uniqued directory and filename strings from 89 /// \a rhs if it is not NULL. 90 /// 91 /// @param[in] rhs 92 /// A const FileSpec object pointer to copy if non-NULL. 93 //------------------------------------------------------------------ 94 FileSpec (const FileSpec* rhs); 95 96 //------------------------------------------------------------------ 97 /// Destructor. 98 //------------------------------------------------------------------ 99 ~FileSpec (); 100 101 //------------------------------------------------------------------ 102 /// Assignment operator. 103 /// 104 /// Makes a copy of the uniqued directory and filename strings from 105 /// \a rhs. 106 /// 107 /// @param[in] rhs 108 /// A const FileSpec object reference to assign to this object. 109 /// 110 /// @return 111 /// A const reference to this object. 112 //------------------------------------------------------------------ 113 const FileSpec& 114 operator= (const FileSpec& rhs); 115 116 //------------------------------------------------------------------ 117 /// Equal to operator 118 /// 119 /// Tests if this object is equal to \a rhs. 120 /// 121 /// @param[in] rhs 122 /// A const FileSpec object reference to compare this object 123 /// to. 124 /// 125 /// @return 126 /// \b true if this object is equal to \a rhs, \b false 127 /// otherwise. 128 //------------------------------------------------------------------ 129 bool 130 operator== (const FileSpec& rhs) const; 131 132 //------------------------------------------------------------------ 133 /// Not equal to operator 134 /// 135 /// Tests if this object is not equal to \a rhs. 136 /// 137 /// @param[in] rhs 138 /// A const FileSpec object reference to compare this object 139 /// to. 140 /// 141 /// @return 142 /// \b true if this object is equal to \a rhs, \b false 143 /// otherwise. 144 //------------------------------------------------------------------ 145 bool 146 operator!= (const FileSpec& rhs) const; 147 148 //------------------------------------------------------------------ 149 /// Less than to operator 150 /// 151 /// Tests if this object is less than \a rhs. 152 /// 153 /// @param[in] rhs 154 /// A const FileSpec object reference to compare this object 155 /// to. 156 /// 157 /// @return 158 /// \b true if this object is less than \a rhs, \b false 159 /// otherwise. 160 //------------------------------------------------------------------ 161 bool 162 operator< (const FileSpec& rhs) const; 163 164 //------------------------------------------------------------------ 165 /// Convert to pointer operator. 166 /// 167 /// This allows code to check a FileSpec object to see if it 168 /// contains anything valid using code such as: 169 /// 170 /// @code 171 /// FileSpec file_spec(...); 172 /// if (file_spec) 173 /// { ... 174 /// @endcode 175 /// 176 /// @return 177 /// A pointer to this object if either the directory or filename 178 /// is valid, NULL otherwise. 179 //------------------------------------------------------------------ 180 explicit operator bool() const; 181 182 //------------------------------------------------------------------ 183 /// Logical NOT operator. 184 /// 185 /// This allows code to check a FileSpec object to see if it is 186 /// invalid using code such as: 187 /// 188 /// @code 189 /// FileSpec file_spec(...); 190 /// if (!file_spec) 191 /// { ... 192 /// @endcode 193 /// 194 /// @return 195 /// Returns \b true if the object has an empty directory and 196 /// filename, \b false otherwise. 197 //------------------------------------------------------------------ 198 bool 199 operator! () const; 200 201 //------------------------------------------------------------------ 202 /// Clears the object state. 203 /// 204 /// Clear this object by releasing both the directory and filename 205 /// string values and reverting them to empty strings. 206 //------------------------------------------------------------------ 207 void 208 Clear (); 209 210 //------------------------------------------------------------------ 211 /// Compare two FileSpec objects. 212 /// 213 /// If \a full is true, then both the directory and the filename 214 /// must match. If \a full is false, then the directory names for 215 /// \a lhs and \a rhs are only compared if they are both not empty. 216 /// This allows a FileSpec object to only contain a filename 217 /// and it can match FileSpec objects that have matching 218 /// filenames with different paths. 219 /// 220 /// @param[in] lhs 221 /// A const reference to the Left Hand Side object to compare. 222 /// 223 /// @param[in] rhs 224 /// A const reference to the Right Hand Side object to compare. 225 /// 226 /// @param[in] full 227 /// If true, then both the directory and filenames will have to 228 /// match for a compare to return zero (equal to). If false 229 /// and either directory from \a lhs or \a rhs is empty, then 230 /// only the filename will be compared, else a full comparison 231 /// is done. 232 /// 233 /// @return 234 /// @li -1 if \a lhs is less than \a rhs 235 /// @li 0 if \a lhs is equal to \a rhs 236 /// @li 1 if \a lhs is greater than \a rhs 237 //------------------------------------------------------------------ 238 static int 239 Compare (const FileSpec& lhs, const FileSpec& rhs, bool full); 240 241 static bool 242 Equal (const FileSpec& a, const FileSpec& b, bool full); 243 244 //------------------------------------------------------------------ 245 /// Dump this object to a Stream. 246 /// 247 /// Dump the object to the supplied stream \a s. If the object 248 /// contains a valid directory name, it will be displayed followed 249 /// by a directory delimiter, and the filename. 250 /// 251 /// @param[in] s 252 /// The stream to which to dump the object descripton. 253 //------------------------------------------------------------------ 254 void 255 Dump (Stream *s) const; 256 257 //------------------------------------------------------------------ 258 /// Existence test. 259 /// 260 /// @return 261 /// \b true if the file exists on disk, \b false otherwise. 262 //------------------------------------------------------------------ 263 bool 264 Exists () const; 265 266 267 //------------------------------------------------------------------ 268 /// Expanded existence test. 269 /// 270 /// Call into the Host to see if it can help find the file (e.g. by 271 /// searching paths set in the environment, etc.). 272 /// 273 /// If found, sets the value of m_directory to the directory where 274 /// the file was found. 275 /// 276 /// @return 277 /// \b true if was able to find the file using expanded search 278 /// methods, \b false otherwise. 279 //------------------------------------------------------------------ 280 bool 281 ResolveExecutableLocation (); 282 283 //------------------------------------------------------------------ 284 /// Canonicalize this file path (basically running the static 285 /// FileSpec::Resolve method on it). Useful if you asked us not to 286 /// resolve the file path when you set the file. 287 //------------------------------------------------------------------ 288 bool 289 ResolvePath (); 290 291 uint64_t 292 GetByteSize() const; 293 294 //------------------------------------------------------------------ 295 /// Directory string get accessor. 296 /// 297 /// @return 298 /// A reference to the directory string object. 299 //------------------------------------------------------------------ 300 ConstString & 301 GetDirectory (); 302 303 //------------------------------------------------------------------ 304 /// Directory string const get accessor. 305 /// 306 /// @return 307 /// A const reference to the directory string object. 308 //------------------------------------------------------------------ 309 const ConstString & 310 GetDirectory () const; 311 312 //------------------------------------------------------------------ 313 /// Filename string get accessor. 314 /// 315 /// @return 316 /// A reference to the filename string object. 317 //------------------------------------------------------------------ 318 ConstString & 319 GetFilename (); 320 321 //------------------------------------------------------------------ 322 /// Filename string const get accessor. 323 /// 324 /// @return 325 /// A const reference to the filename string object. 326 //------------------------------------------------------------------ 327 const ConstString & 328 GetFilename () const; 329 330 //------------------------------------------------------------------ 331 /// Returns true if the filespec represents an implementation source 332 /// file (files with a ".c", ".cpp", ".m", ".mm" (many more) 333 /// extension). 334 /// 335 /// @return 336 /// \b true if the filespec represents an implementation source 337 /// file, \b false otherwise. 338 //------------------------------------------------------------------ 339 bool 340 IsSourceImplementationFile () const; 341 342 //------------------------------------------------------------------ 343 /// Returns true if the filespec represents path that is relative 344 /// path to the current working directory. 345 /// 346 /// @return 347 /// \b true if the filespec represents a current working 348 /// directory relative path, \b false otherwise. 349 //------------------------------------------------------------------ 350 bool 351 IsRelativeToCurrentWorkingDirectory () const; 352 353 TimeValue 354 GetModificationTime () const; 355 356 //------------------------------------------------------------------ 357 /// Extract the full path to the file. 358 /// 359 /// Extract the directory and path into a fixed buffer. This is 360 /// needed as the directory and path are stored in separate string 361 /// values. 362 /// 363 /// @param[out] path 364 /// The buffer in which to place the extracted full path. 365 /// 366 /// @param[in] max_path_length 367 /// The maximum length of \a path. 368 /// 369 /// @return 370 /// Returns the number of characters that would be needed to 371 /// properly copy the full path into \a path. If the returned 372 /// number is less than \a max_path_length, then the path is 373 /// properly copied and terminated. If the return value is 374 /// >= \a max_path_length, then the path was truncated (but is 375 /// still NULL terminated). 376 //------------------------------------------------------------------ 377 size_t 378 GetPath (char *path, size_t max_path_length) const; 379 380 //------------------------------------------------------------------ 381 /// Extract the full path to the file. 382 /// 383 /// Extract the directory and path into a std::string, which is returned. 384 /// 385 /// @return 386 /// Returns a std::string with the directory and filename 387 /// concatenated. 388 //------------------------------------------------------------------ 389 std::string 390 GetPath () const; 391 392 //------------------------------------------------------------------ 393 /// Extract the extension of the file. 394 /// 395 /// Returns a ConstString that represents the extension of the filename 396 /// for this FileSpec object. If this object does not represent a file, 397 /// or the filename has no extension, ConstString(NULL) is returned. 398 /// The dot ('.') character is not returned as part of the extension 399 /// 400 /// @return 401 /// Returns the extension of the file as a ConstString object. 402 //------------------------------------------------------------------ 403 ConstString 404 GetFileNameExtension () const; 405 406 //------------------------------------------------------------------ 407 /// Return the filename without the extension part 408 /// 409 /// Returns a ConstString that represents the filename of this object 410 /// without the extension part (e.g. for a file named "foo.bar", "foo" 411 /// is returned) 412 /// 413 /// @return 414 /// Returns the filename without extension 415 /// as a ConstString object. 416 //------------------------------------------------------------------ 417 ConstString 418 GetFileNameStrippingExtension () const; 419 420 FileType 421 GetFileType () const; 422 423 //------------------------------------------------------------------ 424 /// Return the current permissions of the path. 425 /// 426 /// Returns a bitmask for the current permissions of the file 427 /// ( zero or more of the permission bits defined in 428 /// File::Permissions). 429 /// 430 /// @return 431 /// Zero if the file doesn't exist or we are unable to get 432 /// information for the file, otherwise one or more permission 433 /// bits from the File::Permissions enumeration. 434 //------------------------------------------------------------------ 435 uint32_t 436 GetPermissions () const; 437 438 bool 439 IsDirectory () const 440 { 441 return GetFileType() == FileSpec::eFileTypeDirectory; 442 } 443 444 bool 445 IsPipe () const 446 { 447 return GetFileType() == FileSpec::eFileTypePipe; 448 } 449 450 bool 451 IsRegularFile () const 452 { 453 return GetFileType() == FileSpec::eFileTypeRegular; 454 } 455 456 bool 457 IsSocket () const 458 { 459 return GetFileType() == FileSpec::eFileTypeSocket; 460 } 461 462 bool 463 IsSymbolicLink () const 464 { 465 return GetFileType() == FileSpec::eFileTypeSymbolicLink; 466 } 467 468 //------------------------------------------------------------------ 469 /// Get the memory cost of this object. 470 /// 471 /// Return the size in bytes that this object takes in memory. This 472 /// returns the size in bytes of this object, not any shared string 473 /// values it may refer to. 474 /// 475 /// @return 476 /// The number of bytes that this object occupies in memory. 477 /// 478 /// @see ConstString::StaticMemorySize () 479 //------------------------------------------------------------------ 480 size_t 481 MemorySize () const; 482 483 //------------------------------------------------------------------ 484 /// Memory map part of, or the entire contents of, a file. 485 /// 486 /// Returns a shared pointer to a data buffer that contains all or 487 /// part of the contents of a file. The data is memory mapped and 488 /// will lazily page in data from the file as memory is accessed. 489 /// The data that is mappped will start \a offset bytes into the 490 /// file, and \a length bytes will be mapped. If \a length is 491 /// greater than the number of bytes available in the file starting 492 /// at \a offset, the number of bytes will be appropriately 493 /// truncated. The final number of bytes that get mapped can be 494 /// verified using the DataBuffer::GetByteSize() function on the return 495 /// shared data pointer object contents. 496 /// 497 /// @param[in] offset 498 /// The offset in bytes from the beginning of the file where 499 /// memory mapping should begin. 500 /// 501 /// @param[in] length 502 /// The size in bytes that should be mapped starting \a offset 503 /// bytes into the file. If \a length is \c SIZE_MAX, map 504 /// as many bytes as possible. 505 /// 506 /// @return 507 /// A shared pointer to the memeory mapped data. This shared 508 /// pointer can contain a NULL DataBuffer pointer, so the contained 509 /// pointer must be checked prior to using it. 510 //------------------------------------------------------------------ 511 lldb::DataBufferSP 512 MemoryMapFileContents (off_t offset = 0, size_t length = SIZE_MAX) const; 513 514 //------------------------------------------------------------------ 515 /// Read part of, or the entire contents of, a file into a heap based data buffer. 516 /// 517 /// Returns a shared pointer to a data buffer that contains all or 518 /// part of the contents of a file. The data copies into a heap based 519 /// buffer that lives in the DataBuffer shared pointer object returned. 520 /// The data that is cached will start \a offset bytes into the 521 /// file, and \a length bytes will be mapped. If \a length is 522 /// greater than the number of bytes available in the file starting 523 /// at \a offset, the number of bytes will be appropriately 524 /// truncated. The final number of bytes that get mapped can be 525 /// verified using the DataBuffer::GetByteSize() function. 526 /// 527 /// @param[in] offset 528 /// The offset in bytes from the beginning of the file where 529 /// memory mapping should begin. 530 /// 531 /// @param[in] length 532 /// The size in bytes that should be mapped starting \a offset 533 /// bytes into the file. If \a length is \c SIZE_MAX, map 534 /// as many bytes as possible. 535 /// 536 /// @return 537 /// A shared pointer to the memeory mapped data. This shared 538 /// pointer can contain a NULL DataBuffer pointer, so the contained 539 /// pointer must be checked prior to using it. 540 //------------------------------------------------------------------ 541 lldb::DataBufferSP 542 ReadFileContents (off_t offset = 0, size_t length = SIZE_MAX, Error *error_ptr = NULL) const; 543 544 size_t 545 ReadFileContents (off_t file_offset, void *dst, size_t dst_len, Error *error_ptr) const; 546 547 548 //------------------------------------------------------------------ 549 /// Read the entire contents of a file as data that can be used 550 /// as a C string. 551 /// 552 /// Read the entire contents of a file and ensure that the data 553 /// is NULL terminated so it can be used as a C string. 554 /// 555 /// @return 556 /// A shared pointer to the data. This shared pointer can 557 /// contain a NULL DataBuffer pointer, so the contained pointer 558 /// must be checked prior to using it. 559 //------------------------------------------------------------------ 560 lldb::DataBufferSP 561 ReadFileContentsAsCString(Error *error_ptr = NULL); 562 //------------------------------------------------------------------ 563 /// Change the file specificed with a new path. 564 /// 565 /// Update the contents of this object with a new path. The path will 566 /// be split up into a directory and filename and stored as uniqued 567 /// string values for quick comparison and efficient memory usage. 568 /// 569 /// @param[in] path 570 /// A full, partial, or relative path to a file. 571 /// 572 /// @param[in] resolve_path 573 /// If \b true, then we will try to resolve links the path using 574 /// the static FileSpec::Resolve. 575 //------------------------------------------------------------------ 576 void 577 SetFile (const char *path, bool resolve_path); 578 579 bool 580 IsResolved () const 581 { 582 return m_is_resolved; 583 } 584 585 //------------------------------------------------------------------ 586 /// Set if the file path has been resolved or not. 587 /// 588 /// If you know a file path is already resolved and avoided passing 589 /// a \b true parameter for any functions that take a "bool 590 /// resolve_path" parameter, you can set the value manually using 591 /// this call to make sure we don't try and resolve it later, or try 592 /// and resolve a path that has already been resolved. 593 /// 594 /// @param[in] is_resolved 595 /// A boolean value that will replace the current value that 596 /// indicates if the paths in this object have been resolved. 597 //------------------------------------------------------------------ 598 void 599 SetIsResolved (bool is_resolved) 600 { 601 m_is_resolved = is_resolved; 602 } 603 //------------------------------------------------------------------ 604 /// Read the file into an array of strings, one per line. 605 /// 606 /// Opens and reads the file in this object into an array of strings, 607 /// one string per line of the file. Returns a boolean indicating 608 /// success or failure. 609 /// 610 /// @param[out] lines 611 /// The string array into which to read the file. 612 /// 613 /// @result 614 /// Returns the number of lines that were read from the file. 615 //------------------------------------------------------------------ 616 size_t 617 ReadFileLines (STLStringArray &lines); 618 619 //------------------------------------------------------------------ 620 /// Resolves user name and links in \a src_path, and writes the output 621 /// to \a dst_path. Note if the path pointed to by \a src_path does not 622 /// exist, the contents of \a src_path will be copied to \a dst_path 623 /// unchanged. 624 /// 625 /// @param[in] src_path 626 /// Input path to be resolved. 627 /// 628 /// @param[in] dst_path 629 /// Buffer to store the resolved path. 630 /// 631 /// @param[in] dst_len 632 /// Size of the buffer pointed to by dst_path. 633 /// 634 /// @result 635 /// The number of characters required to write the resolved path. If the 636 /// resolved path doesn't fit in dst_len, dst_len-1 characters will 637 /// be written to \a dst_path, but the actual required length will still be returned. 638 //------------------------------------------------------------------ 639 static size_t 640 Resolve (const char *src_path, char *dst_path, size_t dst_len); 641 642 FileSpec 643 CopyByAppendingPathComponent (const char *new_path) const; 644 645 FileSpec 646 CopyByRemovingLastPathComponent () const; 647 648 void 649 AppendPathComponent (const char *new_path); 650 651 void 652 RemoveLastPathComponent (); 653 654 ConstString 655 GetLastPathComponent () const; 656 657 //------------------------------------------------------------------ 658 /// Resolves the user name at the beginning of \a src_path, and writes the output 659 /// to \a dst_path. Note, \a src_path can contain other path components after the 660 /// user name, they will be copied over, and if the path doesn't start with "~" it 661 /// will also be copied over to \a dst_path. 662 /// 663 /// @param[in] src_path 664 /// Input path to be resolved. 665 /// 666 /// @param[in] dst_path 667 /// Buffer to store the resolved path. 668 /// 669 /// @param[in] dst_len 670 /// Size of the buffer pointed to by dst_path. 671 /// 672 /// @result 673 /// The number of characters required to write the resolved path, or 0 if 674 /// the user name could not be found. If the 675 /// resolved path doesn't fit in dst_len, dst_len-1 characters will 676 /// be written to \a dst_path, but the actual required length will still be returned. 677 //------------------------------------------------------------------ 678 static size_t 679 ResolveUsername (const char *src_path, char *dst_path, size_t dst_len); 680 681 static size_t 682 ResolvePartialUsername (const char *partial_name, StringList &matches); 683 684 enum EnumerateDirectoryResult 685 { 686 eEnumerateDirectoryResultNext, // Enumerate next entry in the current directory 687 eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a directory or symlink, or next if not 688 eEnumerateDirectoryResultExit, // Exit from the current directory at the current level. 689 eEnumerateDirectoryResultQuit // Stop directory enumerations at any level 690 }; 691 692 typedef EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton, 693 FileType file_type, 694 const FileSpec &spec 695); 696 697 static EnumerateDirectoryResult 698 EnumerateDirectory (const char *dir_path, 699 bool find_directories, 700 bool find_files, 701 bool find_other, 702 EnumerateDirectoryCallbackType callback, 703 void *callback_baton); 704 705protected: 706 //------------------------------------------------------------------ 707 // Member variables 708 //------------------------------------------------------------------ 709 ConstString m_directory; ///< The uniqued directory path 710 ConstString m_filename; ///< The uniqued filename path 711 mutable bool m_is_resolved; ///< True if this path has been resolved. 712}; 713 714//---------------------------------------------------------------------- 715/// Dump a FileSpec object to a stream 716//---------------------------------------------------------------------- 717Stream& operator << (Stream& s, const FileSpec& f); 718 719} // namespace lldb_private 720 721#endif // #if defined(__cplusplus) 722#endif // liblldb_FileSpec_h_ 723