Skip to content

Commit 2d8b749

Browse files
committed
[main] rootls: improve recursive printing
The current algorithm didn't properly handle certain cases when the -r flag is used (namely, directories were not printed in a newline)
1 parent 6d3e9ed commit 2d8b749

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

main/src/rootls.cxx

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ static void PrintRNTuple(std::ostream &stream, const ROOT::RNTupleDescriptor &de
282282
std::size_t maxNameLen = 0, maxTypeLen = 0;
283283
std::vector<const ROOT::RFieldDescriptor *> fields;
284284
fields.reserve(rootField.GetLinkIds().size());
285-
for (const auto &field: desc.GetFieldIterable(rootField.GetId())) {
285+
for (const auto &field : desc.GetFieldIterable(rootField.GetId())) {
286286
fields.push_back(&field);
287287
maxNameLen = std::max(maxNameLen, field.GetFieldName().length());
288288
maxTypeLen = std::max(maxTypeLen, field.GetTypeName().length());
@@ -482,11 +482,11 @@ static void PrintNodesInColumns(std::ostream &stream, const RootLsTree &tree,
482482

483483
const bool isTerminal = terminalSize.x + terminalSize.y > 0;
484484

485-
bool mustIndent = false;
485+
auto curCol = 0u;
486486
for (auto i = 0u; i < nNodes; ++i) {
487487
NodeIdx childIdx = nodesBegin[i];
488488
const auto &child = tree.fNodes[childIdx];
489-
if ((i % nCols) == 0 || mustIndent) {
489+
if (curCol == 0) {
490490
PrintIndent(stream, indent);
491491
}
492492

@@ -499,22 +499,39 @@ static void PrintNodesInColumns(std::ostream &stream, const RootLsTree &tree,
499499
stream << Color(kAnsiGreen);
500500
}
501501

502-
const bool isExtremal = !(((i + 1) % nCols) != 0 && i != nNodes - 1);
502+
// Handle line breaks. Lines are broken in the following situations:
503+
// - when the current column number reaches the max number of columns
504+
// - when we are in recursive mode and the item is a directory with children
505+
// - when we are in recursive mode and the NEXT item is a directory with children
506+
507+
const bool isDirWithRecursiveDisplay = isDir && (flags & RootLsArgs::kRecursiveListing) && child.fNChildren > 0;
508+
509+
bool nextIsDirWithRecursiveDisplay = false;
510+
if ((flags & RootLsArgs::kRecursiveListing) && i < nNodes - 1) {
511+
NodeIdx nextChildIdx = nodesBegin[i + 1];
512+
const auto &nextChild = tree.fNodes[nextChildIdx];
513+
nextIsDirWithRecursiveDisplay =
514+
nextChild.fNChildren > 0 && ClassInheritsFrom(nextChild.fClassName.c_str(), "TDirectory");
515+
}
516+
517+
const bool isExtremal = (((curCol + 1) % nCols) == 0) || (i == nNodes - 1) || isDirWithRecursiveDisplay ||
518+
nextIsDirWithRecursiveDisplay;
503519
if (!isExtremal) {
504-
stream << std::left << std::setw(colWidths[i % nCols]) << child.fName;
520+
stream << std::left << std::setw(colWidths[curCol % nCols]) << child.fName;
505521
} else {
506522
stream << std::setw(1) << child.fName;
507523
}
508524
stream << Color(kAnsiNone);
509525

510-
if (isExtremal)
511-
stream << "\n";
526+
if (isExtremal) {
527+
stream << '\n';
528+
curCol = 0;
529+
} else {
530+
++curCol;
531+
}
512532

513-
if (isDir && (flags & RootLsArgs::kRecursiveListing)) {
514-
if (!isExtremal)
515-
stream << "\n";
533+
if (isDirWithRecursiveDisplay) {
516534
PrintChildrenInColumns(stream, tree, childIdx, flags, indent + 2);
517-
mustIndent = true;
518535
}
519536
}
520537
}

roottest/main/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ ROOTTEST_ADD_TEST(RecursiveRootls2
9191
OUTREF RecursiveRootls2.ref
9292
ENVIRONMENT ${test_env})
9393

94+
ROOTTEST_ADD_TEST(RecursiveRootls3
95+
COMMAND ${TOOLS_PREFIX}/rootls${exeext} -r subdirs.root
96+
OUTREF RecursiveRootls3.ref
97+
ENVIRONMENT ${test_env})
98+
9499
ROOTTEST_ADD_TEST(RootlsRNTuple
95100
COMMAND ${TOOLS_PREFIX}/rootls${exeext} -R RNTuple.root
96101
OUTREF RootlsRNTuple.ref

roottest/main/RecursiveRootls3.ref

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
sub
2+
s1 s2
3+
s3
4+
t1
5+
c
6+
sub2 sub3

0 commit comments

Comments
 (0)