move run into the cli module

Now the code has been wholly reorganized!
This commit is contained in:
Frédéric Mangano-Tarumi 2018-11-14 20:15:30 -05:00
parent 2e88bdc207
commit b6c7a90d92
4 changed files with 86 additions and 86 deletions

View File

@ -2,6 +2,8 @@
#include <opustags.h>
#include <getopt.h>
#include <limits.h>
#include <unistd.h>
#include <memory>
@ -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;
}

View File

@ -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 */

View File

@ -1,90 +1,10 @@
#include <config.h>
#include "opustags.h"
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ogg/ogg.h>
#include <opustags.h>
/**
* 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;
}

View File

@ -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<std::string>& comments, FILE* output);
std::list<std::string> 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);
/** \} */