1 //===-- FileSpecList.cpp ----------------------------------------*- 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 #include "lldb/Core/FileSpecList.h" 11 12 #include "lldb/Utility/ConstString.h" // for ConstString 13 #include "lldb/Utility/Stream.h" 14 15 #include <utility> // for find 16 17 #include <stdint.h> // for UINT32_MAX 18 19 using namespace lldb_private; 20 using namespace std; 21 22 FileSpecList::FileSpecList() : m_files() {} 23 24 FileSpecList::FileSpecList(const FileSpecList &rhs) = default; 25 26 FileSpecList::~FileSpecList() = default; 27 28 //------------------------------------------------------------------ 29 // Assignment operator 30 //------------------------------------------------------------------ 31 const FileSpecList &FileSpecList::operator=(const FileSpecList &rhs) { 32 if (this != &rhs) 33 m_files = rhs.m_files; 34 return *this; 35 } 36 37 //------------------------------------------------------------------ 38 // Append the "file_spec" to the end of the file spec list. 39 //------------------------------------------------------------------ 40 void FileSpecList::Append(const FileSpec &file_spec) { 41 m_files.push_back(file_spec); 42 } 43 44 //------------------------------------------------------------------ 45 // Only append the "file_spec" if this list doesn't already contain 46 // it. 47 // 48 // Returns true if "file_spec" was added, false if this list already 49 // contained a copy of "file_spec". 50 //------------------------------------------------------------------ 51 bool FileSpecList::AppendIfUnique(const FileSpec &file_spec) { 52 collection::iterator pos, end = m_files.end(); 53 if (find(m_files.begin(), end, file_spec) == end) { 54 m_files.push_back(file_spec); 55 return true; 56 } 57 return false; 58 } 59 60 //------------------------------------------------------------------ 61 // Clears the file list. 62 //------------------------------------------------------------------ 63 void FileSpecList::Clear() { m_files.clear(); } 64 65 //------------------------------------------------------------------ 66 // Dumps the file list to the supplied stream pointer "s". 67 //------------------------------------------------------------------ 68 void FileSpecList::Dump(Stream *s, const char *separator_cstr) const { 69 collection::const_iterator pos, end = m_files.end(); 70 for (pos = m_files.begin(); pos != end; ++pos) { 71 pos->Dump(s); 72 if (separator_cstr && ((pos + 1) != end)) 73 s->PutCString(separator_cstr); 74 } 75 } 76 77 //------------------------------------------------------------------ 78 // Find the index of the file in the file spec list that matches 79 // "file_spec" starting "start_idx" entries into the file spec list. 80 // 81 // Returns the valid index of the file that matches "file_spec" if 82 // it is found, else std::numeric_limits<uint32_t>::max() is returned. 83 //------------------------------------------------------------------ 84 size_t FileSpecList::FindFileIndex(size_t start_idx, const FileSpec &file_spec, 85 bool full, bool remove_dots) const { 86 const size_t num_files = m_files.size(); 87 88 // When looking for files, we will compare only the filename if the 89 // FILE_SPEC argument is empty 90 bool compare_filename_only = file_spec.GetDirectory().IsEmpty(); 91 92 for (size_t idx = start_idx; idx < num_files; ++idx) { 93 if (compare_filename_only) { 94 if (ConstString::Equals( 95 m_files[idx].GetFilename(), file_spec.GetFilename(), 96 file_spec.IsCaseSensitive() || m_files[idx].IsCaseSensitive())) 97 return idx; 98 } else { 99 if (FileSpec::Equal(m_files[idx], file_spec, full, remove_dots)) 100 return idx; 101 } 102 } 103 104 // We didn't find the file, return an invalid index 105 return UINT32_MAX; 106 } 107 108 //------------------------------------------------------------------ 109 // Returns the FileSpec object at index "idx". If "idx" is out of 110 // range, then an empty FileSpec object will be returned. 111 //------------------------------------------------------------------ 112 const FileSpec &FileSpecList::GetFileSpecAtIndex(size_t idx) const { 113 if (idx < m_files.size()) 114 return m_files[idx]; 115 static FileSpec g_empty_file_spec; 116 return g_empty_file_spec; 117 } 118 119 const FileSpec *FileSpecList::GetFileSpecPointerAtIndex(size_t idx) const { 120 if (idx < m_files.size()) 121 return &m_files[idx]; 122 return nullptr; 123 } 124 125 //------------------------------------------------------------------ 126 // Return the size in bytes that this object takes in memory. This 127 // returns the size in bytes of this object's member variables and 128 // any FileSpec objects its member variables contain, the result 129 // doesn't not include the string values for the directories any 130 // filenames as those are in shared string pools. 131 //------------------------------------------------------------------ 132 size_t FileSpecList::MemorySize() const { 133 size_t mem_size = sizeof(FileSpecList); 134 collection::const_iterator pos, end = m_files.end(); 135 for (pos = m_files.begin(); pos != end; ++pos) { 136 mem_size += pos->MemorySize(); 137 } 138 139 return mem_size; 140 } 141 142 //------------------------------------------------------------------ 143 // Return the number of files in the file spec list. 144 //------------------------------------------------------------------ 145 size_t FileSpecList::GetSize() const { return m_files.size(); } 146 147 size_t FileSpecList::GetFilesMatchingPartialPath(const char *path, 148 bool dir_okay, 149 FileSpecList &matches) { 150 #if 0 // FIXME: Just sketching... 151 matches.Clear(); 152 using namespace llvm::sys::fs; 153 file_status stats; 154 if (status(path, stats, false)) 155 return 0; 156 if (exists(stats)) { 157 if (is_symlink_file(stats)) { 158 // Shouldn't there be a method that realpath's a file? 159 } 160 if (is_regular_file(stats) || (is_directory(stats) && dir_okay)) { 161 matches.Append(FileSpec(path)); 162 return 1; 163 } else if (is_directory(stats)) { 164 // Fill the match list with all the files in the directory: 165 } else { 166 return 0; 167 } 168 } else { 169 ConstString dir_name = path_spec.GetDirectory(); 170 ConstString file_name = GetFilename(); 171 if (dir_name == nullptr) 172 { 173 // Match files in the CWD. 174 } 175 else 176 { 177 // Match files in the given directory: 178 } 179 } 180 #endif 181 return 0; 182 } 183