src/CLIParser.h
branchv_0
changeset 10 3e1608320b6c
parent 7 8d73bff730a7
child 12 0a297eb46ba1
equal deleted inserted replaced
9:b4f29fb16159 10:3e1608320b6c
    18 #pragma once
    18 #pragma once
    19 
    19 
    20 #include <vector>
    20 #include <vector>
    21 
    21 
    22 #include <relpipe/writer/typedefs.h>
    22 #include <relpipe/writer/typedefs.h>
       
    23 #include <relpipe/cli/CLI.h>
       
    24 #include <relpipe/cli/RelpipeCLIException.h>
    23 
    25 
    24 #include "Configuration.h"
    26 #include "Configuration.h"
    25 #include "FileAttributeFinder.h"
    27 #include "FileAttributeFinder.h"
    26 
    28 
    27 namespace relpipe {
    29 namespace relpipe {
    29 namespace filesystem {
    31 namespace filesystem {
    30 
    32 
    31 using namespace relpipe::writer;
    33 using namespace relpipe::writer;
    32 
    34 
    33 class CLIParser {
    35 class CLIParser {
       
    36 private:
       
    37 
       
    38 	string_t readNext(std::vector<string_t> arguments, int& i) {
       
    39 		if (i < arguments.size()) return arguments[i++];
       
    40 		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);
       
    41 	}
       
    42 
       
    43 	void addField(Configuration& c, string_t& group, string_t& name, std::vector<string_t>& aliases, std::map<string_t, string_t>& options) {
       
    44 		if (group.size()) {
       
    45 			c.fields.push_back(RequestedField(group, name, aliases, options));
       
    46 			group.clear();
       
    47 			name.clear();
       
    48 			aliases.clear();
       
    49 			options.clear();
       
    50 		}
       
    51 	}
       
    52 
    34 public:
    53 public:
       
    54 
       
    55 	static const string_t OPTION_FILE;
       
    56 	static const string_t OPTION_XATTR;
       
    57 	static const string_t OPTION_AS;
       
    58 	static const string_t OPTION_OPTION;
    35 
    59 
    36 	Configuration parse(const std::vector<string_t>& arguments) {
    60 	Configuration parse(const std::vector<string_t>& arguments) {
    37 		Configuration c;
    61 		Configuration c;
    38 		// TODO: parse arguments
    62 		if (arguments.empty()) {
    39 		c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_PATH_ORIGINAL));
    63 			// default set of fields:
    40 		// c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_PATH_ABSOLUTE));
    64 			c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_PATH_ORIGINAL));
    41 		// c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_PATH_CANONICAL));
    65 			// c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_PATH_ABSOLUTE));
    42 		// c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_NAME));
    66 			// c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_PATH_CANONICAL));
    43 		c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_TYPE));
    67 			// c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_NAME));
    44 		// c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_TYPE,{L"type_a", L"type_b"}));
    68 			c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_TYPE));
    45 		c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_SYMLINK_TARGET_TYPE));
    69 			// c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_TYPE,{L"type_a", L"type_b"})); // one field → two attributes with same value
    46 		// c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_SYMLINK_TARGET));
    70 			// c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_SYMLINK_TARGET_TYPE));
    47 		c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_SIZE));
    71 			// c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_SYMLINK_TARGET));
    48 		c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_OWNER));
    72 			c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_SIZE));
    49 		c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_GROUP));
    73 			c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_OWNER));
    50 		c.fields.push_back(RequestedField(RequestedField::GROUP_XATTR, L"user.xdg.origin.url"));
    74 			c.fields.push_back(RequestedField(RequestedField::GROUP_FILE, FileAttributeFinder::FIELD_GROUP));
       
    75 			// c.fields.push_back(RequestedField(RequestedField::GROUP_XATTR, L"user.xdg.origin.url"));
       
    76 		} else {
       
    77 			string_t currentGroup;
       
    78 			string_t currentName;
       
    79 			std::vector<string_t> currentAliases;
       
    80 			std::map<string_t, string_t> currentOptions;
       
    81 
       
    82 			for (int i = 0; i < arguments.size();) {
       
    83 				string_t option = readNext(arguments, i);
       
    84 
       
    85 				if (option == CLIParser::OPTION_FILE || option == CLIParser::OPTION_XATTR) {
       
    86 					addField(c, currentGroup, currentName, currentAliases, currentOptions); // previous field
       
    87 					currentGroup = option.substr(2); // cut off --
       
    88 					currentName = readNext(arguments, i);
       
    89 				} else if (option == OPTION_AS) {
       
    90 					currentAliases.push_back(readNext(arguments, i));
       
    91 				} else if (option == OPTION_OPTION) {
       
    92 					string_t key = readNext(arguments, i);
       
    93 					string_t value = readNext(arguments, i);
       
    94 					currentOptions[key] = value;
       
    95 				} else {
       
    96 					throw relpipe::cli::RelpipeCLIException(L"Unsupported CLI option: " + option, relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
       
    97 				}
       
    98 			}
       
    99 			
       
   100 			addField(c, currentGroup, currentName, currentAliases, currentOptions); // last field
       
   101 		}
    51 		return c;
   102 		return c;
    52 	}
   103 	}
    53 
   104 
    54 	virtual ~CLIParser() {
   105 	virtual ~CLIParser() {
    55 	}
   106 	}
    56 };
   107 };
    57 
   108 
       
   109 const string_t CLIParser::OPTION_FILE = L"--" + RequestedField::GROUP_FILE;
       
   110 const string_t CLIParser::OPTION_XATTR = L"--" + RequestedField::GROUP_XATTR;
       
   111 const string_t CLIParser::OPTION_AS = L"--as";
       
   112 const string_t CLIParser::OPTION_OPTION = L"--option";
       
   113 
    58 }
   114 }
    59 }
   115 }
    60 }
   116 }