bool Config::ParseCliArgs()

in source/config/Config.cpp [1385:1503]


bool Config::ParseCliArgs(int argc, char **argv, CliArgs &cliArgs)
{
    struct ArgumentDefinition
    {
        string cliFlag;     // Cli flag to look for
        bool additionalArg; // Does this take an addition argument?
        bool stopIfFound;   // Should we stop processing more arguments if this is found?
        std::function<void(const string &additionalArg)> extraSteps; // Function to call if this is found
    };
    ArgumentDefinition argumentDefinitions[] = {
        {CLI_HELP, false, true, [](const string &additionalArg) { PrintHelpMessage(); }},
        {CLI_EXPORT_DEFAULT_SETTINGS,
         true,
         true,
         [](const string &additionalArg) { ExportDefaultSetting(additionalArg); }},
        {CLI_CONFIG_FILE, true, false, nullptr},

        {PlainConfig::CLI_ENDPOINT, true, false, nullptr},
        {PlainConfig::CLI_CERT, true, false, nullptr},
        {PlainConfig::CLI_KEY, true, false, nullptr},
        {PlainConfig::CLI_ROOT_CA, true, false, nullptr},
        {PlainConfig::CLI_THING_NAME, true, false, nullptr},

        {PlainConfig::LogConfig::CLI_LOG_LEVEL, true, false, nullptr},
        {PlainConfig::LogConfig::CLI_LOG_TYPE, true, false, nullptr},
        {PlainConfig::LogConfig::CLI_LOG_FILE, true, false, nullptr},
        {PlainConfig::LogConfig::CLI_ENABLE_SDK_LOGGING, false, false, nullptr},
        {PlainConfig::LogConfig::CLI_SDK_LOG_LEVEL, true, false, nullptr},
        {PlainConfig::LogConfig::CLI_SDK_LOG_FILE, true, false, nullptr},

        {PlainConfig::Jobs::CLI_ENABLE_JOBS, true, false, nullptr},
        {PlainConfig::Jobs::CLI_HANDLER_DIR, true, false, nullptr},

        {PlainConfig::Tunneling::CLI_ENABLE_TUNNELING, true, false, nullptr},
        {PlainConfig::Tunneling::CLI_TUNNELING_REGION, true, false, nullptr},
        {PlainConfig::Tunneling::CLI_TUNNELING_SERVICE, true, false, nullptr},
        {PlainConfig::Tunneling::CLI_TUNNELING_DISABLE_NOTIFICATION, false, false, nullptr},

        {PlainConfig::DeviceDefender::CLI_ENABLE_DEVICE_DEFENDER, true, false, nullptr},
        {PlainConfig::DeviceDefender::CLI_DEVICE_DEFENDER_INTERVAL, true, false, nullptr},

        {PlainConfig::FleetProvisioning::CLI_ENABLE_FLEET_PROVISIONING, true, false, nullptr},
        {PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_TEMPLATE_NAME, true, false, nullptr},
        {PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_TEMPLATE_PARAMETERS, true, false, nullptr},
        {PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_CSR_FILE, true, false, nullptr},
        {PlainConfig::FleetProvisioning::CLI_FLEET_PROVISIONING_DEVICE_KEY, true, false, nullptr},

        {PlainConfig::PubSub::CLI_ENABLE_PUB_SUB, true, false, nullptr},
        {PlainConfig::PubSub::CLI_PUB_SUB_PUBLISH_TOPIC, true, false, nullptr},
        {PlainConfig::PubSub::CLI_PUB_SUB_PUBLISH_FILE, true, false, nullptr},
        {PlainConfig::PubSub::CLI_PUB_SUB_SUBSCRIBE_TOPIC, true, false, nullptr},
        {PlainConfig::PubSub::CLI_PUB_SUB_SUBSCRIBE_FILE, true, false, nullptr},

        {PlainConfig::SampleShadow::CLI_ENABLE_SAMPLE_SHADOW, true, false, nullptr},
        {PlainConfig::SampleShadow::CLI_SAMPLE_SHADOW_NAME, true, false, nullptr},
        {PlainConfig::SampleShadow::CLI_SAMPLE_SHADOW_INPUT_FILE, true, false, nullptr},
        {PlainConfig::SampleShadow::CLI_SAMPLE_SHADOW_OUTPUT_FILE, true, false, nullptr},

        {PlainConfig::ConfigShadow::CLI_ENABLE_CONFIG_SHADOW, true, false, nullptr}};

    map<string, ArgumentDefinition> argumentDefinitionMap;
    for (auto &i : argumentDefinitions)
    {
        argumentDefinitionMap[i.cliFlag] = i;
    }
    cliArgs.clear();
    for (int i = 1; i < argc; i++)
    {
        std::string currentArg = argv[i];
        auto search = argumentDefinitionMap.find(currentArg);
        if (search == argumentDefinitionMap.end())
        {
            LOGM_ERROR(
                TAG,
                "*** %s: Unrecognised command line argument: %s ***",
                DeviceClient::DC_FATAL_ERROR,
                Sanitize(currentArg).c_str());
            return false;
        }

        if (cliArgs.find(currentArg) != cliArgs.end())
        {
            LOGM_ERROR(
                TAG,
                "*** %s: Command Line argument '%s' cannot be specified more than once ***",
                DeviceClient::DC_FATAL_ERROR,
                Sanitize(currentArg).c_str());
            return false;
        }

        string additionalArg;
        if (search->second.additionalArg)
        {
            if (i + 1 >= argc)
            {
                LOGM_ERROR(
                    TAG,
                    "*** *s: Command Line argument '%s' was passed without specifying addition argument ***",
                    DeviceClient::DC_FATAL_ERROR,
                    Sanitize(currentArg).c_str());
                return false;
            }

            additionalArg = argv[++i];
        }
        cliArgs[currentArg] = additionalArg; // Saving the argument here

        if (search->second.extraSteps)
        {
            search->second.extraSteps(additionalArg);
        }

        if (search->second.stopIfFound)
        {
            return false;
        }
    }
    return true;
}