From b6c7a90d921216658b1124207d0ee8b2b7a3fbf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Mangano-Tarumi?= Date: Wed, 14 Nov 2018 20:15:30 -0500 Subject: [PATCH] move run into the cli module Now the code has been wholly reorganized! --- src/cli.cc | 76 +++++++++++++++++++++++++++++++++++++++++ src/error.cc | 1 + src/opustags.cc | 91 ++++--------------------------------------------- src/opustags.h | 4 ++- 4 files changed, 86 insertions(+), 86 deletions(-) diff --git a/src/cli.cc b/src/cli.cc index 15cf8ac..fb4f1ea 100644 --- a/src/cli.cc +++ b/src/cli.cc @@ -2,6 +2,8 @@ #include #include +#include +#include #include @@ -327,3 +329,77 @@ ot::status ot::process(ogg_reader& reader, ogg_writer& writer, const ot::options } return ot::status::ok; } + +/** + * Check if two filepaths point to the same file, after path canonicalization. + * The path "-" is treated specially, meaning stdin for path_in and stdout for path_out. + */ +static bool same_file(const std::string& path_in, const std::string& path_out) +{ + if (path_in == "-" || path_out == "-") + return false; + char canon_in[PATH_MAX+1], canon_out[PATH_MAX+1]; + if (realpath(path_in.c_str(), canon_in) && realpath(path_out.c_str(), canon_out)) { + return (strcmp(canon_in, canon_out) == 0); + } + return false; +} + +/** + * Open the input and output streams, then call #ot::process. + */ +ot::status ot::run(ot::options& opt) +{ + if (!opt.path_out.empty() && same_file(opt.path_in, opt.path_out)) { + fputs("error: the input and output files are the same\n", stderr); + return ot::status::fatal_error; + } + ot::ogg_reader reader; + ot::ogg_writer writer; + if (opt.path_in == "-") { + reader.file = stdin; + } else { + reader.file = fopen(opt.path_in.c_str(), "r"); + if (reader.file == nullptr) { + perror("fopen"); + return ot::status::fatal_error; + } + } + writer.file = NULL; + if (opt.inplace != nullptr) + opt.path_out = opt.path_in + opt.inplace; + if (!opt.path_out.empty()) { + if (opt.path_out == "-") { + writer.file = stdout; + } else { + if (!opt.overwrite && !opt.inplace) { + if (access(opt.path_out.c_str(), F_OK) == 0) { + fprintf(stderr, "'%s' already exists (use -y to overwrite)\n", opt.path_out.c_str()); + fclose(reader.file); + return ot::status::fatal_error; + } + } + writer.file = fopen(opt.path_out.c_str(), "w"); + if (!writer.file) { + perror("fopen"); + fclose(reader.file); + return ot::status::fatal_error; + } + } + } + ot::status rc = process(reader, writer, opt); + fclose(reader.file); + if (writer.file) + fclose(writer.file); + if (rc != ot::status::ok) { + if (!opt.path_out.empty() && writer.file != stdout) + remove(opt.path_out.c_str()); + return ot::status::fatal_error; + } else if (opt.inplace) { + if (rename(opt.path_out.c_str(), opt.path_in.c_str()) == -1) { + perror("rename"); + return ot::status::fatal_error; + } + } + return ot::status::ok; +} diff --git a/src/error.cc b/src/error.cc index 436fb77..f5ed14e 100644 --- a/src/error.cc +++ b/src/error.cc @@ -3,6 +3,7 @@ static const char* messages[] = { "OK", "Need to exit", + "Fatal error", "Bad command-line arguments", "Integer overflow", nullptr, /* standard error: call stderror */ diff --git a/src/opustags.cc b/src/opustags.cc index 3ad6356..384cedc 100644 --- a/src/opustags.cc +++ b/src/opustags.cc @@ -1,90 +1,10 @@ -#include - -#include "opustags.h" - -#include -#include -#include -#include -#include -#include -#include +#include /** - * Check if two filepaths point to the same file, after path canonicalization. - * The path "-" is treated specially, meaning stdin for path_in and stdout for path_out. + * Main entry point to the opustags binary. + * + * Does practically nothing but call the cli module. */ -static bool same_file(const std::string& path_in, const std::string& path_out) -{ - if (path_in == "-" || path_out == "-") - return false; - char canon_in[PATH_MAX+1], canon_out[PATH_MAX+1]; - if (realpath(path_in.c_str(), canon_in) && realpath(path_out.c_str(), canon_out)) { - return (strcmp(canon_in, canon_out) == 0); - } - return false; -} - -/** - * Open the input and output streams, then call #ot::process. - */ -static int run(ot::options& opt) -{ - if (!opt.path_out.empty() && same_file(opt.path_in, opt.path_out)) { - fputs("error: the input and output files are the same\n", stderr); - return EXIT_FAILURE; - } - ot::ogg_reader reader; - ot::ogg_writer writer; - if (opt.path_in == "-") { - reader.file = stdin; - } else { - reader.file = fopen(opt.path_in.c_str(), "r"); - if (reader.file == nullptr) { - perror("fopen"); - return EXIT_FAILURE; - } - } - writer.file = NULL; - if (opt.inplace != nullptr) - opt.path_out = opt.path_in + opt.inplace; - if (!opt.path_out.empty()) { - if (opt.path_out == "-") { - writer.file = stdout; - } else { - if (!opt.overwrite && !opt.inplace){ - if (access(opt.path_out.c_str(), F_OK) == 0) { - fprintf(stderr, "'%s' already exists (use -y to overwrite)\n", opt.path_out.c_str()); - fclose(reader.file); - return EXIT_FAILURE; - } - } - writer.file = fopen(opt.path_out.c_str(), "w"); - if(!writer.file){ - perror("fopen"); - fclose(reader.file); - return EXIT_FAILURE; - } - } - } - ot::status rc = process(reader, writer, opt); - fclose(reader.file); - if(writer.file) - fclose(writer.file); - if (rc != ot::status::ok) { - if (!opt.path_out.empty() && writer.file != stdout) - remove(opt.path_out.c_str()); - return EXIT_FAILURE; - } - else if (opt.inplace) { - if (rename(opt.path_out.c_str(), opt.path_in.c_str()) == -1) { - perror("rename"); - return EXIT_FAILURE; - } - } - return EXIT_SUCCESS; -} - int main(int argc, char** argv) { ot::status rc; ot::options opt; @@ -93,5 +13,6 @@ int main(int argc, char** argv) { return EXIT_SUCCESS; else if (rc != ot::status::ok) return EXIT_FAILURE; - return run(opt); + rc = run(opt); + return rc == ot::status::ok ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/src/opustags.h b/src/opustags.h index 0ccbdd9..9071e11 100644 --- a/src/opustags.h +++ b/src/opustags.h @@ -29,6 +29,7 @@ namespace ot { enum class status { ok = 0, exit_now, + fatal_error, bad_arguments, int_overflow, /** On standard error, errno will give more details. */ @@ -256,7 +257,8 @@ status process_options(int argc, char** argv, options& opt); void print_comments(const std::list& comments, FILE* output); std::list read_comments(FILE* input); -ot::status process(ogg_reader& reader, ogg_writer& writer, const ot::options &opt); +status run(options& opt); +status process(ogg_reader& reader, ogg_writer& writer, const options &opt); /** \} */