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