diff --git a/io/io/src/TDirectoryFile.cxx b/io/io/src/TDirectoryFile.cxx index d4f33a9c12a6e..34ae71942a592 100644 --- a/io/io/src/TDirectoryFile.cxx +++ b/io/io/src/TDirectoryFile.cxx @@ -1258,7 +1258,9 @@ TFile *TDirectoryFile::OpenFile(const char *name, Option_t *option,const char *f /// Create a sub-directory "a" or a hierarchy of sub-directories "a/b/c/...". /// /// @param name the name or hierarchy of the subdirectory ("a" or "a/b/c") -/// @param title the title +/// @param title the title of the directory. For hierarchies, this is only applied +/// to the innermost directory (so if `name == "a/b/c"` and `title == "my dir"`, +/// only `c` will have the title `"my dir"`). /// @param returnExistingDirectory if key-name is already existing, the returned /// value points to preexisting sub-directory if true and to `nullptr` if false. /// @return a pointer to the created sub-directory, not to the top sub-directory @@ -1284,10 +1286,11 @@ TDirectory *TDirectoryFile::mkdir(const char *name, const char *title, Bool_t re TDirectoryFile *tmpdir = nullptr; GetObject(workname.Data(), tmpdir); if (!tmpdir) { - tmpdir = (TDirectoryFile*)mkdir(workname.Data(),title); + // We give all intermediate directories a default title, as `title` is only given to the innermost dir. + tmpdir = (TDirectoryFile *)mkdir(workname.Data(), workname.Data()); if (!tmpdir) return nullptr; } - return tmpdir->mkdir(slash + 1); + return tmpdir->mkdir(slash + 1, title, returnExistingDirectory); } TDirectory::TContext ctxt(this); diff --git a/io/io/test/TFileTests.cxx b/io/io/test/TFileTests.cxx index 16c58e8fd46a6..e33ddfc59ec66 100644 --- a/io/io/test/TFileTests.cxx +++ b/io/io/test/TFileTests.cxx @@ -5,6 +5,8 @@ #include "gtest/gtest.h" +#include + #include "TFile.h" #include "TMemFile.h" #include "TDirectory.h" @@ -280,6 +282,28 @@ TEST(TDirectoryFile, SeekParent) EXPECT_EQ(dir11->GetSeekParent(), 239); } +TEST(TDirectoryFile, RecursiveMkdir) +{ + TMemFile f("mkdirtest.root", "RECREATE"); + auto dir1 = f.mkdir("a/b/c", "my dir"); + EXPECT_NE(dir1, nullptr); + { + ROOT::TestSupport::CheckDiagsRAII diags; + diags.requiredDiag(kError, "TDirectoryFile::mkdir","An object with name c exists already"); + auto dir2 = f.mkdir("a/b/c", "", /* returnExisting = */ false); + EXPECT_EQ(dir2, nullptr); + } + auto dir3 = f.mkdir("a/b/c", "foobar", /* returnExisting = */ true); + EXPECT_EQ(dir3, dir1); + EXPECT_STREQ(dir3->GetTitle(), "my dir"); + auto dirB = dir3->GetMotherDir(); + ASSERT_NE(dirB, nullptr); + EXPECT_STREQ(dirB->GetTitle(), "b"); + auto dirA = dirB->GetMotherDir(); + ASSERT_NE(dirA, nullptr); + EXPECT_STREQ(dirA->GetTitle(), "a"); +} + // https://its.cern.ch/jira/browse/ROOT-10581 TEST(TFile, PersistTObjectStdArray) {