diff --git a/src/main.cpp b/src/main.cpp index 1e999f3..effbdb0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,11 +2,13 @@ #include #include #include +#include #include #include #include #include #include +#include // POSIX #include @@ -21,38 +23,40 @@ // project #include "version.hpp" -std::vector additions; -std::string change; -std::map changes; -std::vector deletions; -bool should_list = false; -bool sort = false; +using namespace std; -static void handle_additions(std::vector& tags) { - for (const std::string& tag : additions) { - tags.push_back(tag); - } +set additions; +string change; +map changes; +vector deletions; +bool should_list = false; + +static void handle_additions(vector& cur_tags) { + set tags {cur_tags.begin(), cur_tags.end()}; + tags.insert(additions.begin(), additions.end()); + cur_tags.clear(); + copy(tags.begin(), tags.end(), back_inserter(cur_tags)); } -static void handle_changes(std::vector& tags) { +static void handle_changes(vector& tags) { for (const auto& elem : changes) { - auto it = std::find(tags.begin(), tags.end(), elem.first); + auto it = find(tags.begin(), tags.end(), elem.first); if (it != tags.end()) { *it = elem.second; } } } -static void handle_deletions(std::vector& tags) { - for (const std::string& tag : deletions) { - tags.erase(std::remove(tags.begin(), tags.end(), tag), tags.end()); +static void handle_deletions(vector& tags) { + for (const string& tag : deletions) { + tags.erase(remove(tags.begin(), tags.end(), tag), tags.end()); } } static void process(const char* path) { const char* tagname {"user.xdg.tags"}; - std::vector tags; - std::vector buf(1024); + vector tags; + vector buf(1024); ssize_t sz = 0; do { sz = getxattr(path, tagname, buf.data(), buf.size()); @@ -67,41 +71,37 @@ static void process(const char* path) { } } while (sz == -1 && errno == ERANGE); if (sz > 0) { - std::string val(buf.data(), sz); + string val(buf.data(), sz); tags = sc::split(val, ","); } bool edits = additions.size() > 0 || changes.size() > 0 || deletions.size() > 0; if (edits) { if (should_list) { - std::cout << path << '\n'; - std::cout << " before: " << sc::io::greenf << sc::join(tags, ", ") << sc::io::reset << '\n'; + cout << path << '\n'; + cout << " before: " << sc::io::greenf << sc::join(tags, ", ") << sc::io::reset << '\n'; } handle_deletions(tags); handle_changes(tags); handle_additions(tags); - if (sort) { - std::sort(tags.begin(), tags.end()); - } if (should_list) { - std::cout << " after: " << sc::io::yellowf << sc::join(tags, ", ") << sc::io::reset << '\n'; + cout << " after: " << sc::io::yellowf << sc::join(tags, ", ") << sc::io::reset << '\n'; } - std::string joined {sc::join(tags, ",")}; + string joined {sc::join(tags, ",")}; throw_if_min1(setxattr(path, tagname, joined.c_str(), joined.size(), 0)); } else { - std::cout << path << ": " << sc::io::yellowf << sc::join(tags, ", ") << sc::io::reset << '\n'; + cout << path << ": " << sc::io::yellowf << sc::join(tags, ", ") << sc::io::reset << '\n'; } } static void print_help() { - std::cout << "usage: tagger [-h|--version] [-l] [-s] [-a tag] [-d tag] [-c tag -i tag] file...\n"; - std::cout << " -h, --help show this help text and exit\n"; - std::cout << " --version show version number and exit\n"; - std::cout << " -l, --list list all tags\n"; - std::cout << " -s, --sort write tags sorted alphabetically\n"; - std::cout << " -a, --add add a tag\n"; - std::cout << " -d, --delete delete a tag\n"; - std::cout << " -c, --change change a tag\n"; - std::cout << " -i, --into into new value\n"; + cout << "usage: tagger [-h|--version] [-l] [-a tag] [-d tag] [-c tag -i tag] file...\n"; + cout << " -h, --help show this help text and exit\n"; + cout << " --version show version number and exit\n"; + cout << " -l, --list list all tags\n"; + cout << " -a, --add add a tag\n"; + cout << " -d, --delete delete a tag\n"; + cout << " -c, --change change a tag\n"; + cout << " -i, --into into new value\n"; } int main(int argc, char* argv[]) { @@ -114,45 +114,43 @@ int main(int argc, char* argv[]) { {"help", no_argument, nullptr, 'h'}, {"into", required_argument, nullptr, 'i'}, {"list", no_argument, nullptr, 'l'}, - {"sort", no_argument, nullptr, 's'}, {"version", no_argument, &opt_val, 1}, {nullptr, 0, nullptr, 0} }; - while ((opt_char = getopt_long(argc, argv, "a:c:d:hi:ls", long_options, nullptr)) != -1) { - std::string arg {optarg ? optarg : ""}; + while ((opt_char = getopt_long(argc, argv, "a:c:d:hi:l", long_options, nullptr)) != -1) { + string arg {optarg ? optarg : ""}; switch (opt_char) { case 0: { // handle long-only options here switch (opt_val) { case 1: - std::cout << tagger_version() << '\n'; + cout << tagger_version() << '\n'; return EXIT_SUCCESS; } break; } - case 'a': additions.push_back(arg); break; + case 'a': additions.insert(arg); break; case 'c': change = arg; break; case 'd': deletions.push_back(arg); break; case 'h': print_help(); return EXIT_SUCCESS; case 'i': changes.emplace(change, arg); break; case 'l': should_list = true; break; - case 's': sort = true; break; - case '?': throw std::runtime_error {"unrecognized option"}; + case '?': throw runtime_error {"unrecognized option"}; } } if (optind == argc) { // here when no file args - throw std::runtime_error {"please specify input files"}; + throw runtime_error {"please specify input files"}; } for (int i = optind; i < argc; ++i) { try { process(argv[i]); - } catch (const std::runtime_error& ex) { - std::cerr << "tagger: " << ex.what() << '\n'; + } catch (const runtime_error& ex) { + cerr << "tagger: " << ex.what() << '\n'; } } - } catch (const std::exception& ex) { - std::cerr << "tagger: " << ex.what() << '\n'; + } catch (const exception& ex) { + cerr << "tagger: " << ex.what() << '\n'; return EXIT_FAILURE; } return EXIT_SUCCESS;