mirror of
https://github.com/fmang/opustags.git
synced 2025-01-16 05:03:13 +01:00
move run into the cli module
Now the code has been wholly reorganized!
This commit is contained in:
parent
2e88bdc207
commit
b6c7a90d92
76
src/cli.cc
76
src/cli.cc
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
/** \} */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user