Refactorize command-line & friends 51/33351/4
authorAleksander Zdyb <a.zdyb@samsung.com>
Tue, 13 Jan 2015 08:17:04 +0000 (09:17 +0100)
committerAleksander Zdyb <a.zdyb@samsung.com>
Thu, 15 Jan 2015 10:16:51 +0000 (11:16 +0100)
This refactoring run mostly deals with cumbersome
and redundant command-line options framework.

Change-Id: I62369d9faaf0414314e1ea5e450fac2eb7319534

12 files changed:
src/cyad/CMakeLists.txt
src/cyad/CommandlineParser/CmdlineErrors.cpp [new file with mode: 0644]
src/cyad/CommandlineParser/CmdlineErrors.h [new file with mode: 0644]
src/cyad/CommandlineParser/CmdlineOpts.cpp [new file with mode: 0644]
src/cyad/CommandlineParser/CmdlineOpts.h [new file with mode: 0644]
src/cyad/CommandlineParser/CyadCommandlineParser.cpp
src/cyad/CommandlineParser/CyadCommandlineParser.h
src/cyad/CommandsDispatcher.cpp
src/cyad/CommandsDispatcher.h
test/CMakeLists.txt
test/cyad/commandline_errors.cpp
test/cyad/commandline_options.cpp [new file with mode: 0644]

index 4990a1b..1415f6d 100644 (file)
@@ -23,6 +23,8 @@ SET(CYAD_SOURCES
     ${CYAD_PATH}/AdminPolicyParser.cpp
     ${CYAD_PATH}/Cyad.cpp
     ${CYAD_PATH}/CynaraAdminPolicies.cpp
+    ${CYAD_PATH}/CommandlineParser/CmdlineErrors.cpp
+    ${CYAD_PATH}/CommandlineParser/CmdlineOpts.cpp
     ${CYAD_PATH}/CommandlineParser/CyadCommand.cpp
     ${CYAD_PATH}/CommandlineParser/CyadCommandlineParser.cpp
     ${CYAD_PATH}/CommandlineParser/HumanReadableParser.cpp
diff --git a/src/cyad/CommandlineParser/CmdlineErrors.cpp b/src/cyad/CommandlineParser/CmdlineErrors.cpp
new file mode 100644 (file)
index 0000000..f5c12d6
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file        src/cyad/CommandlineParser/CommandlineErrors.cpp
+ * @author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * @version     1.0
+ * @brief       Command-line error messages
+ */
+
+#include <cyad/CommandlineParser/CmdlineOpts.h>
+#include "CmdlineErrors.h"
+
+namespace Cynara {
+
+namespace CmdlineErrors {
+
+std::string inOption(CmdlineOpts::CmdlineOpt option, const std::string &prefix) {
+    const auto &opt = CmdlineOpts::commandlineOptions.at(option);
+    return prefix + " in --" + opt.longOption + " (-" + opt.shortOption + ")";
+}
+
+std::string unknownError(void) {
+    return "Unknown error";
+};
+
+std::string noOption(void) {
+    return "No option specified";
+};
+
+std::string unknownOption(void) {
+    return "Unknown option";
+};
+
+std::string unknownOption(CmdlineOpts::CmdlineOpt option) {
+    return inOption(option, "Unknown option");
+};
+
+std::string noType(void) {
+    return "No --policy specified";
+};
+
+std::string noBucket(void) {
+    return "No bucket specified";
+};
+
+std::string invalidType(void) {
+    return "Invalid --policy option";
+};
+
+std::string optionMissing(CmdlineOpts::CmdlineOpt option) {
+    return inOption(option, "One or more option missing");
+};
+
+std::string argumentMissing(CmdlineOpts::CmdlineOpt option) {
+    return inOption(option, "One or more argument missing");
+};
+
+} /* namespace CmdlineErrors */
+
+} /* namespace Cynara */
diff --git a/src/cyad/CommandlineParser/CmdlineErrors.h b/src/cyad/CommandlineParser/CmdlineErrors.h
new file mode 100644 (file)
index 0000000..e5c1da9
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file        src/cyad/CommandlineParser/CmdlineErrors.h
+ * @author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * @version     1.0
+ * @brief       Command-line error messages
+ */
+
+#ifndef SRC_CYAD_COMMANDLINEPARSER_CMDLINEERRORS_H_
+#define SRC_CYAD_COMMANDLINEPARSER_CMDLINEERRORS_H_
+
+#include <string>
+
+#include <cyad/CommandlineParser/CmdlineOpts.h>
+
+namespace Cynara {
+
+namespace CmdlineErrors {
+
+std::string unknownError(void);
+std::string noOption(void);
+std::string unknownOption(void);
+std::string unknownOption(CmdlineOpts::CmdlineOpt option);
+std::string noType(void);
+std::string noBucket(void);
+std::string invalidType(void);
+std::string optionMissing(CmdlineOpts::CmdlineOpt option);
+std::string argumentMissing(CmdlineOpts::CmdlineOpt option);
+
+} /* namespace CmdlineErrors */
+
+} /* namespace Cynara */
+
+#endif /* SRC_CYAD_COMMANDLINEPARSER_CMDLINEERRORS_H_ */
diff --git a/src/cyad/CommandlineParser/CmdlineOpts.cpp b/src/cyad/CommandlineParser/CmdlineOpts.cpp
new file mode 100644 (file)
index 0000000..1e8f2bc
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file        src/cyad/CommandlineParser/CmdlineOpts.cpp
+ * @author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * @version     1.0
+ * @brief       Command-line structs and helpers
+ */
+
+#include <cassert>
+#include <sstream>
+
+#include "CmdlineOpts.h"
+
+namespace Cynara {
+
+namespace CmdlineOpts {
+
+const OptionsMap commandlineOptions = {
+    { CmdlineOpt::SetBucket,
+        { "set-bucket", CmdlineOpt::SetBucket, "set-bucket=<name>",
+           "name of bucket to add or alter", OptHasArg::RequiredArgument } },
+    { CmdlineOpt::DeleteBucket,
+        { "delete-bucket", CmdlineOpt::DeleteBucket, "delete-bucket=<name>",
+          "name of bucket to delete", OptHasArg::RequiredArgument } },
+    { CmdlineOpt::SetPolicy,
+        { "set-policy", CmdlineOpt::SetPolicy, "",
+          "", OptHasArg::NoArgument } },
+    { CmdlineOpt::Erase,
+        { "erase", CmdlineOpt::Erase, "erase=<name>",
+          "name of bucket to erase policies from", OptHasArg::RequiredArgument } },
+    { CmdlineOpt::Check,
+        { "check", CmdlineOpt::Check, "check",
+          "", OptHasArg::NoArgument } },
+
+    { CmdlineOpt::Type,
+        { "type", CmdlineOpt::Type, "type=<type>",
+          "policy type", OptHasArg::RequiredArgument } },
+    { CmdlineOpt::Metadata,
+        { "metadata", CmdlineOpt::Metadata, "metadata=<metadata>",
+          "metadata for policy", OptHasArg::RequiredArgument } },
+
+    { CmdlineOpt::Client,
+        { "client", CmdlineOpt::Client, "client=<client>",
+          "client value", OptHasArg::RequiredArgument } },
+    { CmdlineOpt::User,
+        { "user", CmdlineOpt::User, "user=<user>",
+          "user value", OptHasArg::RequiredArgument } },
+    { CmdlineOpt::Privilege,
+        { "privilege", CmdlineOpt::Privilege, "privilege=<privilege>",
+          "privilege value", OptHasArg::RequiredArgument } },
+
+    { CmdlineOpt::Bulk,
+        { "bulk", CmdlineOpt::Bulk, "bulk=<filename>",
+          "path or - for stdin", OptHasArg::RequiredArgument } },
+
+    { CmdlineOpt::Bucket,
+        { "bucket", CmdlineOpt::Bucket, "bucket=<name>",
+          "name of bucket; omit for default", OptHasArg::RequiredArgument } },
+    { CmdlineOpt::Recursive,
+        { "recursive", CmdlineOpt::Recursive, "recursive=<yes|no>",
+          "if linked buckets should be processed as well", OptHasArg::RequiredArgument } },
+
+    { CmdlineOpt::Help,
+        { "help", CmdlineOpt::Help, "help",
+          "print help message", OptHasArg::NoArgument } }
+};
+
+std::vector<option> makeLongOptions(const std::vector<CmdlineOpt> &opts) {
+    std::vector<option> options;
+    for (const auto &opt : opts) {
+        const auto &o = commandlineOptions.at(opt);
+        options.push_back({ o.longOption, o.hasArg, nullptr, static_cast<int>(opt) });
+    }
+
+    options.push_back({ nullptr, 0, nullptr, 0 });
+    return options;
+}
+
+std::string makeShortOptions(const std::vector<CmdlineOpt> &opts) {
+    std::stringstream optstr;
+    optstr << ":";
+
+    for (const auto &opt : opts) {
+        const auto &o = commandlineOptions.at(opt);
+        optstr << o.shortOption;
+
+        if (o.hasArg == OptHasArg::RequiredArgument)
+            optstr << ":";
+    }
+
+    return optstr.str();
+}
+
+std::string makeHelp(void) {
+
+    std::size_t optWidth = 33;
+
+    auto head = [] (const std::string &header, CmdlineOpt opt) -> std::string {
+        return header + " (with -" + commandlineOptions.at(opt).shortOption
+                      + " or --" + commandlineOptions.at(opt).longOption + ")";
+    };
+
+    auto opt = [&optWidth] (CmdlineOpt opt) -> std::string {
+        auto prefix = std::string("  -") + commandlineOptions.at(opt).shortOption
+                    + ", --" + commandlineOptions.at(opt).helpArgument;
+        auto spaceLen = optWidth > prefix.length() ? optWidth - prefix.length() : 1;
+        return prefix + std::string(spaceLen, ' ')
+                      + commandlineOptions.at(opt).helpDescription;
+    };
+
+    std::stringstream helpStr;
+
+    helpStr << "Usage: cyad [OPTIONS]" << std::endl << std::endl;
+
+    helpStr << head("Bucket set options", CmdlineOpt::SetBucket) << std::endl;
+    helpStr << opt(CmdlineOpt::SetBucket) << std::endl;
+    helpStr << opt(CmdlineOpt::Type) << std::endl;
+    helpStr << opt(CmdlineOpt::Metadata) << std::endl;
+    helpStr << std::endl;
+
+    helpStr << head("Bucket delete options", CmdlineOpt::DeleteBucket) << std::endl;
+    helpStr << opt(CmdlineOpt::DeleteBucket) << std::endl;
+    helpStr << std::endl;
+
+    helpStr << head("Policy set options", CmdlineOpt::SetPolicy) << std::endl;
+    helpStr << opt(CmdlineOpt::Bucket) << std::endl;
+    helpStr << opt(CmdlineOpt::Client) << std::endl;
+    helpStr << opt(CmdlineOpt::User) << std::endl;
+    helpStr << opt(CmdlineOpt::Privilege) << std::endl;
+    helpStr << opt(CmdlineOpt::Type) << std::endl;
+    helpStr << opt(CmdlineOpt::Metadata) << std::endl;
+    helpStr << opt(CmdlineOpt::Bulk) << std::endl;
+    helpStr << std::endl;
+
+    helpStr << head("Policy erase options", CmdlineOpt::Erase) << std::endl;
+    helpStr << opt(CmdlineOpt::Erase) << std::endl;
+    helpStr << opt(CmdlineOpt::Recursive) << std::endl;
+    helpStr << opt(CmdlineOpt::Client) << std::endl;
+    helpStr << opt(CmdlineOpt::User) << std::endl;
+    helpStr << opt(CmdlineOpt::Privilege) << std::endl;
+    helpStr << std::endl;
+
+    helpStr << head("Administrative policy check options", CmdlineOpt::Check) << std::endl;
+    helpStr << opt(CmdlineOpt::Bucket) << std::endl;
+    helpStr << opt(CmdlineOpt::Recursive) << std::endl;
+    helpStr << opt(CmdlineOpt::Client) << std::endl;
+    helpStr << opt(CmdlineOpt::User) << std::endl;
+    helpStr << opt(CmdlineOpt::Privilege) << std::endl;
+    helpStr << std::endl;
+
+    helpStr << head("Help options", CmdlineOpt::Help) << std::endl;
+    helpStr << opt(CmdlineOpt::Help);
+
+    return helpStr.str();
+}
+
+} /* namespace CmdlineOpts */
+
+} /* namespace Cynara */
diff --git a/src/cyad/CommandlineParser/CmdlineOpts.h b/src/cyad/CommandlineParser/CmdlineOpts.h
new file mode 100644 (file)
index 0000000..63d73b3
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file        src/cyad/CommandlineParser/CmdlineOpts.h
+ * @author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * @version     1.0
+ * @brief       Command-line structs and helpers
+ */
+
+#ifndef SRC_CYAD_COMMANDLINEPARSER_CMDLINEOPTS_H_
+#define SRC_CYAD_COMMANDLINEPARSER_CMDLINEOPTS_H_
+
+#include <functional>
+#include <getopt.h>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace Cynara {
+
+namespace CmdlineOpts {
+
+enum CmdlineOpt {
+    SetBucket = 'b',
+    DeleteBucket = 'd',
+    SetPolicy = 's',
+    Erase = 'e',
+    Check = 'a',
+
+    Type = 't',
+    Metadata = 'm',
+    Client = 'c',
+    User = 'u',
+    Privilege = 'p',
+    Bulk = 'f',
+    Bucket = 'k',
+    Recursive = 'r',
+
+    Help = 'h'
+};
+
+enum OptHasArg {
+    NoArgument = no_argument,
+    RequiredArgument = required_argument
+};
+
+struct CmdlineOptDesc {
+    const char *longOption;
+    char shortOption;
+    const char *helpArgument;
+    const char *helpDescription;
+    OptHasArg hasArg;
+};
+
+typedef std::unordered_map<CmdlineOpt, const CmdlineOptDesc, std::hash<int>> OptionsMap;
+extern const OptionsMap commandlineOptions;
+
+typedef std::vector<option> LongOptions;
+LongOptions makeLongOptions(const std::vector<CmdlineOpt> &opts);
+
+typedef std::string ShortOptions;
+ShortOptions makeShortOptions(const std::vector<CmdlineOpt> &opts);
+
+std::string makeHelp(void);
+
+} /* namespace CmdlineOpts */
+
+} /* namespace Cynara */
+
+#endif /* SRC_CYAD_COMMANDLINEPARSER_CMDLINEOPTS_H_ */
index e7f38f8..8f66ce4 100644 (file)
  * @brief       Commandline parser for Cyad
  */
 
-#include <cstring>
+#include <functional>
 #include <getopt.h>
-#include <map>
+#include <memory>
 #include <sstream>
 #include <string>
+#include <unordered_map>
 
 #include <cynara-admin-types.h>
 
+#include <cyad/CommandlineParser/CmdlineErrors.h>
+#include <cyad/CommandlineParser/CmdlineOpts.h>
 #include <cyad/CommandlineParser/HumanReadableParser.h>
 #include <cyad/CommandlineParser/PolicyParsingException.h>
 
 
 namespace Cynara {
 
-namespace CyadCmdlineArgs {
-    const char HELP = 'h';
-    const char * const HELP_LONG = "help";
-
-    const char SET_BUCKET = 'b';
-    const char * const SET_BUCKET_LONG = "set-bucket";
-
-    const char DELETE_BUCKET = 'd';
-    const char * const DELETE_BUCKET_LONG = "delete-bucket";
-
-    const char TYPE = 't';
-    const char * const TYPE_LONG = "type";
-
-    const char METADATA = 'm';
-    const char * const METADATA_LONG = "metadata";
-
-    const char BUCKET = 'k';
-    const char * const BUCKET_LONG = "bucket";
-
-    const char SET_POLICY = 's';
-    const char * const SET_POLICY_LONG = "set-policy";
-
-    const char CLIENT = 'c';
-    const char * const CLIENT_LONG = "client";
-
-    const char USER = 'u';
-    const char * const USER_LONG = "user";
-
-    const char PRIVILEGE = 'p';
-    const char * const PRIVILEGE_LONG = "privilege";
-
-    const char BULK = 'f';
-    const char * const BULK_LONG = "bulk";
-
-    const char ERASE = 'e';
-    const char * const ERASE_LONG = "erase";
-
-    const char RECURSIVE = 'r';
-    const char * const RECURSIVE_LONG = "recursive";
-
-    const char CHECK = 'a';
-    const char * const CHECK_LONG = "check";
-}
-
-namespace CyadCmdlineErrors {
-    const char * const UNKNOWN_ERROR = "Unknown error";
-    const char * const NO_OPTION = "No option specified";
-    const char * const UNKNOWN_OPTION = "Unknown option";
-    const char * const UNKNOWN_OPTION_SET_BUCKET = "Unknown option in --set-bucket";
-    const char * const UNKNOWN_OPTION_DELETE_BUCKET = "Unknown option in --delete-bucket";
-    const char * const UNKNOWN_OPTION_SET_POLICY = "Unknown option in --set-policy";
-    const char * const UNKNOWN_OPTION_ERASE = "Unknown option in --erase (-e)";
-    const char * const UNKNOWN_OPTION_CHECK = "Unknown option in --check (-a)";
-    const char * const NO_POLICY = "No --policy specified";
-    const char * const NO_BUCKET = "No bucket specified";
-    const char * const INVALID_POLICY = "Invalid --policy option";
-    const char * const OPTION_MISSING_SET_POLICY = "One or more option missing in --set-policy";
-    const char * const ARGUMENT_MISSING_SET_POLICY = "One or more argument missing in --set-policy";
-    const char * const OPTION_MISSING_ERASE = "One or more option missing in --erase (-e)";
-    const char * const ARGUMENT_MISSING_ERASE = "One or more argument missing in --erase (-e)";
-    const char * const OPTION_MISSING_CHECK = "One or more option missing in --check (-a)";
-    const char * const ARGUMENT_MISSING_CHECK = "One or more argument missing in --check (-a)";
-}
-
 CyadCommandlineParser::CyadCommandlineParser(int argc, char * const *argv)
     : m_argc(argc), m_argv(argv) {}
 
 CyadCommandlineParser::~CyadCommandlineParser() {}
 
+static std::shared_ptr<ErrorCyadCommand> sharedError(const std::string &message) {
+    return std::make_shared<ErrorCyadCommand>(message);
+}
+
 std::shared_ptr<CyadCommand> CyadCommandlineParser::parseMain(void) {
-    namespace Args = CyadCmdlineArgs;
-
-    const struct option long_options[] = {
-        { Args::HELP_LONG,          no_argument,       nullptr, Args::HELP },
-        { Args::SET_BUCKET_LONG,    required_argument, nullptr, Args::SET_BUCKET },
-        { Args::DELETE_BUCKET_LONG, required_argument, nullptr, Args::DELETE_BUCKET },
-        { Args::SET_POLICY_LONG,    no_argument,       nullptr, Args::SET_POLICY },
-        { Args::ERASE_LONG,         required_argument, nullptr, Args::ERASE },
-        { Args::CHECK_LONG,         no_argument,       nullptr, Args::CHECK },
-        { nullptr, 0, nullptr, 0 }
+    namespace Opts = CmdlineOpts;
+    namespace Err = CmdlineErrors;
+    using CmdlineOpts::CmdlineOpt;
+
+    std::vector<CmdlineOpt> opts = {
+        CmdlineOpt::Help,
+        CmdlineOpt::SetBucket,
+        CmdlineOpt::DeleteBucket,
+        CmdlineOpt::SetPolicy,
+        CmdlineOpt::Erase,
+        CmdlineOpt::Check
     };
 
+    const auto longOpts = Opts::makeLongOptions(opts);
+    const auto shortOpts = Opts::makeShortOptions(opts);
+
     optind = 0; // On entry to `getopt', zero means this is the first call; initialize.
     int opt;
-    std::stringstream optstr;
-    optstr << ":" << Args::HELP
-           << Args::SET_BUCKET << ":"
-           << Args::DELETE_BUCKET << ":"
-           << Args::SET_POLICY
-           << Args::ERASE << ":"
-           << Args::CHECK;
-
-    while ((opt = getopt_long(m_argc, m_argv, optstr.str().c_str(), long_options, nullptr)) != -1) {
+    while ((opt = getopt_long(m_argc, m_argv, shortOpts.data(), longOpts.data(), nullptr)) != -1) {
         switch (opt) {
-            case Args::HELP:
+            case CmdlineOpt::Help:
                 return std::make_shared<HelpCyadCommand>();
 
-            case Args::SET_BUCKET:
+            case CmdlineOpt::SetBucket:
                 return parseSetBucket(optarg);
 
-            case Args::DELETE_BUCKET:
+            case CmdlineOpt::DeleteBucket:
                 return parseDeleteBucket(optarg);
 
-            case Args::SET_POLICY:
+            case CmdlineOpt::SetPolicy:
                 return parseSetPolicy();
 
-            case Args::ERASE:
+            case CmdlineOpt::Erase:
                 return parseErase(optarg);
 
-            case Args::CHECK:
+            case CmdlineOpt::Check:
                 return parseCheck();
 
             case '?': // Unknown option
-                return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::UNKNOWN_OPTION);
+                return sharedError(Err::unknownOption());
 
             case ':': // Missing argument
                 switch (optopt) {
-                    case Args::SET_BUCKET:
-                    case Args::DELETE_BUCKET:
-                        return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::NO_BUCKET);
+                    case CmdlineOpt::SetBucket:
+                    case CmdlineOpt::DeleteBucket:
+                    case CmdlineOpt::Erase:
+                        return sharedError(Err::noBucket());
                 }
                 // Shall never happen, but let's just make compiler happy.
-                return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::UNKNOWN_ERROR);
+                return sharedError(Err::unknownError());
 
             default:
-                return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::UNKNOWN_OPTION);
+                return sharedError(Err::unknownOption());
         }
     }
 
-    return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::NO_OPTION);
+    return sharedError(Err::noOption());
 }
 
 std::shared_ptr<CyadCommand> CyadCommandlineParser::parseSetBucket(const std::string &bucketId) {
-    namespace Args = CyadCmdlineArgs;
-    namespace Errors = CyadCmdlineErrors;
+    namespace Opts = CmdlineOpts;
+    namespace Err = CmdlineErrors;
+    using CmdlineOpts::CmdlineOpt;
 
-    const struct option long_options[] = {
-        { Args::TYPE_LONG,     required_argument, nullptr, Args::TYPE },
-        { Args::METADATA_LONG, required_argument, nullptr, Args::METADATA },
-        { nullptr, 0, nullptr, 0 }
+    std::vector<CmdlineOpt> opts = {
+        CmdlineOpt::Type,
+        CmdlineOpt::Metadata
     };
 
+    const auto longOpts = Opts::makeLongOptions(opts);
+    const auto shortOpts = Opts::makeShortOptions(opts);
+
     std::string policy;
     std::string metadata;
 
     int opt;
-    std::stringstream optstr;
-    optstr << ":"
-           << Args::TYPE << ":"
-           << Args::METADATA << ":";
-
-    while ((opt = getopt_long(m_argc, m_argv, optstr.str().c_str(), long_options, nullptr)) != -1) {
-        switch(opt) {
-        case Args::TYPE:
-            policy = optarg;
-            break;
-        case Args::METADATA:
-            metadata = optarg;
-            break;
-        default:
-            return std::make_shared<ErrorCyadCommand>(Errors::UNKNOWN_OPTION_SET_BUCKET);
+    while ((opt = getopt_long(m_argc, m_argv, shortOpts.data(), longOpts.data(), nullptr)) != -1) {
+        switch (opt) {
+            case CmdlineOpt::Type:
+                policy = optarg;
+                break;
+            case CmdlineOpt::Metadata:
+                metadata = optarg;
+                break;
+            default:
+                return sharedError(Err::unknownOption(CmdlineOpt::SetBucket));
         }
     }
 
     if (policy.empty())
-        return std::make_shared<ErrorCyadCommand>(Errors::NO_POLICY);
+        return sharedError(Err::noType());
 
     try {
         auto policyType = HumanReadableParser::policyType(policy);
         return std::make_shared<SetBucketCyadCommand>(bucketId, PolicyResult(policyType, metadata));
     } catch (const PolicyParsingException &) {
-        return std::make_shared<ErrorCyadCommand>(Errors::INVALID_POLICY);
+        return sharedError(Err::invalidType());
     }
 }
 
 std::shared_ptr<CyadCommand> CyadCommandlineParser::parseDeleteBucket(const std::string &bucketId) {
-    namespace Errors = CyadCmdlineErrors;
+    namespace Opts = CmdlineOpts;
+    namespace Err = CmdlineErrors;
+    using CmdlineOpts::CmdlineOpt;
 
     // Expect no additional options
-    const struct option long_options[] = {
-        { nullptr, 0, nullptr, 0 }
-    };
+    std::vector<CmdlineOpt> opts = {};
+    const auto longOpts = Opts::makeLongOptions(opts);
+    const auto shortOpts = Opts::makeShortOptions(opts);
 
-    if (getopt_long(m_argc, m_argv, ":", long_options, nullptr) == -1) {
+    if (getopt_long(m_argc, m_argv, shortOpts.data(), longOpts.data(), nullptr) == -1) {
         return std::make_shared<DeleteBucketCyadCommand>(bucketId);
     } else {
-        return std::make_shared<ErrorCyadCommand>(Errors::UNKNOWN_OPTION_DELETE_BUCKET);
+        return sharedError(Err::unknownOption(CmdlineOpt::DeleteBucket));
     }
 }
 
 std::shared_ptr<CyadCommand> CyadCommandlineParser::parseSetPolicy(void) {
-    namespace Args = CyadCmdlineArgs;
-    namespace Errors = CyadCmdlineErrors;
-
-    const struct option long_options[] = {
-        { Args::CLIENT_LONG,    required_argument, nullptr, Args::CLIENT },
-        { Args::USER_LONG,      required_argument, nullptr, Args::USER },
-        { Args::PRIVILEGE_LONG, required_argument, nullptr, Args::PRIVILEGE },
-        { Args::BUCKET_LONG,    required_argument, nullptr, Args::BUCKET },
-        { Args::TYPE_LONG,      required_argument, nullptr, Args::TYPE },
-        { Args::METADATA_LONG,  required_argument, nullptr, Args::METADATA },
-        { Args::BULK_LONG,      required_argument, nullptr, Args::BULK },
-        { nullptr, 0, nullptr, 0 }
+    namespace Opts = CmdlineOpts;
+    namespace Err = CmdlineErrors;
+    using CmdlineOpts::CmdlineOpt;
+
+    std::vector<CmdlineOpt> opts = {
+        CmdlineOpt::Client,
+        CmdlineOpt::User,
+        CmdlineOpt::Privilege,
+        CmdlineOpt::Bucket,
+        CmdlineOpt::Type,
+        CmdlineOpt::Metadata,
+        CmdlineOpt::Bulk
     };
 
-    typedef std::map<char, std::string> OptionsValues;
-    OptionsValues values = { { Args::CLIENT,    std::string() },
-                             { Args::USER,      std::string() },
-                             { Args::PRIVILEGE, std::string() },
-                             { Args::TYPE,      std::string() } };
+    const auto longOpts = Opts::makeLongOptions(opts);
+    const auto shortOpts = Opts::makeShortOptions(opts);
+
+    typedef std::unordered_map<char, std::string> OptionsValues;
+    OptionsValues values = { { CmdlineOpt::Client,    std::string() },
+                             { CmdlineOpt::User,      std::string() },
+                             { CmdlineOpt::Privilege, std::string() },
+                             { CmdlineOpt::Type,      std::string() } };
 
     std::string metadata;
-    std::string bucket;
+    std::string bucket = CYNARA_ADMIN_DEFAULT_BUCKET;
 
     int opt;
-    std::stringstream optstr;
-    optstr << ":"
-           << Args::CLIENT << ":"
-           << Args::USER << ":"
-           << Args::PRIVILEGE << ":"
-           << Args::BUCKET << ":"
-           << Args::TYPE << ":"
-           << Args::METADATA << ":"
-           << Args::BULK << ":";
-
-    while ((opt = getopt_long(m_argc, m_argv, optstr.str().c_str(), long_options, nullptr)) != -1) {
-        switch(opt) {
-        case Args::CLIENT:
-        case Args::USER:
-        case Args::PRIVILEGE:
-        case Args::TYPE:
-            values[opt] = optarg;
-            break;
-        case Args::BUCKET:
-            bucket = optarg;
-            break;
-        case Args::METADATA:
-            metadata = optarg;
-            break;
-        case Args::BULK:
-            return std::make_shared<SetPolicyBulkCyadCommand>(optarg);
-        case ':': // Missing argument
-            return std::make_shared<ErrorCyadCommand>(Errors::ARGUMENT_MISSING_SET_POLICY);
-        default:
-            return std::make_shared<ErrorCyadCommand>(Errors::UNKNOWN_OPTION_SET_POLICY);
+    while ((opt = getopt_long(m_argc, m_argv, shortOpts.data(), longOpts.data(), nullptr)) != -1) {
+        switch (opt) {
+            case CmdlineOpt::Client:
+            case CmdlineOpt::User:
+            case CmdlineOpt::Privilege:
+            case CmdlineOpt::Type:
+                values[opt] = optarg;
+                break;
+            case CmdlineOpt::Bucket:
+                bucket = optarg;
+                break;
+            case CmdlineOpt::Metadata:
+                metadata = optarg;
+                break;
+            case CmdlineOpt::Bulk:
+                return std::make_shared<SetPolicyBulkCyadCommand>(optarg);
+            case ':': // Missing argument
+                return sharedError(Err::argumentMissing(CmdlineOpt::SetPolicy));
+            default:
+                return sharedError(Err::unknownOption(CmdlineOpt::SetPolicy));
         }
     }
 
     for (const auto &val : values) {
         if (val.second.empty()) {
             // TODO: Identify actual option
-            return std::make_shared<ErrorCyadCommand>(Errors::OPTION_MISSING_SET_POLICY);
+            return sharedError(Err::optionMissing(CmdlineOpt::SetPolicy));
         }
     }
 
     try {
-        auto policyType = HumanReadableParser::policyType(values[Args::TYPE]);
+        auto policyType = HumanReadableParser::policyType(values[CmdlineOpt::Type]);
         auto policyResult = PolicyResult(policyType, metadata);
         return std::make_shared<SetPolicyCyadCommand>(bucket, policyResult,
-                                                      PolicyKey(values[Args::CLIENT],
-                                                                values[Args::USER],
-                                                                values[Args::PRIVILEGE]));
+                                                      PolicyKey(values[CmdlineOpt::Client],
+                                                                values[CmdlineOpt::User],
+                                                                values[CmdlineOpt::Privilege]));
     } catch (const PolicyParsingException &) {
-        return std::make_shared<ErrorCyadCommand>(Errors::INVALID_POLICY);
+        return sharedError(Err::invalidType());
     }
 
-    return std::make_shared<ErrorCyadCommand>(Errors::UNKNOWN_ERROR);
+    return sharedError(Err::unknownError());
 }
 
 std::shared_ptr<CyadCommand> CyadCommandlineParser::parseErase(const std::string &bucketId) {
-    namespace Args = CyadCmdlineArgs;
-    namespace Errors = CyadCmdlineErrors;
-
-    const struct option long_options[] = {
-        { Args::RECURSIVE_LONG, required_argument, nullptr, Args::RECURSIVE },
-        { Args::CLIENT_LONG,    required_argument, nullptr, Args::CLIENT },
-        { Args::USER_LONG,      required_argument, nullptr, Args::USER },
-        { Args::PRIVILEGE_LONG, required_argument, nullptr, Args::PRIVILEGE },
-        { nullptr, 0, nullptr, 0 }
+    namespace Opts = CmdlineOpts;
+    namespace Err = CmdlineErrors;
+    using CmdlineOpts::CmdlineOpt;
+
+    std::vector<CmdlineOpt> opts = {
+        CmdlineOpt::Recursive,
+        CmdlineOpt::Client,
+        CmdlineOpt::User,
+        CmdlineOpt::Privilege
     };
 
-    typedef std::map<char, std::string> OptionsValues;
-    OptionsValues values = { { Args::RECURSIVE, std::string() },
-                             { Args::CLIENT,    std::string() },
-                             { Args::USER,      std::string() },
-                             { Args::PRIVILEGE, std::string() } };
+    const auto longOpts = Opts::makeLongOptions(opts);
+    const auto shortOpts = Opts::makeShortOptions(opts);
+
+    typedef std::unordered_map<char, std::string> OptionsValues;
+    OptionsValues values = { { CmdlineOpt::Recursive, std::string() },
+                             { CmdlineOpt::Client,    std::string() },
+                             { CmdlineOpt::User,      std::string() },
+                             { CmdlineOpt::Privilege, std::string() } };
 
     int opt;
-    std::stringstream optstr;
-    optstr << ":"
-           << Args::RECURSIVE << ":"
-           << Args::CLIENT << ":"
-           << Args::USER << ":"
-           << Args::PRIVILEGE << ":";
-
-    while ((opt = getopt_long(m_argc, m_argv, optstr.str().c_str(), long_options, nullptr)) != -1) {
+    while ((opt = getopt_long(m_argc, m_argv, shortOpts.data(), longOpts.data(), nullptr)) != -1) {
         switch (opt) {
-        case Args::RECURSIVE:
-        case Args::CLIENT:
-        case Args::USER:
-        case Args::PRIVILEGE:
-            values[opt] = optarg;
-            break;
-        case ':': // Missing argument
-            return std::make_shared<ErrorCyadCommand>(Errors::ARGUMENT_MISSING_ERASE);
-        default:
-            return std::make_shared<ErrorCyadCommand>(Errors::UNKNOWN_OPTION_ERASE);
+            case CmdlineOpt::Recursive:
+            case CmdlineOpt::Client:
+            case CmdlineOpt::User:
+            case CmdlineOpt::Privilege:
+                values[opt] = optarg;
+                break;
+            case ':': // Missing argument
+                return sharedError(Err::argumentMissing(CmdlineOpt::Erase));
+            default:
+                return sharedError(Err::unknownOption(CmdlineOpt::Erase));
         }
     }
 
     for (const auto &val : values) {
         if (val.second.empty()) {
             // TODO: Identify actual option
-            return std::make_shared<ErrorCyadCommand>(Errors::OPTION_MISSING_ERASE);
+            return sharedError(Err::optionMissing(CmdlineOpt::Erase));
         }
     }
 
-    auto recursive = HumanReadableParser::isYes(values[Args::RECURSIVE]);
+    auto recursive = HumanReadableParser::isYes(values[CmdlineOpt::Recursive]);
 
 
     return std::make_shared<EraseCyadCommand>(bucketId, recursive,
-                                              PolicyKey(values[Args::CLIENT], values[Args::USER],
-                                                        values[Args::PRIVILEGE]));
+                                              PolicyKey(values[CmdlineOpt::Client],
+                                                        values[CmdlineOpt::User],
+                                                        values[CmdlineOpt::Privilege]));
 }
 
 std::shared_ptr<CyadCommand> CyadCommandlineParser::parseCheck(void) {
-    namespace Args = CyadCmdlineArgs;
-    namespace Errors = CyadCmdlineErrors;
-
-    const struct option long_options[] = {
-        { Args::BUCKET_LONG,    required_argument, nullptr, Args::BUCKET },
-        { Args::RECURSIVE_LONG, required_argument, nullptr, Args::RECURSIVE },
-        { Args::CLIENT_LONG,    required_argument, nullptr, Args::CLIENT },
-        { Args::USER_LONG,      required_argument, nullptr, Args::USER },
-        { Args::PRIVILEGE_LONG, required_argument, nullptr, Args::PRIVILEGE },
-        { nullptr, 0, nullptr, 0 }
+    namespace Opts = CmdlineOpts;
+    namespace Err = CmdlineErrors;
+    using CmdlineOpts::CmdlineOpt;
+
+    std::vector<CmdlineOpt> opts = {
+        CmdlineOpt::Bucket,
+        CmdlineOpt::Recursive,
+        CmdlineOpt::Client,
+        CmdlineOpt::User,
+        CmdlineOpt::Privilege
     };
 
-    typedef std::map<char, std::string> OptionsValues;
-    OptionsValues values = { { Args::RECURSIVE, std::string() },
-                             { Args::CLIENT,    std::string() },
-                             { Args::USER,      std::string() },
-                             { Args::PRIVILEGE, std::string() } };
+    const auto longOpts = Opts::makeLongOptions(opts);
+    const auto shortOpts = Opts::makeShortOptions(opts);
+
+    typedef std::unordered_map<char, std::string> OptionsValues;
+    OptionsValues values = { { CmdlineOpt::Recursive, std::string() },
+                             { CmdlineOpt::Client,    std::string() },
+                             { CmdlineOpt::User,      std::string() },
+                             { CmdlineOpt::Privilege, std::string() } };
 
     std::string bucketId = CYNARA_ADMIN_DEFAULT_BUCKET;
 
     int opt;
-    std::stringstream optstr;
-    optstr << ":"
-           << Args::BUCKET << ":"
-           << Args::RECURSIVE << ":"
-           << Args::CLIENT << ":"
-           << Args::USER << ":"
-           << Args::PRIVILEGE << ":";
-
-    while ((opt = getopt_long(m_argc, m_argv, optstr.str().c_str(), long_options, nullptr)) != -1) {
-        switch(opt) {
-        case Args::RECURSIVE:
-        case Args::CLIENT:
-        case Args::USER:
-        case Args::PRIVILEGE:
-            values[opt] = optarg;
-            break;
-        case Args::BUCKET:
-            bucketId = optarg;
-            break;
-        case ':': // Missing argument
-            return std::make_shared<ErrorCyadCommand>(Errors::ARGUMENT_MISSING_CHECK);
-        default:
-            return std::make_shared<ErrorCyadCommand>(Errors::UNKNOWN_OPTION_CHECK);
+    while ((opt = getopt_long(m_argc, m_argv, shortOpts.data(), longOpts.data(), nullptr)) != -1) {
+        switch (opt) {
+            case CmdlineOpt::Recursive:
+            case CmdlineOpt::Client:
+            case CmdlineOpt::User:
+            case CmdlineOpt::Privilege:
+                values[opt] = optarg;
+                break;
+            case CmdlineOpt::Bucket:
+                bucketId = optarg;
+                break;
+            case ':': // Missing argument
+                return sharedError(Err::argumentMissing(CmdlineOpt::Check));
+            default:
+                return sharedError(Err::unknownOption(CmdlineOpt::Check));
         }
     }
 
     for (const auto &val : values) {
         if (val.second.empty()) {
             // TODO: Identify actual option
-            return std::make_shared<ErrorCyadCommand>(Errors::OPTION_MISSING_CHECK);
+            return sharedError(Err::optionMissing(CmdlineOpt::Check));
         }
     }
 
-    auto recursive = HumanReadableParser::isYes(values[Args::RECURSIVE]);
+    auto recursive = HumanReadableParser::isYes(values[CmdlineOpt::Recursive]);
 
     return std::make_shared<CheckCyadCommand>(bucketId, recursive,
-                                              PolicyKey(values[Args::CLIENT], values[Args::USER],
-                                                        values[Args::PRIVILEGE]));
+                                              PolicyKey(values[CmdlineOpt::Client],
+                                                        values[CmdlineOpt::User],
+                                                        values[CmdlineOpt::Privilege]));
 }
 
 } /* namespace Cynara */
index 54851ef..b29e428 100644 (file)
 #define SRC_CYAD_COMMANDLINEPARSER_CYADCOMMANDLINEPARSER_H_
 
 #include <memory>
+#include <string>
 
 #include <cyad/CommandlineParser/CyadCommand.h>
 
 namespace Cynara {
 
-namespace CyadCmdlineArgs {
-    extern const char HELP;
-    extern const char * const HELP_LONG;
-
-    extern const char SET_BUCKET;
-    extern const char * const SET_BUCKET_LONG;
-
-    extern const char DELETE_BUCKET;
-    extern const char * const DELETE_BUCKET_LONG;
-
-    extern const char TYPE;
-    extern const char * const TYPE_LONG;
-
-    extern const char METADATA;
-    extern const char * const METADATA_LONG;
-
-    extern const char BUCKET;
-    extern const char * const BUCKET_LONG;
-
-    extern const char CLIENT;
-    extern const char * const CLIENT_LONG;
-
-    extern const char USER;
-    extern const char * const USER_LONG;
-
-    extern const char PRIVILEGE;
-    extern const char * const PRIVILEGE_LONG;
-
-    extern const char BULK;
-    extern const char * const BULK_LONG;
-
-    extern const char ERASE;
-    extern const char * const ERASE_LONG;
-
-    extern const char RECURSIVE;
-    extern const char * const RECURSIVE_LONG;
-
-    extern const char CHECK;
-    extern const char * const CHECK_LONG;
-}
-
-namespace CyadCmdlineErrors {
-    extern const char * const UNKNOWN_ERROR;
-    extern const char * const NO_OPTION;
-    extern const char * const UNKNOWN_OPTION;
-    extern const char * const UNKNOWN_OPTION_SET_BUCKET;
-    extern const char * const UNKNOWN_OPTION_DELETE_BUCKET;
-    extern const char * const UNKNOWN_OPTION_SET_POLICY;
-    extern const char * const UNKNOWN_OPTION_ERASE;
-    extern const char * const UNKNOWN_OPTION_CHECK;
-    extern const char * const NO_POLICY;
-    extern const char * const NO_BUCKET;
-    extern const char * const INVALID_POLICY;
-    extern const char * const OPTION_MISSING_SET_POLICY;
-    extern const char * const ARGUMENT_MISSING_SET_POLICY;
-    extern const char * const OPTION_MISSING_ERASE;
-    extern const char * const ARGUMENT_MISSING_ERASE;
-    extern const char * const OPTION_MISSING_CHECK;
-    extern const char * const ARGUMENT_MISSING_CHECK;
-}
-
 class CyadCommandlineParser {
 public:
     CyadCommandlineParser(int argc, char * const *argv);
index 8726915..43abd35 100644 (file)
@@ -26,8 +26,9 @@
 #include <exceptions/BucketRecordCorruptedException.h>
 
 #include <cyad/AdminLibraryInitializationFailedException.h>
-#include <cyad/CynaraAdminPolicies.h>
 #include <cyad/AdminPolicyParser.h>
+#include <cyad/CommandlineParser/CmdlineOpts.h>
+#include <cyad/CynaraAdminPolicies.h>
 
 #include "CommandsDispatcher.h"
 
@@ -51,7 +52,7 @@ int CommandsDispatcher::execute(CyadCommand &) {
 }
 
 int CommandsDispatcher::execute(HelpCyadCommand &) {
-    m_io.cout() << helpMessage << std::endl;
+    m_io.cout() << CmdlineOpts::makeHelp() << std::endl;
     return CYNARA_API_SUCCESS;
 }
 
@@ -59,7 +60,7 @@ int CommandsDispatcher::execute(ErrorCyadCommand &result) {
     m_io.cout() << "There was an error in command-line options:" << std::endl;
     m_io.cout() << result.message() << std::endl;
 
-    m_io.cout() << std::endl << helpMessage << std::endl;
+    m_io.cout() << std::endl << CmdlineOpts::makeHelp() << std::endl;
     return CYNARA_API_INVALID_COMMANDLINE_PARAM;
 }
 
index 02d441e..d680c1d 100644 (file)
@@ -48,46 +48,6 @@ public:
     virtual int execute(CheckCyadCommand &);
 
 private:
-    // TODO: Get argv[0] instead of hardcoded name
-    const std::string helpMessage = "Usage: cyad [OPTIONS]\n\n"
-                                    "Bucket set options (with -b or --set-bucket)\n"
-                                    "  -b, --set-bucket=<name>        name of bucket\n"
-                                    "  -t, --type=<policy>            default policy type\n"
-                                    "  -m, --metadata=<metadata>      metadata for default policy\n"
-                                    "\n"
-                                    "Bucket delete options (with -d or --delete-bucket)\n"
-                                    "  -d, --delete-bucket=<name>     name of bucket to delete\n"
-                                    "\n"
-                                    "Policy set options (with -s or --set-policy)\n"
-                                    "  -k, --bucket=<name>            name of bucket;"
-                                                                     " omit for default\n"
-                                    "  -c, --client=<client>          client value\n"
-                                    "  -u, --user=<user>              user value\n"
-                                    "  -p, --privilege=<privilege>    privilege value\n"
-                                    "  -t, --type=<policy>            policy type\n"
-                                    "  -m, --metadata=<metadata>      metadata for policy\n"
-                                    "  -f, --bulk=<filename>          path or - for stdin\n"
-                                    "\n"
-                                    "Policy erase options (with -e or --erase)\n"
-                                    "  -e, --erase=<name>             name of bucket"
-                                                                     " to start from\n"
-                                    "  -r, --recursive=<yes|no>       if linked buckets should be"
-                                                                     " processed as well\n"
-                                    "  -c, --client=<client>          client value\n"
-                                    "  -u, --user=<user>              user value\n"
-                                    "  -p, --privilege=<privilege>    privilege value\n"
-                                    "\n"
-                                    "Administrative policy check options (with -a or --check)\n"
-                                    "  -k, --bucket=<name>            name of bucket;"
-                                                                     " omit for default\n"
-                                    "  -r, --recursive=<yes|no>       if linked buckets should be"
-                                                                     " processed as well\n"
-                                    "  -c, --client=<client>          client value\n"
-                                    "  -u, --user=<user>              user value\n"
-                                    "  -p, --privilege=<privilege>    privilege value\n"
-                                    "\n"
-                                    "Help options:\n"
-                                    "  -h, --help                     print help message";
     BaseDispatcherIO &m_io;
     BaseAdminApiWrapper &m_adminApiWrapper;
     struct cynara_admin *m_cynaraAdmin;
index 3c9ad60..b7a1c2f 100644 (file)
@@ -49,6 +49,8 @@ SET(CYNARA_SOURCES_FOR_TESTS
     ${CYNARA_SRC}/common/types/PolicyResult.cpp
     ${CYNARA_SRC}/common/types/PolicyType.cpp
     ${CYNARA_SRC}/cyad/AdminPolicyParser.cpp
+    ${CYNARA_SRC}/cyad/CommandlineParser/CmdlineErrors.cpp
+    ${CYNARA_SRC}/cyad/CommandlineParser/CmdlineOpts.cpp
     ${CYNARA_SRC}/cyad/CommandlineParser/CyadCommand.cpp
     ${CYNARA_SRC}/cyad/CommandlineParser/CyadCommandlineParser.cpp
     ${CYNARA_SRC}/cyad/CommandlineParser/HumanReadableParser.cpp
index c541187..049851a 100644 (file)
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
+#include <cyad/CommandlineParser/CmdlineErrors.h>
+#include <cyad/CommandlineParser/CmdlineOpts.h>
 #include <cyad/CommandlineParser/CyadCommand.h>
 #include <cyad/CommandlineParser/CyadCommandlineParser.h>
 
 #include "CyadCommandlineTest.h"
 
+namespace Errors = Cynara::CmdlineErrors;
+using Cynara::CmdlineOpts::CmdlineOpt;
+
 #define ASSERT_ERROR_MSG(msg,rawResult) { \
     auto result = std::dynamic_pointer_cast<Cynara::ErrorCyadCommand>(rawResult); \
     ASSERT_NE(nullptr, result); \
 TEST_F(CyadCommandlineTest, noOption) {
     prepare_argv({ "./cyad" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::NO_OPTION, parser.parseMain());
+    ASSERT_ERROR_MSG(Errors::noOption(), parser.parseMain());
 }
 
 TEST_F(CyadCommandlineTest, unknownOption) {
     prepare_argv({ "./cyad", "--unknown-option" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::UNKNOWN_OPTION, parser.parseMain());
+    ASSERT_ERROR_MSG(Errors::unknownOption(), parser.parseMain());
 }
 
 TEST_F(CyadCommandlineTest, deleteBucketNoBucket) {
     prepare_argv({ "./cyad", "--delete-bucket" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::NO_BUCKET, parser.parseMain());
+    ASSERT_ERROR_MSG(Errors::noBucket(), parser.parseMain());
 }
 
 TEST_F(CyadCommandlineTest, deleteBucketUnknownOption) {
     prepare_argv({ "./cyad", "--delete-bucket=bucket", "--unknown" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::UNKNOWN_OPTION_DELETE_BUCKET, parser.parseMain());
+    ASSERT_ERROR_MSG(Errors::unknownOption(CmdlineOpt::DeleteBucket), parser.parseMain());
 }
 
 TEST_F(CyadCommandlineTest, setBucketNoBucket) {
     prepare_argv({ "./cyad", "--set-bucket" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::NO_BUCKET, parser.parseMain());
+    ASSERT_ERROR_MSG(Errors::noBucket(), parser.parseMain());
 }
 
 TEST_F(CyadCommandlineTest, setBucketNoPolicy) {
     prepare_argv({ "./cyad", "--set-bucket=bucket" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::NO_POLICY, parser.parseMain());
+    ASSERT_ERROR_MSG(Cynara::CmdlineErrors::noType(), parser.parseMain());
 }
 
 TEST_F(CyadCommandlineTest, setBucketInvalidPolicy) {
     prepare_argv({ "./cyad", "--set-bucket=bucket", "--type=NaN" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::INVALID_POLICY, parser.parseMain());
+    ASSERT_ERROR_MSG(Errors::invalidType(), parser.parseMain());
 }
 
 TEST_F(CyadCommandlineTest, setBucketUnknownOption) {
     prepare_argv({ "./cyad", "--set-bucket=bucket", "--unknown", "--type=42" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::UNKNOWN_OPTION_SET_BUCKET, parser.parseMain());
+    ASSERT_ERROR_MSG(Errors::unknownOption(CmdlineOpt::SetBucket), parser.parseMain());
 }
 
 TEST_F(CyadCommandlineTest, setBucketMetadataNoPolicy) {
     prepare_argv({ "./cyad", "--set-bucket=bucket", "--metadata=some-meta" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::NO_POLICY, parser.parseMain());
+    ASSERT_ERROR_MSG(Errors::noType(), parser.parseMain());
 }
 
 TEST_F(CyadCommandlineTest, setPolicyNoOption) {
     prepare_argv({ "./cyad", "--set-policy" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::OPTION_MISSING_SET_POLICY, parser.parseMain());
+    ASSERT_ERROR_MSG(Errors::optionMissing(CmdlineOpt::SetPolicy), parser.parseMain());
 }
 
 TEST_F(CyadCommandlineTest, setPolicyUnknownOption) {
     prepare_argv({ "./cyad", "--set-policy", "--unknown-option" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::UNKNOWN_OPTION_SET_POLICY, parser.parseMain());
+    ASSERT_ERROR_MSG(Errors::unknownOption(CmdlineOpt::SetPolicy), parser.parseMain());
 }
 
 TEST_F(CyadCommandlineTest, setPolicyArgumentMissing) {
     prepare_argv({ "./cyad", "--set-policy", "--bucket" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::ARGUMENT_MISSING_SET_POLICY, parser.parseMain());
+    ASSERT_ERROR_MSG(Errors::argumentMissing(CmdlineOpt::SetPolicy), parser.parseMain());
 }
 
 TEST_F(CyadCommandlineTest, setPolicyNoPolicy) {
@@ -114,12 +119,12 @@ TEST_F(CyadCommandlineTest, setPolicyNoPolicy) {
     prepare_argv({ "./cyad", "--set-policy", "--bucket=some-bucket",
                    "--client=client", "--user=user", "--privilege=privilege" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::OPTION_MISSING_SET_POLICY, parser.parseMain());
+    ASSERT_ERROR_MSG(Errors::optionMissing(CmdlineOpt::SetPolicy), parser.parseMain());
 }
 
 TEST_F(CyadCommandlineTest, eraseNoRecursive) {
     prepare_argv({ "./cyad", "--erase=",
                    "--client=client", "--user=user", "--privilege=privilege" });
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
-    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::OPTION_MISSING_ERASE, parser.parseMain());
+    ASSERT_ERROR_MSG(Errors::optionMissing(CmdlineOpt::Erase), parser.parseMain());
 }
diff --git a/test/cyad/commandline_options.cpp b/test/cyad/commandline_options.cpp
new file mode 100644 (file)
index 0000000..42f893a
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+/**
+ * @file        test/cyad/commandline_options.cpp
+ * @author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * @version     1.0
+ * @brief       Tests for command-line options
+ */
+
+#include <cyad/CommandlineParser/CmdlineOpts.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+
+TEST(CommandlineOptions, allOptionsPresent) {
+    using Cynara::CmdlineOpts::CmdlineOpt;
+    using Cynara::CmdlineOpts::commandlineOptions;
+
+    // A cheap trick to make sure this test is updated, when new options are added
+    ASSERT_EQ(14, commandlineOptions.size());
+
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::SetBucket));
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::DeleteBucket));
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::SetPolicy));
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::Erase));
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::Check));
+
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::Type));
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::Metadata));
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::Client));
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::User));
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::Privilege));
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::Bulk));
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::Bucket));
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::Recursive));
+
+    ASSERT_NO_THROW(commandlineOptions.at(CmdlineOpt::Help));
+}
+
+
+void ASSERT_OPTS_END_WITH_NULL(const std::vector<option> &opts) {
+    const auto &lastOpt = opts.end() - 1;
+    ASSERT_EQ(nullptr, lastOpt->name);
+    ASSERT_EQ(0, lastOpt->has_arg);
+    ASSERT_EQ(nullptr, lastOpt->flag);
+    ASSERT_EQ(0, lastOpt->val);
+}
+
+TEST(CommandlineOptions, makeOptionsNone) {
+    const auto opts = Cynara::CmdlineOpts::makeLongOptions({});
+    ASSERT_OPTS_END_WITH_NULL(opts);
+}
+
+TEST(CommandlineOptions, makeOptionsOne) {
+    using Cynara::CmdlineOpts::CmdlineOpt;
+    using Cynara::CmdlineOpts::commandlineOptions;
+
+    const auto opts = Cynara::CmdlineOpts::makeLongOptions({ CmdlineOpt::Help });
+
+    ASSERT_OPTS_END_WITH_NULL(opts);
+    ASSERT_STREQ(commandlineOptions.at(CmdlineOpt::Help).longOption, opts.at(0).name);
+}
+
+TEST(CommandlineOptions, makeOptionsMore) {
+    using Cynara::CmdlineOpts::CmdlineOpt;
+    using Cynara::CmdlineOpts::commandlineOptions;
+
+    const auto opts = Cynara::CmdlineOpts::makeLongOptions({ CmdlineOpt::Help,
+                                                             CmdlineOpt::SetPolicy });
+
+    ASSERT_OPTS_END_WITH_NULL(opts);
+    ASSERT_STREQ(commandlineOptions.at(CmdlineOpt::Help).longOption, opts.at(0).name);
+    ASSERT_STREQ(commandlineOptions.at(CmdlineOpt::SetPolicy).longOption, opts.at(1).name);
+}