7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
144#if QT_CONFIG(regularexpression)
145#include <QtCore/qregularexpression.h>
148#include <QtCore/private/qfilesystemiterator_p.h>
149#include <QtCore/private/qfilesystementry_p.h>
150#include <QtCore/private/qfilesystemmetadata_p.h>
151#include <QtCore/private/qfilesystemengine_p.h>
152#include <QtCore/private/qfileinfo_p.h>
153#include <QtCore/private/qduplicatetracker_p.h>
160using namespace Qt::StringLiterals;
183#if QT_CONFIG(regularexpression)
196#ifndef QT_NO_FILESYSTEMITERATOR
207 if (nameFilters.contains(
"*"_L1))
210#if QT_CONFIG(regularexpression)
211 nameRegExps.reserve(nameFilters.size());
213 const bool isCase = iteratorFlags.testAnyFlags(QDirListing::IteratorFlag::CaseSensitive);
214 const auto cs = isCase ? Qt::CaseSensitive : Qt::CaseInsensitive;
215 for (
const auto &filter : nameFilters)
216 nameRegExps.emplace_back(QRegularExpression::fromWildcard(filter, cs));
219 engine = QFileSystemEngine::createLegacyEngine(initialEntryInfo.entry,
220 initialEntryInfo.metaData);
224
225
226
227
228
231#ifndef QT_NO_FILESYSTEMITERATOR
232 nativeIterators.clear();
234 fileEngineIterators.clear();
235 visitedLinks.clear();
236 pushDirectory(initialEntryInfo);
241 const QString path = [&entryInfo] {
243 if (entryInfo.isSymLink())
244 return entryInfo.canonicalFilePath();
246 return entryInfo.filePath();
250 if (iteratorFlags.testAnyFlags(QDirListing::IteratorFlag::FollowDirSymlinks)) {
252 if (visitedLinks.hasSeen(entryInfo.canonicalFilePath()))
257 engine->setFileName(path);
258 if (
auto it = engine->beginEntryList(path, iteratorFlags, nameFilters)) {
259 fileEngineIterators.emplace_back(std::move(it));
264#ifndef QT_NO_FILESYSTEMITERATOR
265 QFileSystemEntry *fentry =
nullptr;
266 if (entryInfo.fileInfoOpt)
267 fentry = &entryInfo.fileInfoOpt->d_ptr->fileEntry;
269 fentry = &entryInfo.entry;
270 nativeIterators.emplace_back(std::make_unique<QFileSystemIterator>(*fentry, iteratorFlags));
272 qWarning(
"Qt was built with -no-feature-filesystemiterator: no files/plugins will be found!");
284
285
286
287
288
289
290
291
292
293
294
295
296
304 while (!fileEngineIterators.empty()) {
306 QAbstractFileEngineIterator *it;
307 while (it = fileEngineIterators.back().get(), it->advance()) {
309 entryInfo.fileInfoOpt = it->currentFileInfo();
311 currentEntryInfo = std::move(entryInfo);
316 fileEngineIterators.pop_back();
319#ifndef QT_NO_FILESYSTEMITERATOR
321 while (!nativeIterators.empty()) {
323 QFileSystemIterator *it;
324 while (it = nativeIterators.back().get(),
325 it->advance(entryInfo.entry, entryInfo.metaData)) {
327 currentEntryInfo = std::move(entryInfo);
333 nativeIterators.pop_back();
341 return fileName ==
"."_L1 || fileName ==
".."_L1;
348 if (!iteratorFlags.testAnyFlags(F::Recursive))
352 if (!iteratorFlags.testAnyFlags(F::FollowDirSymlinks) && entryInfo.isSymLink())
356 if (isDotOrDotDot(entryInfo.fileName()))
360 const bool includeHidden = iteratorFlags.testAnyFlags(QDirListing::IteratorFlag::IncludeHidden);
372
373
374
375
376
377
382 const QString &fileName = entryInfo.fileName();
383 if (fileName.isEmpty())
387#if QT_CONFIG(regularexpression)
388 const bool skipNameFilters = iteratorFlags.testAnyFlags(F::NoNameFiltersForDirs)
389 && entryInfo.isDir();
390 if (!skipNameFilters) {
391 if (!regexMatchesName(fileName))
396 if (isDotOrDotDot(fileName))
397 return iteratorFlags.testFlags(F::IncludeDotAndDotDot);
399 if (!iteratorFlags.testAnyFlag(F::IncludeHidden) && entryInfo.isHidden())
402 const bool includeBrokenSymlinks = iteratorFlags.testAnyFlags(F::IncludeBrokenSymlinks);
406 if (iteratorFlags.testFlag(F::ResolveSymlinks)) {
411 const bool filterByTargetType = iteratorFlags.testAnyFlags(f);
416 if (iteratorFlags.testAnyFlag(F::ExcludeOther)
417 && !entryInfo.isFile() && !entryInfo.isDir() && !entryInfo.isSymLink()) {
421 if (iteratorFlags.testAnyFlags(F::ExcludeDirs) && entryInfo.isDir())
424 if (iteratorFlags.testAnyFlags(F::ExcludeFiles) && entryInfo.isFile())
433 return !fileEngineIterators.empty();
435#if !defined(QT_NO_FILESYSTEMITERATOR)
436 return !nativeIterators.empty();
443
444
445
446
447
448
449
450
451
455 d->initialEntryInfo.entry = QFileSystemEntry(path);
456 d->iteratorFlags = flags;
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483QDirListing::QDirListing(
const QString &path,
const QStringList &nameFilters, IteratorFlags flags)
486 d->initialEntryInfo.entry = QFileSystemEntry(path);
487 d->nameFilters = nameFilters;
488 d->iteratorFlags = flags;
493
494
495
496
497
498
499
500
501
502
505
506
507
508
509
510
513
514
521
522
525 return d->initialEntryInfo.filePath();
529
530
533 return d->iteratorFlags;
537
538
539
542 return d->nameFilters;
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
575
576
577
578
581
582
583
584
587
588
589
590
591
592
593
594
595
596
597
598
599
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
641
642
643
644
645
648
649
650
651
652
655
656
657
658
659
662
663
664
665
666
667
668
669
670
671
672
673
674
675
678
679
680
681
682
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
742 return dirListPtr->currentEntryInfo.fileInfo();
747 return dirListPtr->currentEntryInfo.fileName();
752 return dirListPtr->currentEntryInfo.baseName();
757 return dirListPtr->currentEntryInfo.completeBaseName();
762 return dirListPtr->currentEntryInfo.suffix();
767 return dirListPtr->currentEntryInfo.bundleName();
772 return dirListPtr->currentEntryInfo.completeSuffix();
777 return dirListPtr->currentEntryInfo.filePath();
782 return dirListPtr->currentEntryInfo.canonicalFilePath();
787 return dirListPtr->currentEntryInfo.absoluteFilePath();
792 return dirListPtr->currentEntryInfo.absolutePath();
797 return dirListPtr->currentEntryInfo.isDir();
802 return dirListPtr->currentEntryInfo.isFile();
807 return dirListPtr->currentEntryInfo.isSymLink();
812 return dirListPtr->currentEntryInfo.exists();
817 return dirListPtr->currentEntryInfo.isHidden();
822 return dirListPtr->currentEntryInfo.isReadable();
827 return dirListPtr->currentEntryInfo.isWritable();
832 return dirListPtr->currentEntryInfo.isExecutable();
837 return dirListPtr->currentEntryInfo.size();
842 return dirListPtr->currentEntryInfo.fileTime(type, tz);
845#ifndef QT_NO_DEBUG_STREAM
847
848
849QDebug operator<<(QDebug debug, QDirListing::IteratorFlags flags)
851 QDebugStateSaver save(debug);
854 QByteArray ret =
"QDirListing::IteratorFlags(";
859 ret +=
"ExcludeFiles|";
861 ret +=
"ExcludeDirs|";
863 ret +=
"ExcludeOther|";
865 ret +=
"ResolveSymlinks|";
871 ret +=
"IncludeHidden|";
873 ret +=
"IncludeDotAndDotDot|";
875 ret +=
"CaseSensitive|";
879 ret +=
"FollowDirSymlinks|";
881 ret +=
"IncludeBrokenSymlinks|";
883 ret +=
"NoNameFiltersForDirs|";
885 if (ret.endsWith(
'|'))
889 debug.noquote() << ret;
bool entryMatches(QDirEntryInfo &info)
QDirListing::IteratorFlags iteratorFlags
void pushInitialDirectory()
void checkAndPushDirectory(QDirEntryInfo &info)
std::unique_ptr< QAbstractFileEngine > engine
QDuplicateTracker< QString > visitedLinks
bool hasIterators() const
bool matchesFilters(QDirEntryInfo &data) const
QDirEntryInfo initialEntryInfo
QDirEntryInfo currentEntryInfo
std::vector< FEngineIteratorPtr > fileEngineIterators
std::vector< FsIteratorPtr > nativeIterators
void pushDirectory(QDirEntryInfo &info)
Q_CORE_EXPORT bool isReadable() const
Q_CORE_EXPORT bool isHidden() const
Q_CORE_EXPORT bool isWritable() const
Q_CORE_EXPORT bool isExecutable() const
Q_CORE_EXPORT bool isFile() const
Q_CORE_EXPORT bool exists() const
Q_CORE_EXPORT bool isSymLink() const
Q_CORE_EXPORT bool isDir() const
const_iterator & operator++()
Pre-increment operator.
IteratorFlag
This enum class describes flags that can be used to configure the behavior of QDirListing.
static bool isDotOrDotDot(QStringView fileName)