Skip to content

Commit 361c072

Browse files
committed
Automatically create directories if they don't exist; issue #41
1 parent 93bc9d7 commit 361c072

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

src/ProcessReads.h

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,35 @@
3434
#define KSEQ_INIT_READY
3535
KSEQ_INIT(gzFile, gzread)
3636
#endif
37+
38+
// Create directories recursively if they don't exist (exiting if not possible)
39+
// C++17 and above only
40+
#if SPLITCODE_CPP_VERSION < 201703L
41+
void ensure_parent_directories(const std::string& filepath) { } // Empty
42+
#else
43+
#include <filesystem>
44+
#include <system_error>
45+
inline void ensure_parent_directories(const std::string& filepath) {
46+
if (filepath.length() == 0) return;
47+
namespace fs = std::filesystem;
48+
fs::path p(filepath);
49+
fs::path parent = p.parent_path();
50+
// No parent (e.g. "out.txt") → nothing to do
51+
if (parent.empty()) {
52+
return;
53+
}
54+
std::error_code ec;
55+
fs::create_directories(parent, ec); // creates all missing parents; no-op if they exist
56+
if (ec) {
57+
std::fprintf(stderr,
58+
"Error: Failed to create directory '%s': %s\n",
59+
parent.string().c_str(),
60+
ec.message().c_str());
61+
std::exit(1);
62+
}
63+
}
64+
#endif
65+
3766

3867
class MasterProcessor;
3968

@@ -130,13 +159,15 @@ class MasterProcessor {
130159
std::string compress_level_str = "wb" + std::to_string(opt.compress_level);
131160
const char* gz_out_str = compress_level_str.c_str();
132161
for (auto f : opt.output_files) {
162+
ensure_parent_directories(f);
133163
if (opt.gzip) {
134164
out_gz.push_back(gzopen(f.c_str(), gz_out_str));
135165
} else {
136166
out.push_back(fopen(f.c_str(), "wb"));
137167
}
138168
}
139169
for (auto f : opt.unassigned_files) {
170+
ensure_parent_directories(f);
140171
if (opt.gzip) {
141172
if (f.length() == 0) outu_gz.push_back(nullptr);
142173
else outu_gz.push_back(gzopen(f.c_str(), gz_out_str));
@@ -147,6 +178,7 @@ class MasterProcessor {
147178
}
148179
if (!opt.pipe && !opt.no_x_out && !opt.no_output) {
149180
for (auto f : sc.get_umi_names()) {
181+
ensure_parent_directories(f+suffix);
150182
if (opt.gzip) {
151183
outumi_gz.push_back(gzopen((f+suffix_gz).c_str(), gz_out_str));
152184
} else {
@@ -182,6 +214,7 @@ class MasterProcessor {
182214
out_keep_name = v[i-1];
183215
}
184216
}
217+
ensure_parent_directories(out_keep_name+suffix_gz);
185218
out_keep_gz[f.second].push_back(gzopen((out_keep_name + suffix_gz).c_str(), gz_out_str));
186219
}
187220
}
@@ -207,6 +240,7 @@ class MasterProcessor {
207240
out_keep_name = v[i-1];
208241
}
209242
}
243+
ensure_parent_directories(out_keep_name+suffix);
210244
out_keep[f.second].push_back(fopen((out_keep_name + suffix).c_str(), "wb"));
211245
}
212246
}
@@ -238,6 +272,7 @@ class MasterProcessor {
238272
out_keep_name = v[i-1];
239273
}
240274
}
275+
ensure_parent_directories(out_keep_name+suffix_gz);
241276
out_keep_gz[f.second].push_back(gzopen((out_keep_name + suffix_gz).c_str(), gz_out_str));
242277
}
243278
}
@@ -263,14 +298,18 @@ class MasterProcessor {
263298
out_keep_name = v[i-1];
264299
}
265300
}
266-
else out_keep[f.second].push_back(fopen((out_keep_name + suffix).c_str(), "wb"));
301+
else {
302+
ensure_parent_directories(out_keep_name+suffix);
303+
out_keep[f.second].push_back(fopen((out_keep_name + suffix).c_str(), "wb"));
304+
}
267305
}
268306
}
269307
}
270308
}
271309
write_output_fastq = opt.output_fastq_specified || opt.pipe || opt.x_only;
272310
write_unassigned_fastq = outu.size() > 0 || outu_gz.size() > 0;
273311
if (write_barcode_separate_fastq) {
312+
ensure_parent_directories(opt.outputb_file);
274313
if (opt.gzip) {
275314
outb_gz = gzopen(opt.outputb_file.c_str(), gz_out_str);
276315
} else {

0 commit comments

Comments
 (0)