FileSpec.h revision fc04d2463ad654c28f9ee2ee836174cc86b7f8b8
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 /// The destructor is virtual in case this class is subclassed. 100 //------------------------------------------------------------------ 101 virtual 102 ~FileSpec (); 103 104 //------------------------------------------------------------------ 105 /// Assignment operator. 106 /// 107 /// Makes a copy of the uniqued directory and filename strings from 108 /// \a rhs. 109 /// 110 /// @param[in] rhs 111 /// A const FileSpec object reference to assign to this object. 112 /// 113 /// @return 114 /// A const reference to this object. 115 //------------------------------------------------------------------ 116 const FileSpec& 117 operator= (const FileSpec& rhs); 118 119 //------------------------------------------------------------------ 120 /// Equal to operator 121 /// 122 /// Tests if this object is equal to \a rhs. 123 /// 124 /// @param[in] rhs 125 /// A const FileSpec object reference to compare this object 126 /// to. 127 /// 128 /// @return 129 /// \b true if this object is equal to \a rhs, \b false 130 /// otherwise. 131 //------------------------------------------------------------------ 132 bool 133 operator== (const FileSpec& rhs) const; 134 135 //------------------------------------------------------------------ 136 /// Not equal to operator 137 /// 138 /// Tests if this object is not equal to \a rhs. 139 /// 140 /// @param[in] rhs 141 /// A const FileSpec object reference to compare this object 142 /// to. 143 /// 144 /// @return 145 /// \b true if this object is equal to \a rhs, \b false 146 /// otherwise. 147 //------------------------------------------------------------------ 148 bool 149 operator!= (const FileSpec& rhs) const; 150 151 //------------------------------------------------------------------ 152 /// Less than to operator 153 /// 154 /// Tests if this object is less than \a rhs. 155 /// 156 /// @param[in] rhs 157 /// A const FileSpec object reference to compare this object 158 /// to. 159 /// 160 /// @return 161 /// \b true if this object is less than \a rhs, \b false 162 /// otherwise. 163 //------------------------------------------------------------------ 164 bool 165 operator< (const FileSpec& rhs) const; 166 167 //------------------------------------------------------------------ 168 /// Convert to pointer operator. 169 /// 170 /// This allows code to check a FileSpec object to see if it 171 /// contains anything valid using code such as: 172 /// 173 /// @code 174 /// FileSpec file_spec(...); 175 /// if (file_spec) 176 /// { ... 177 /// @endcode 178 /// 179 /// @return 180 /// A pointer to this object if either the directory or filename 181 /// is valid, NULL otherwise. 182 //------------------------------------------------------------------ 183 operator bool() const; 184 185 //------------------------------------------------------------------ 186 /// Logical NOT operator. 187 /// 188 /// This allows code to check a FileSpec object to see if it is 189 /// invalid using code such as: 190 /// 191 /// @code 192 /// FileSpec file_spec(...); 193 /// if (!file_spec) 194 /// { ... 195 /// @endcode 196 /// 197 /// @return 198 /// Returns \b true if the object has an empty directory and 199 /// filename, \b false otherwise. 200 //------------------------------------------------------------------ 201 bool 202 operator! () const; 203 204 //------------------------------------------------------------------ 205 /// Clears the object state. 206 /// 207 /// Clear this object by releasing both the directory and filename 208 /// string values and reverting them to empty strings. 209 //------------------------------------------------------------------ 210 void 211 Clear (); 212 213 //------------------------------------------------------------------ 214 /// Compare two FileSpec objects. 215 /// 216 /// If \a full is true, then both the directory and the filename 217 /// must match. If \a full is false, then the directory names for 218 /// \a lhs and \a rhs are only compared if they are both not empty. 219 /// This allows a FileSpec object to only contain a filename 220 /// and it can match FileSpec objects that have matching 221 /// filenames with different paths. 222 /// 223 /// @param[in] lhs 224 /// A const reference to the Left Hand Side object to compare. 225 /// 226 /// @param[in] rhs 227 /// A const reference to the Right Hand Side object to compare. 228 /// 229 /// @param[in] full 230 /// If true, then both the directory and filenames will have to 231 /// match for a compare to return zero (equal to). If false 232 /// and either directory from \a lhs or \a rhs is empty, then 233 /// only the filename will be compared, else a full comparison 234 /// is done. 235 /// 236 /// @return 237 /// @li -1 if \a lhs is less than \a rhs 238 /// @li 0 if \a lhs is equal to \a rhs 239 /// @li 1 if \a lhs is greater than \a rhs 240 //------------------------------------------------------------------ 241 static int 242 Compare (const FileSpec& lhs, const FileSpec& rhs, bool full); 243 244 static bool 245 Equal (const FileSpec& a, const FileSpec& b, bool full); 246 247 //------------------------------------------------------------------ 248 /// Dump this object to a Stream. 249 /// 250 /// Dump the object to the supplied stream \a s. If the object 251 /// contains a valid directory name, it will be displayed followed 252 /// by a directory delimiter, and the filename. 253 /// 254 /// @param[in] s 255 /// The stream to which to dump the object descripton. 256 //------------------------------------------------------------------ 257 void 258 Dump (Stream *s) const; 259 260 //------------------------------------------------------------------ 261 /// Existence test. 262 /// 263 /// @return 264 /// \b true if the file exists on disk, \b false otherwise. 265 //------------------------------------------------------------------ 266 bool 267 Exists () const; 268 269 270 //------------------------------------------------------------------ 271 /// Expanded existence test. 272 /// 273 /// Call into the Host to see if it can help find the file (e.g. by 274 /// searching paths set in the environment, etc.). 275 /// 276 /// If found, sets the value of m_directory to the directory where 277 /// the file was found. 278 /// 279 /// @return 280 /// \b true if was able to find the file using expanded search 281 /// methods, \b false otherwise. 282 //------------------------------------------------------------------ 283 bool 284 ResolveExecutableLocation (); 285 286 //------------------------------------------------------------------ 287 /// Canonicalize this file path (basically running the static 288 /// FileSpec::Resolve method on it). Useful if you asked us not to 289 /// resolve the file path when you set the file. 290 //------------------------------------------------------------------ 291 bool 292 ResolvePath (); 293 294 uint64_t 295 GetByteSize() const; 296 297 //------------------------------------------------------------------ 298 /// Directory string get accessor. 299 /// 300 /// @return 301 /// A reference to the directory string object. 302 //------------------------------------------------------------------ 303 ConstString & 304 GetDirectory (); 305 306 //------------------------------------------------------------------ 307 /// Directory string const get accessor. 308 /// 309 /// @return 310 /// A const reference to the directory string object. 311 //------------------------------------------------------------------ 312 const ConstString & 313 GetDirectory () const; 314 315 //------------------------------------------------------------------ 316 /// Filename string get accessor. 317 /// 318 /// @return 319 /// A reference to the filename string object. 320 //------------------------------------------------------------------ 321 ConstString & 322 GetFilename (); 323 324 //------------------------------------------------------------------ 325 /// Filename string const get accessor. 326 /// 327 /// @return 328 /// A const reference to the filename string object. 329 //------------------------------------------------------------------ 330 const ConstString & 331 GetFilename () const; 332 333 //------------------------------------------------------------------ 334 /// Returns true if the filespec represents an implementation source 335 /// file (files with a ".c", ".cpp", ".m", ".mm" (many more) 336 /// extension). 337 /// 338 /// @return 339 /// \b true if the filespec represents an implementation source 340 /// file, \b false otherwise. 341 //------------------------------------------------------------------ 342 bool 343 IsSourceImplementationFile () const; 344 345 TimeValue 346 GetModificationTime () const; 347 348 //------------------------------------------------------------------ 349 /// Extract the full path to the file. 350 /// 351 /// Extract the directory and path into a fixed buffer. This is 352 /// needed as the directory and path are stored in separate string 353 /// values. 354 /// 355 /// @param[out] path 356 /// The buffer in which to place the extracted full path. 357 /// 358 /// @param[in] max_path_length 359 /// The maximum length of \a path. 360 /// 361 /// @return 362 /// Returns the number of characters that would be needed to 363 /// properly copy the full path into \a path. If the returned 364 /// number is less than \a max_path_length, then the path is 365 /// properly copied and terminated. If the return value is 366 /// >= \a max_path_length, then the path was truncated (but is 367 /// still NULL terminated). 368 //------------------------------------------------------------------ 369 size_t 370 GetPath (char *path, size_t max_path_length) const; 371 372 //------------------------------------------------------------------ 373 /// Extract the extension of the file. 374 /// 375 /// Returns a ConstString that represents the extension of the filename 376 /// for this FileSpec object. If this object does not represent a file, 377 /// or the filename has no extension, ConstString(NULL) is returned. 378 /// The dot ('.') character is not returned as part of the extension 379 /// 380 /// @return 381 /// Returns the extension of the file as a ConstString object. 382 //------------------------------------------------------------------ 383 ConstString 384 GetFileNameExtension () const; 385 386 //------------------------------------------------------------------ 387 /// Return the filename without the extension part 388 /// 389 /// Returns a ConstString that represents the filename of this object 390 /// without the extension part (e.g. for a file named "foo.bar", "foo" 391 /// is returned) 392 /// 393 /// @return 394 /// Returns the filename without extension 395 /// as a ConstString object. 396 //------------------------------------------------------------------ 397 ConstString 398 GetFileNameStrippingExtension () const; 399 400 FileType 401 GetFileType () const; 402 403 //------------------------------------------------------------------ 404 /// Get the memory cost of this object. 405 /// 406 /// Return the size in bytes that this object takes in memory. This 407 /// returns the size in bytes of this object, not any shared string 408 /// values it may refer to. 409 /// 410 /// @return 411 /// The number of bytes that this object occupies in memory. 412 /// 413 /// @see ConstString::StaticMemorySize () 414 //------------------------------------------------------------------ 415 size_t 416 MemorySize () const; 417 418 //------------------------------------------------------------------ 419 /// Memory map part of, or the entire contents of, a file. 420 /// 421 /// Returns a shared pointer to a data buffer that contains all or 422 /// part of the contents of a file. The data is memory mapped and 423 /// will lazily page in data from the file as memory is accessed. 424 /// The data that is mappped will start \a offset bytes into the 425 /// file, and \a length bytes will be mapped. If \a length is 426 /// greater than the number of bytes available in the file starting 427 /// at \a offset, the number of bytes will be appropriately 428 /// truncated. The final number of bytes that get mapped can be 429 /// verified using the DataBuffer::GetByteSize() function on the return 430 /// shared data pointer object contents. 431 /// 432 /// @param[in] offset 433 /// The offset in bytes from the beginning of the file where 434 /// memory mapping should begin. 435 /// 436 /// @param[in] length 437 /// The size in bytes that should be mapped starting \a offset 438 /// bytes into the file. If \a length is \c SIZE_MAX, map 439 /// as many bytes as possible. 440 /// 441 /// @return 442 /// A shared pointer to the memeory mapped data. This shared 443 /// pointer can contain a NULL DataBuffer pointer, so the contained 444 /// pointer must be checked prior to using it. 445 //------------------------------------------------------------------ 446 lldb::DataBufferSP 447 MemoryMapFileContents (off_t offset = 0, size_t length = SIZE_MAX) const; 448 449 //------------------------------------------------------------------ 450 /// Read part of, or the entire contents of, a file into a heap based data buffer. 451 /// 452 /// Returns a shared pointer to a data buffer that contains all or 453 /// part of the contents of a file. The data copies into a heap based 454 /// buffer that lives in the DataBuffer shared pointer object returned. 455 /// The data that is cached will start \a offset bytes into the 456 /// file, and \a length bytes will be mapped. If \a length is 457 /// greater than the number of bytes available in the file starting 458 /// at \a offset, the number of bytes will be appropriately 459 /// truncated. The final number of bytes that get mapped can be 460 /// verified using the DataBuffer::GetByteSize() function. 461 /// 462 /// @param[in] offset 463 /// The offset in bytes from the beginning of the file where 464 /// memory mapping should begin. 465 /// 466 /// @param[in] length 467 /// The size in bytes that should be mapped starting \a offset 468 /// bytes into the file. If \a length is \c SIZE_MAX, map 469 /// as many bytes as possible. 470 /// 471 /// @return 472 /// A shared pointer to the memeory mapped data. This shared 473 /// pointer can contain a NULL DataBuffer pointer, so the contained 474 /// pointer must be checked prior to using it. 475 //------------------------------------------------------------------ 476 lldb::DataBufferSP 477 ReadFileContents (off_t offset = 0, size_t length = SIZE_MAX, Error *error_ptr = NULL) const; 478 479 size_t 480 ReadFileContents (off_t file_offset, void *dst, size_t dst_len, Error *error_ptr) const; 481 482 483 //------------------------------------------------------------------ 484 /// Read the entire contents of a file as data that can be used 485 /// as a C string. 486 /// 487 /// Read the entire contents of a file and ensure that the data 488 /// is NULL terminated so it can be used as a C string. 489 /// 490 /// @return 491 /// A shared pointer to the data. This shared pointer can 492 /// contain a NULL DataBuffer pointer, so the contained pointer 493 /// must be checked prior to using it. 494 //------------------------------------------------------------------ 495 lldb::DataBufferSP 496 ReadFileContentsAsCString(Error *error_ptr = NULL); 497 //------------------------------------------------------------------ 498 /// Change the file specificed with a new path. 499 /// 500 /// Update the contents of this object with a new path. The path will 501 /// be split up into a directory and filename and stored as uniqued 502 /// string values for quick comparison and efficient memory usage. 503 /// 504 /// @param[in] path 505 /// A full, partial, or relative path to a file. 506 /// 507 /// @param[in] resolve_path 508 /// If \b true, then we will try to resolve links the path using 509 /// the static FileSpec::Resolve. 510 //------------------------------------------------------------------ 511 void 512 SetFile (const char *path, bool resolve_path); 513 514 bool 515 IsResolved () const 516 { 517 return m_is_resolved; 518 } 519 520 //------------------------------------------------------------------ 521 /// Set if the file path has been resolved or not. 522 /// 523 /// If you know a file path is already resolved and avoided passing 524 /// a \b true parameter for any functions that take a "bool 525 /// resolve_path" parameter, you can set the value manually using 526 /// this call to make sure we don't try and resolve it later, or try 527 /// and resolve a path that has already been resolved. 528 /// 529 /// @param[in] is_resolved 530 /// A boolean value that will replace the current value that 531 /// indicates if the paths in this object have been resolved. 532 //------------------------------------------------------------------ 533 void 534 SetIsResolved (bool is_resolved) 535 { 536 m_is_resolved = is_resolved; 537 } 538 //------------------------------------------------------------------ 539 /// Read the file into an array of strings, one per line. 540 /// 541 /// Opens and reads the file in this object into an array of strings, 542 /// one string per line of the file. Returns a boolean indicating 543 /// success or failure. 544 /// 545 /// @param[out] lines 546 /// The string array into which to read the file. 547 /// 548 /// @result 549 /// Returns the number of lines that were read from the file. 550 //------------------------------------------------------------------ 551 size_t 552 ReadFileLines (STLStringArray &lines); 553 554 //------------------------------------------------------------------ 555 /// Resolves user name and links in \a src_path, and writes the output 556 /// to \a dst_path. Note if the path pointed to by \a src_path does not 557 /// exist, the contents of \a src_path will be copied to \a dst_path 558 /// unchanged. 559 /// 560 /// @param[in] src_path 561 /// Input path to be resolved. 562 /// 563 /// @param[in] dst_path 564 /// Buffer to store the resolved path. 565 /// 566 /// @param[in] dst_len 567 /// Size of the buffer pointed to by dst_path. 568 /// 569 /// @result 570 /// The number of characters required to write the resolved path. If the 571 /// resolved path doesn't fit in dst_len, dst_len-1 characters will 572 /// be written to \a dst_path, but the actual required length will still be returned. 573 //------------------------------------------------------------------ 574 static size_t 575 Resolve (const char *src_path, char *dst_path, size_t dst_len); 576 577 //------------------------------------------------------------------ 578 /// Resolves the user name at the beginning of \a src_path, and writes the output 579 /// to \a dst_path. Note, \a src_path can contain other path components after the 580 /// user name, they will be copied over, and if the path doesn't start with "~" it 581 /// will also be copied over to \a dst_path. 582 /// 583 /// @param[in] src_path 584 /// Input path to be resolved. 585 /// 586 /// @param[in] dst_path 587 /// Buffer to store the resolved path. 588 /// 589 /// @param[in] dst_len 590 /// Size of the buffer pointed to by dst_path. 591 /// 592 /// @result 593 /// The number of characters required to write the resolved path, or 0 if 594 /// the user name could not be found. If the 595 /// resolved path doesn't fit in dst_len, dst_len-1 characters will 596 /// be written to \a dst_path, but the actual required length will still be returned. 597 //------------------------------------------------------------------ 598 static size_t 599 ResolveUsername (const char *src_path, char *dst_path, size_t dst_len); 600 601 static size_t 602 ResolvePartialUsername (const char *partial_name, StringList &matches); 603 604 enum EnumerateDirectoryResult 605 { 606 eEnumerateDirectoryResultNext, // Enumerate next entry in the current directory 607 eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a directory or symlink, or next if not 608 eEnumerateDirectoryResultExit, // Exit from the current directory at the current level. 609 eEnumerateDirectoryResultQuit // Stop directory enumerations at any level 610 }; 611 612 typedef EnumerateDirectoryResult (*EnumerateDirectoryCallbackType) (void *baton, 613 FileType file_type, 614 const FileSpec &spec 615); 616 617 static EnumerateDirectoryResult 618 EnumerateDirectory (const char *dir_path, 619 bool find_directories, 620 bool find_files, 621 bool find_other, 622 EnumerateDirectoryCallbackType callback, 623 void *callback_baton); 624 625protected: 626 //------------------------------------------------------------------ 627 // Member variables 628 //------------------------------------------------------------------ 629 ConstString m_directory; ///< The uniqued directory path 630 ConstString m_filename; ///< The uniqued filename path 631 mutable bool m_is_resolved; ///< True if this path has been resolved. 632}; 633 634//---------------------------------------------------------------------- 635/// Dump a FileSpec object to a stream 636//---------------------------------------------------------------------- 637Stream& operator << (Stream& s, const FileSpec& f); 638 639} // namespace lldb_private 640 641#endif // #if defined(__cplusplus) 642#endif // liblldb_FileSpec_h_ 643