Skip to content

Commit ff395d7

Browse files
committed
Use RAII in output_writer_t
1 parent f541bdd commit ff395d7

File tree

5 files changed

+35
-36
lines changed

5 files changed

+35
-36
lines changed

lib/PATO/output_writer.cpp

+32-26
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@ pato::output_writer_t::create(const pato::options_t &opts) {
9090
return pato::output_writer_t{output_file, summary_file, opts};
9191
}
9292

93+
pato::output_writer_t::output_writer_t(std::FILE *output_file_,
94+
std::FILE *summary_file_,
95+
const options_t &opts_)
96+
: output_file{output_file_,
97+
[this](std::FILE *f) -> void {
98+
if (opts.output_format != output_format_t::summary) {
99+
std::fclose(f);
100+
}
101+
}},
102+
summary_file{summary_file_, [](std::FILE *f) -> void { std::fclose(f); }},
103+
opts{opts_} {}
104+
93105
void pato::output_writer_t::print_motifs(const pato::motif_vector_t &motifs,
94106
const pato::name_vector_t &names) {
95107
if (opts.output_format == output_format_t::summary || motifs.empty()) {
@@ -101,25 +113,26 @@ void pato::output_writer_t::print_motifs(const pato::motif_vector_t &motifs,
101113

102114
for (const auto &m : motifs) {
103115
if (opts.output_format == output_format_t::bed) {
104-
std::fprintf(
105-
output_file, "%s\t%lu\t%lu\t%u\t%c\t%.2g\t%s\t%.2g\t%d\t%s\t-\n",
106-
seqan::toCString(names[seqan::getSequenceNo(m)]),
107-
seqan::beginPosition(m), seqan::endPosition(m), seqan::score(m),
108-
seqan::getMotif(m),
109-
1.0 - static_cast<double>(seqan::score(m)) /
110-
(seqan::endPosition(m) - seqan::beginPosition(m)),
111-
seqan::toCString(seqan::errorString(m)), seqan::guanineRate(m),
112-
seqan::duplicates(m),
113-
seqan::toCString(opts.pretty_output ? seqan::prettyString(m)
114-
: seqan::outputString(m)));
116+
std::fprintf(output_file.get(),
117+
"%s\t%lu\t%lu\t%u\t%c\t%.2g\t%s\t%.2g\t%d\t%s\t-\n",
118+
seqan::toCString(names[seqan::getSequenceNo(m)]),
119+
seqan::beginPosition(m), seqan::endPosition(m),
120+
seqan::score(m), seqan::getMotif(m),
121+
1.0 - static_cast<double>(seqan::score(m)) /
122+
(seqan::endPosition(m) - seqan::beginPosition(m)),
123+
seqan::toCString(seqan::errorString(m)),
124+
seqan::guanineRate(m), seqan::duplicates(m),
125+
seqan::toCString(opts.pretty_output
126+
? seqan::prettyString(m)
127+
: seqan::outputString(m)));
115128
} else {
116129
if (last_sequence_id != seqan::getSequenceNo(m)) {
117130
counter = 1;
118131
last_sequence_id = seqan::getSequenceNo(m);
119132
}
120133

121134
std::fprintf(
122-
output_file, ">%s_%u\t%lu-%lu %c\t%u\t%s\t%g\t%d\t-\n%s\n",
135+
output_file.get(), ">%s_%u\t%lu-%lu %c\t%u\t%s\t%g\t%d\t-\n%s\n",
123136
seqan::toCString(names[seqan::getSequenceNo(m)]), counter++,
124137
seqan::beginPosition(m), seqan::endPosition(m), seqan::getMotif(m),
125138
seqan::score(m), seqan::toCString(seqan::errorString(m)),
@@ -317,21 +330,21 @@ void pato::output_writer_t::print_motifs_summary(
317330
const pato::name_vector_t &names) {
318331
for (const auto &potential : potentials) {
319332
if (seqan::hasCount(potential)) {
320-
std::fprintf(summary_file, "%s\t%u\t%.3g",
333+
std::fprintf(summary_file.get(), "%s\t%u\t%.3g",
321334
seqan::toCString(names[seqan::getKey(potential)]),
322335
seqan::getCounts(potential),
323336
seqan::getCounts(potential) / seqan::getNorm(potential));
324337
if (opts.run_mode == run_mode_t::tfo_search) {
325338
std::fprintf(
326-
summary_file, "\t%u\t%.3g\t%u\t%.3g\t%u\t%.3g\t",
339+
summary_file.get(), "\t%u\t%.3g\t%u\t%.3g\t%u\t%.3g\t",
327340
seqan::getCount(potential, 'R'),
328341
seqan::getCount(potential, 'R') / seqan::getNorm(potential),
329342
seqan::getCount(potential, 'Y'),
330343
seqan::getCount(potential, 'Y') / seqan::getNorm(potential),
331344
seqan::getCount(potential, 'M'),
332345
seqan::getCount(potential, 'M') / seqan::getNorm(potential));
333346
}
334-
std::fprintf(summary_file, "\n");
347+
std::fprintf(summary_file.get(), "\n");
335348
}
336349
}
337350
}
@@ -362,7 +375,7 @@ void pato::output_writer_t::print_triplexes(
362375
auto tts_seq_id = match.ttsSeqNo;
363376

364377
std::fprintf(
365-
output_file,
378+
output_file.get(),
366379
"%s\t%lu\t%lu\t%s\t%lu\t%lu\t%u\t%.2g\t%s\t%c\t%c\t%c\t%.2g",
367380
seqan::toCString(tfo_names[tfo_seq_id]), match.oBegin, match.oEnd,
368381
seqan::toCString(tts_names[tts_seq_id]), match.dBegin, match.dEnd,
@@ -373,11 +386,11 @@ void pato::output_writer_t::print_triplexes(
373386
match.motif, match.strand, match.parallel ? 'P' : 'A',
374387
static_cast<double>(match.guanines) / (match.dEnd - match.dBegin));
375388
if (opts.output_format == output_format_t::triplex) {
376-
std::fprintf(output_file, "%s",
389+
std::fprintf(output_file.get(), "%s",
377390
seqan::toCString(triplex_alignment_string(match, tfo_motifs,
378391
tts_motifs)));
379392
}
380-
std::fprintf(output_file, "\n");
393+
std::fprintf(output_file.get(), "\n");
381394
#if defined(_OPENMP)
382395
}
383396
#endif
@@ -391,7 +404,7 @@ void pato::output_writer_t::print_triplex_summary(
391404
for (const auto &potential_entry : potentials) {
392405
const auto &potential = potential_entry.second;
393406
if (seqan::hasCount(potential)) {
394-
std::fprintf(summary_file,
407+
std::fprintf(summary_file.get(),
395408
"%s\t%s\t%u\t%.3g\t%u\t%.3g\t%u\t%.3g\t%u\t%.3g\t\n",
396409
seqan::toCString(tts_names[seqan::getKey(potential).second]),
397410
seqan::toCString(tfo_names[seqan::getKey(potential).first]),
@@ -406,10 +419,3 @@ void pato::output_writer_t::print_triplex_summary(
406419
}
407420
}
408421
}
409-
410-
void pato::output_writer_t::destroy() {
411-
if (opts.output_format != pato::output_format_t::summary) {
412-
std::fclose(output_file);
413-
}
414-
std::fclose(summary_file);
415-
}

lib/PATO/output_writer.h

+3-7
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,12 @@ class output_writer_t {
5353
const name_vector_t &tfo_names,
5454
const name_vector_t &tts_names);
5555

56-
// FIXME: Use RAII!
57-
void destroy();
58-
5956
private:
6057
output_writer_t(std::FILE *output_file_, std::FILE *summary_file_,
61-
const options_t &opts_)
62-
: output_file{output_file_}, summary_file{summary_file_}, opts{opts_} {}
58+
const options_t &opts_);
6359

64-
std::FILE *output_file;
65-
std::FILE *summary_file;
60+
std::shared_ptr<std::FILE> output_file;
61+
std::shared_ptr<std::FILE> summary_file;
6662

6763
const options_t &opts;
6864
};

lib/PATO/tfo_finder.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ pato::find_tfo_motifs(const pato::options_t &opts) {
246246
#pragma omp section
247247
output_writer->print_motifs_summary(tfo_potentials, tfo_names);
248248
} // #pragma omp parallel sections num_threads(2)
249-
output_writer->destroy();
250249

251250
return pato::find_tfo_motifs_result::success;
252251
}

lib/PATO/tpx_finder.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,6 @@ pato::find_tpx_result pato::find_tpxes(const pato::options_t &opts) {
334334
#endif
335335
potentials.clear();
336336
}
337-
output_writer->destroy();
338337

339338
return pato::find_tpx_result::success;
340339
}

lib/PATO/tts_finder.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,6 @@ pato::find_tts_motifs(const pato::options_t &opts) {
213213
tts_sequences.clear();
214214
tts_potentials.clear();
215215
}
216-
output_writer->destroy();
217216

218217
return pato::find_tts_motifs_result::success;
219218
}

0 commit comments

Comments
 (0)