#include <getopt.h>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <libversion/config.h>
#include <libversion/version.h>
class VersionsList {
private:
int flags_;
std::vector<std::string> versions_;
bool VersionLess(const std::string& a, const std::string& b) const {
int res = version_compare4(a.c_str(), b.c_str(), flags_, flags_);
if (res < 0) {
return true;
}
if (res > 0) {
return false;
}
return a < b; }
public:
VersionsList(int flags) : flags_(flags) {
}
void Read(std::istream& stream) {
std::string line;
while (std::getline(stream, line)) {
versions_.push_back(line);
}
}
void Sort() {
std::sort(
versions_.begin(),
versions_.end(),
[this](const std::string& a, const std::string& b) -> bool {
return VersionLess(a, b);
}
);
}
void Dump(std::ostream& stream) const {
for (const auto& version: versions_) {
stream << version << '\n';
}
}
void VerboseDump(std::ostream& stream) const {
std::string prev;
for (const auto& version: versions_) {
stream << version << (VersionLess(prev, version) ? " (<)" : " (==)") << '\n';
prev = version;
}
}
};
static void print_version() {
std::cerr << "libversion " << LIBVERSION_VERSION << std::endl;
}
static void print_usage(const char* progname) {
std::cerr << "Usage: " << progname << " [-pa] [path]\n";
std::cerr << "\n";
std::cerr << " -p - 'p' letter is treated as 'patch' instead of 'pre'\n";
std::cerr << " -a - any alphabetic characters are treated as post-release\n";
std::cerr << " -v - verbose mode (display whether version is different from the previous one)\n";
std::cerr << "\n";
std::cerr << " -h, -? - print usage and exit\n";
std::cerr << " -V - print version and exit" << std::endl;
}
int main(int argc, char** argv) {
int ch, flags = 0;
const char* progname = argv[0];
bool verbose = false;
while ((ch = getopt(argc, argv, "pahvV")) != -1) {
switch (ch) {
case 'p':
flags |= VERSIONFLAG_P_IS_PATCH;
break;
case 'a':
flags |= VERSIONFLAG_ANY_IS_PATCH;
break;
case 'h':
case '?':
print_usage(progname);
return 0;
case 'V':
print_version();
return 0;
case 'v':
verbose = true;
break;
default:
print_usage(progname);
return 1;
}
}
argc -= optind;
argv += optind;
VersionsList versions(flags);
if (argc == 0) {
versions.Read(std::cin);
}
for (int arg = 0; arg < argc; ++arg) {
std::fstream fs(argv[arg]);
versions.Read(fs);
}
versions.Sort();
if (verbose) {
versions.VerboseDump(std::cout);
} else {
versions.Dump(std::cout);
}
return 0;
}