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 19 namespace 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 //---------------------------------------------------------------------- 39 class FileSpec 40 { 41 public: 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 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 bool IsDirectory()424 IsDirectory () const 425 { 426 return GetFileType() == FileSpec::eFileTypeDirectory; 427 } 428 429 bool IsPipe()430 IsPipe () const 431 { 432 return GetFileType() == FileSpec::eFileTypePipe; 433 } 434 435 bool IsRegularFile()436 IsRegularFile () const 437 { 438 return GetFileType() == FileSpec::eFileTypeRegular; 439 } 440 441 bool IsSocket()442 IsSocket () const 443 { 444 return GetFileType() == FileSpec::eFileTypeSocket; 445 } 446 447 bool IsSymbolicLink()448 IsSymbolicLink () const 449 { 450 return GetFileType() == FileSpec::eFileTypeSymbolicLink; 451 } 452 453 //------------------------------------------------------------------ 454 /// Get the memory cost of this object. 455 /// 456 /// Return the size in bytes that this object takes in memory. This 457 /// returns the size in bytes of this object, not any shared string 458 /// values it may refer to. 459 /// 460 /// @return 461 /// The number of bytes that this object occupies in memory. 462 /// 463 /// @see ConstString::StaticMemorySize () 464 //------------------------------------------------------------------ 465 size_t 466 MemorySize () const; 467 468 //------------------------------------------------------------------ 469 /// Memory map part of, or the entire contents of, a file. 470 /// 471 /// Returns a shared pointer to a data buffer that contains all or 472 /// part of the contents of a file. The data is memory mapped and 473 /// will lazily page in data from the file as memory is accessed. 474 /// The data that is mappped will start \a offset bytes into the 475 /// file, and \a length bytes will be mapped. If \a length is 476 /// greater than the number of bytes available in the file starting 477 /// at \a offset, the number of bytes will be appropriately 478 /// truncated. The final number of bytes that get mapped can be 479 /// verified using the DataBuffer::GetByteSize() function on the return 480 /// shared data pointer object contents. 481 /// 482 /// @param[in] offset 483 /// The offset in bytes from the beginning of the file where 484 /// memory mapping should begin. 485 /// 486 /// @param[in] length 487 /// The size in bytes that should be mapped starting \a offset 488 /// bytes into the file. If \a length is \c SIZE_MAX, map 489 /// as many bytes as possible. 490 /// 491 /// @return 492 /// A shared pointer to the memeory mapped data. This shared 493 /// pointer can contain a NULL DataBuffer pointer, so the contained 494 /// pointer must be checked prior to using it. 495 //------------------------------------------------------------------ 496 lldb::DataBufferSP 497 MemoryMapFileContents (off_t offset = 0, size_t length = SIZE_MAX) const; 498 499 //------------------------------------------------------------------ 500 /// Read part of, or the entire contents of, a file into a heap based data buffer. 501 /// 502 /// Returns a shared pointer to a data buffer that contains all or 503 /// part of the contents of a file. The data copies into a heap based 504 /// buffer that lives in the DataBuffer shared pointer object returned. 505 /// The data that is cached will start \a offset bytes into the 506 /// file, and \a length bytes will be mapped. If \a length is 507 /// greater than the number of bytes available in the file starting 508 /// at \a offset, the number of bytes will be appropriately 509 /// truncated. The final number of bytes that get mapped can be 510 /// verified using the DataBuffer::GetByteSize() function. 511 /// 512 /// @param[in] offset 513 /// The offset in bytes from the beginning of the file where 514 /// memory mapping should begin. 515 /// 516 /// @param[in] length 517 /// The size in bytes that should be mapped starting \a offset 518 /// bytes into the file. If \a length is \c SIZE_MAX, map 519 /// as many bytes as possible. 520 /// 521 /// @return 522 /// A shared pointer to the memeory mapped data. This shared 523 /// pointer can contain a NULL DataBuffer pointer, so the contained 524 /// pointer must be checked prior to using it. 525 //------------------------------------------------------------------ 526 lldb::DataBufferSP 527 ReadFileContents (off_t offset = 0, size_t length = SIZE_MAX, Error *error_ptr = NULL) const; 528 529 size_t 530 ReadFileContents (off_t file_offset, void *dst, size_t dst_len, Error *error_ptr) const; 531 532 533 //------------------------------------------------------------------ 534 /// Read the entire contents of a file as data that can be used 535 /// as a C string. 536 /// 537 /// Read the entire contents of a file and ensure that the data 538 /// is NULL terminated so it can be used as a C string. 539 /// 540 /// @return 541 /// A shared pointer to the data. This shared pointer can 542 /// contain a NULL DataBuffer pointer, so the contained pointer 543 /// must be checked prior to using it. 544 //------------------------------------------------------------------ 545 lldb::DataBufferSP 546 ReadFileContentsAsCString(Error *error_ptr = NULL); 547 //------------------------------------------------------------------ 548 /// Change the file specificed with a new path. 549 /// 550 /// Update the contents of this object with a new path. The path will 551 /// be split up into a directory and filename and stored as uniqued 552 /// string values for quick comparison and efficient memory usage. 553 /// 554 /// @param[in] path 555 /// A full, partial, or relative path to a file. 556 /// 557 /// @param[in] resolve_path 558 /// If \b true, then we will try to resolve links the path using 559 /// the static FileSpec::Resolve. 560 //------------------------------------------------------------------ 561 void 562 SetFile (const char *path, bool resolve_path); 563 564 bool IsResolved()565 IsResolved () const 566 { 567 return m_is_resolved; 568 } 569 570 //------------------------------------------------------------------ 571 /// Set if the file path has been resolved or not. 572 /// 573 /// If you know a file path is already resolved and avoided passing 574 /// a \b true parameter for any functions that take a "bool 575 /// resolve_path" parameter, you can set the value manually using 576 /// this call to make sure we don't try and resolve it later, or try 577 /// and resolve a path that has already been resolved. 578 /// 579 /// @param[in] is_resolved 580 /// A boolean value that will replace the current value that 581 /// indicates if the paths in this object have been resolved. 582 //------------------------------------------------------------------ 583 void SetIsResolved(bool is_resolved)584 SetIsResolved (bool is_resolved) 585 { 586 m_is_resolved = is_resolved; 587 } 588 //------------------------------------------------------------------ 589 /// Read the file into an array of strings, one per line. 590 /// 591 /// Opens and reads the file in this object into an array of strings, 592 /// one string per line of the file. Returns a boolean indicating 593 /// success or failure. 594 /// 595 /// @param[out] lines 596 /// The string array into which to read the file. 597 /// 598 /// @result 599 /// Returns the number of lines that were read from the file. 600 //------------------------------------------------------------------ 601 size_t 602 ReadFileLines (STLStringArray &lines); 603 604 //------------------------------------------------------------------ 605 /// Resolves user name and links in \a src_path, and writes the output 606 /// to \a dst_path. Note if the path pointed to by \a src_path does not 607 /// exist, the contents of \a src_path will be copied to \a dst_path 608 /// unchanged. 609 /// 610 /// @param[in] src_path 611 /// Input path to be resolved. 612 /// 613 /// @param[in] dst_path 614 /// Buffer to store the resolved path. 615 /// 616 /// @param[in] dst_len 617 /// Size of the buffer pointed to by dst_path. 618 /// 619 /// @result 620 /// The number of characters required to write the resolved path. If the 621 /// resolved path doesn't fit in dst_len, dst_len-1 characters will 622 /// be written to \a dst_path, but the actual required length will still be returned. 623 //------------------------------------------------------------------ 624 static size_t 625 Resolve (const char *src_path, char *dst_path, size_t dst_len); 626 627 //------------------------------------------------------------------ 628 /// Resolves the user name at the beginning of \a src_path, and writes the output 629 /// to \a dst_path. Note, \a src_path can contain other path components after the 630 /// user name, they will be copied over, and if the path doesn't start with "~" it 631 /// will also be copied over to \a dst_path. 632 /// 633 /// @param[in] src_path 634 /// Input path to be resolved. 635 /// 636 /// @param[in] dst_path 637 /// Buffer to store the resolved path. 638 /// 639 /// @param[in] dst_len 640 /// Size of the buffer pointed to by dst_path. 641 /// 642 /// @result 643 /// The number of characters required to write the resolved path, or 0 if 644 /// the user name could not be found. If the 645 /// resolved path doesn't fit in dst_len, dst_len-1 characters will 646 /// be written to \a dst_path, but the actual required length will still be returned. 647 //------------------------------------------------------------------ 648 static size_t 649 ResolveUsername (const char *src_path, char *dst_path, size_t dst_len); 650 651 static size_t 652 ResolvePartialUsername (const char *partial_name, StringList &matches); 653 654 enum EnumerateDirectoryResult 655 { 656 eEnumerateDirectoryResultNext, // Enumerate next entry in the current directory 657 eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a directory or symlink, or next if not 658 eEnumerateDirectoryResultExit, // Exit from the current directory at the current level. 659 eEnumerateDirectoryResultQuit // Stop directory enumerations at any level 660 }; 661 662 typedef EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton, 663 FileType file_type, 664 const FileSpec &spec 665 ); 666 667 static EnumerateDirectoryResult 668 EnumerateDirectory (const char *dir_path, 669 bool find_directories, 670 bool find_files, 671 bool find_other, 672 EnumerateDirectoryCallbackType callback, 673 void *callback_baton); 674 675 protected: 676 //------------------------------------------------------------------ 677 // Member variables 678 //------------------------------------------------------------------ 679 ConstString m_directory; ///< The uniqued directory path 680 ConstString m_filename; ///< The uniqued filename path 681 mutable bool m_is_resolved; ///< True if this path has been resolved. 682 }; 683 684 //---------------------------------------------------------------------- 685 /// Dump a FileSpec object to a stream 686 //---------------------------------------------------------------------- 687 Stream& operator << (Stream& s, const FileSpec& f); 688 689 } // namespace lldb_private 690 691 #endif // #if defined(__cplusplus) 692 #endif // liblldb_FileSpec_h_ 693