| 227 | virtual ~cmDirectoryListGenerator() = default; |
| 228 | |
| 229 | std::string GetNextCandidate(std::string const& parent) |
| 230 | { |
| 231 | // Construct a list of matches if not yet |
| 232 | if (this->Matches.empty()) { |
| 233 | cmsys::Directory directoryLister; |
| 234 | // ALERT `Directory::Load()` keeps only names |
| 235 | // internally and LOST entry type from `dirent`. |
| 236 | // So, `Directory::FileIsDirectory` gonna use |
| 237 | // `SystemTools::FileIsDirectory()` and waste a syscall. |
| 238 | // TODO Need to enhance the `Directory` class. |
| 239 | directoryLister.Load(parent); |
| 240 | |
| 241 | // ATTENTION Is it guaranteed that first two entries are |
| 242 | // `.` and `..`? |
| 243 | // TODO If so, just start with index 2 and drop the |
| 244 | // `isDirentryToIgnore(i)` condition to check. |
| 245 | for (auto i = 0ul; i < directoryLister.GetNumberOfFiles(); ++i) { |
| 246 | char const* const fname = directoryLister.GetFile(i); |
| 247 | // Skip entries to ignore or that aren't directories. |
| 248 | if (isDirentryToIgnore(fname)) { |
| 249 | continue; |
| 250 | } |
| 251 | |
| 252 | if (!this->Names) { |
| 253 | if (directoryLister.FileIsDirectory(i)) { |
| 254 | this->Matches.emplace_back(fname); |
| 255 | } |
| 256 | } else { |
| 257 | for (auto const& n : *this->Names) { |
| 258 | // NOTE Customization point for |
| 259 | // `cmMacProjectDirectoryListGenerator` |
| 260 | auto const name = this->TransformNameBeforeCmp(n); |
| 261 | // Skip entries that don't match. |
| 262 | auto const equal = |
| 263 | ((this->ExactMatch |
| 264 | ? cmsysString_strcasecmp(fname, name.c_str()) |
| 265 | : cmsysString_strncasecmp(fname, name.c_str(), |
| 266 | name.length())) == 0); |
| 267 | if (equal) { |
| 268 | if (directoryLister.FileIsDirectory(i)) { |
| 269 | this->Matches.emplace_back(fname); |
| 270 | } |
| 271 | break; |
| 272 | } |
| 273 | } |
| 274 | } |
| 275 | } |
| 276 | // NOTE Customization point for `cmProjectDirectoryListGenerator` |
| 277 | this->OnMatchesLoaded(); |
| 278 | |
| 279 | this->Current = this->Matches.cbegin(); |
| 280 | } |
| 281 | |
| 282 | if (this->Current != this->Matches.cend()) { |
| 283 | auto candidate = cmStrCat(parent, *this->Current++, '/'); |
| 284 | return candidate; |
| 285 | } |
| 286 |
no test coverage detected