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