# HG changeset patch # User František Kučera # Date 1547727277 -3600 # Node ID 3e1608320b6cb6f487298f8a2a104c96ecb6965f # Parent b4f29fb16159b48da96a222f728cb69f81e49f6c parse CLI arguments diff -r b4f29fb16159 -r 3e1608320b6c src/CLIParser.h --- a/src/CLIParser.h Wed Jan 16 19:31:37 2019 +0100 +++ b/src/CLIParser.h Thu Jan 17 13:14:37 2019 +0100 @@ -20,6 +20,8 @@ #include #include +#include +#include #include "Configuration.h" #include "FileAttributeFinder.h" @@ -31,23 +33,72 @@ using namespace relpipe::writer; class CLIParser { +private: + + string_t readNext(std::vector arguments, int& i) { + if (i < arguments.size()) return arguments[i++]; + else throw relpipe::cli::RelpipeCLIException(L"Missing CLI argument" + (i > 0 ? (L" after " + arguments[i - 1]) : L""), relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS); + } + + void addField(Configuration& c, string_t& group, string_t& name, std::vector& aliases, std::map& options) { + if (group.size()) { + c.fields.push_back(RequestedField(group, name, aliases, options)); + group.clear(); + name.clear(); + aliases.clear(); + options.clear(); + } + } + public: + static const string_t OPTION_FILE; + static const string_t OPTION_XATTR; + static const string_t OPTION_AS; + static const string_t OPTION_OPTION; + Configuration parse(const std::vector& arguments) { Configuration c; - // TODO: parse arguments - c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_PATH_ORIGINAL)); - // c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_PATH_ABSOLUTE)); - // c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_PATH_CANONICAL)); - // c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_NAME)); - c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_TYPE)); - // c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_TYPE,{L"type_a", L"type_b"})); - c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_SYMLINK_TARGET_TYPE)); - // c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_SYMLINK_TARGET)); - c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_SIZE)); - c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_OWNER)); - c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_GROUP)); - c.fields.push_back(RequestedField(RequestedField::GROUP_XATTR, L"user.xdg.origin.url")); + if (arguments.empty()) { + // default set of fields: + c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_PATH_ORIGINAL)); + // c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_PATH_ABSOLUTE)); + // c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_PATH_CANONICAL)); + // c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_NAME)); + c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_TYPE)); + // c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_TYPE,{L"type_a", L"type_b"})); // one field → two attributes with same value + // c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_SYMLINK_TARGET_TYPE)); + // c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_SYMLINK_TARGET)); + c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_SIZE)); + c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_OWNER)); + c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_GROUP)); + // c.fields.push_back(RequestedField(RequestedField::GROUP_XATTR, L"user.xdg.origin.url")); + } else { + string_t currentGroup; + string_t currentName; + std::vector currentAliases; + std::map currentOptions; + + for (int i = 0; i < arguments.size();) { + string_t option = readNext(arguments, i); + + if (option == CLIParser::OPTION_FILE || option == CLIParser::OPTION_XATTR) { + addField(c, currentGroup, currentName, currentAliases, currentOptions); // previous field + currentGroup = option.substr(2); // cut off -- + currentName = readNext(arguments, i); + } else if (option == OPTION_AS) { + currentAliases.push_back(readNext(arguments, i)); + } else if (option == OPTION_OPTION) { + string_t key = readNext(arguments, i); + string_t value = readNext(arguments, i); + currentOptions[key] = value; + } else { + throw relpipe::cli::RelpipeCLIException(L"Unsupported CLI option: " + option, relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS); + } + } + + addField(c, currentGroup, currentName, currentAliases, currentOptions); // last field + } return c; } @@ -55,6 +106,11 @@ } }; +const string_t CLIParser::OPTION_FILE = L"--" + RequestedField::GROUP_FILE; +const string_t CLIParser::OPTION_XATTR = L"--" + RequestedField::GROUP_XATTR; +const string_t CLIParser::OPTION_AS = L"--as"; +const string_t CLIParser::OPTION_OPTION = L"--option"; + } } } diff -r b4f29fb16159 -r 3e1608320b6c src/relpipe-in-filesystem.cpp --- a/src/relpipe-in-filesystem.cpp Wed Jan 16 19:31:37 2019 +0100 +++ b/src/relpipe-in-filesystem.cpp Thu Jan 17 13:14:37 2019 +0100 @@ -28,6 +28,7 @@ #include #include +#include #include "FilesystemCommand.h" #include "CLIParser.h" @@ -53,6 +54,10 @@ fwprintf(stderr, L"Caught Writer exception: %ls\n", e.getMessge().c_str()); fwprintf(stderr, L"Debug: Input stream: eof=%ls, lastRead=%d\n", (cin.eof() ? L"true" : L"false"), cin.gcount()); resultCode = CLI::EXIT_CODE_DATA_ERROR; + } catch (RelpipeCLIException e) { + fwprintf(stderr, L"Caught CLI exception: %ls\n", e.getMessge().c_str()); + fwprintf(stderr, L"Debug: Input stream: eof=%ls, lastRead=%d\n", (cin.eof() ? L"true" : L"false"), cin.gcount()); + resultCode = e.getExitCode(); } return resultCode;