参数解析代码分析 args.cc

//==========================================================================
//  ARGS.CC - part of
//                     OMNeT++/OMNEST
//             Discrete System Simulation in C++
//
//  Command line argument handling
//
//  Author: Andras Varga
//
//==========================================================================


#include <cstring>
#include <cstdio>
#include "common/opp_ctype.h"
#include "args.h"

using namespace omnetpp::common;

namespace omnetpp {
namespace envir {

ArgList::ArgList()
{
    argc = 0;
    argv = nullptr;
}

// args.parse(argc, argv, "h?f:u:l:c:r:n:p:x:X:q:agGvwsm");
/*
--debug-on-errors=true
--record-eventlog=true
--sim-time-limit=1000s
--**.serviceTime=100ms
*/
void ArgList::parse(int argc, char *argv[], const char *spec)
{
    this->argc = argc;
    this->argv = argv;
    this->spec = spec;

    int i;
    for (i = 1; i < argc; i++) {
        if (strcmp(argv[i], "--") == 0) {
            // 选项停止,直接退出
            i++;
            break;
        }

        // 处理长参数
        if (argv[i][0] == '-' && argv[i][1] == '-') {
            // long option -- treat it liberally for now
            const char *eqpos = strchr(argv[i], '=');
            if (eqpos)
                longOpts[std::string(argv[i]+2, eqpos-argv[i]-2)] = eqpos+1;
            
            // 如果是没有=,则认为是参数名;
            // 最后一个argv,没有设置参数值,则设置为空; 如果不是最后一个,则值设置为下一个argv
            else if (i == argc-1)
                longOpts[argv[i]+2] = "";
            else {
                longOpts[argv[i]+2] = argv[i+1];
                i++;
            }
        }

        // 处理短参数
        else if (argv[i][0] == '-') {
            // short option
            char c = argv[i][1];
            if (!isValidOption(c))
                throw opp_runtime_error("Invalid command-line option %s, try -h for help", argv[i]);

            // 短参数字符对应的数组,
            std::vector<std::string>& v = shortOpts[c];  // get or create map element
            if (hasArg(c)) {

                // 把2个字符后面的作为值存储  -cHello
                if (argv[i][2])
                    v.push_back(argv[i]+2);
                // 如果中间有空格,不是最后一个argv,则把下一个argv作为值 -c hello
                else if (i < argc-1)
                    v.push_back(argv[++i]);

                // 否则,没有值,就不对了
                else if (!hasOptionalArg(c))
                    throw opp_runtime_error("command-line option %s is missing required argument", argv[i]);
            }
            else {
                if (argv[i][2])
                    throw opp_runtime_error("command-line option -%c expects no argument", argv[i][1]);
            }
        }
        else {
            // non-option arg before '--',其他情况,不是--c=1, -c hello这样的
            params.push_back(argv[i]);
        }
    }

    // '--'后面的argv 都写到这个数组里
    for ( ; i < argc; i++) {
        params.push_back(argv[i]);
    }
}

bool ArgList::isValidOption(char c) const
{
    return strchr(spec.c_str(), c) != nullptr;
}

bool ArgList::hasArg(char c) const
{
    const char *p = strchr(spec.c_str(), c);
    return p && (*(p+1) == ':' || *(p+1) == '?');
}

bool ArgList::hasOptionalArg(char c) const
{
    const char *p = strchr(spec.c_str(), c);
    return p && *(p+1) == '?';
}

std::map<std::string, std::string> ArgList::getLongOptions() const
{
    return longOpts;
}

bool ArgList::optionGiven(char c) const
{
    return shortOpts.find(c) != shortOpts.end();
}

const char *ArgList::optionValue(char c, int k) const
{
    if (shortOpts.find(c) == shortOpts.end())
        return nullptr;
    const std::vector<std::string>& v = shortOpts.find(c)->second;
    return (k >= 0 && k < (int)v.size()) ? v[k].c_str() : nullptr;
}

const char *ArgList::argument(int k) const
{
    return (k >= 0 && k < (int)params.size()) ? params[k].c_str() : nullptr;
}

}  // namespace envir
}  // namespace omnetpp

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值