Project

General

Profile

Statistics
| Branch: | Revision:

root / src / envir / args.cc @ a3be1d55

History | View | Annotate | Download (3.52 KB)

1 01873262 Georg Kunz
//==========================================================================
2
//  ARGS.CC - part of
3
//                     OMNeT++/OMNEST
4
//             Discrete System Simulation in C++
5
//
6
//  Command line argument handling
7
//
8
//  Author: Andras Varga
9
//
10
//==========================================================================
11
12
/*--------------------------------------------------------------*
13
  Copyright (C) 1992-2008 Andras Varga
14
  Copyright (C) 2006-2008 OpenSim Ltd.
15

16
  This file is distributed WITHOUT ANY WARRANTY. See the file
17
  `license' for details on this and other legal matters.
18
*--------------------------------------------------------------*/
19
20
#include <string.h>
21
#include <stdio.h>
22
#include "args.h"
23
#include "opp_ctype.h"
24
#include "exception.h"
25
26
USING_NAMESPACE
27
28
29
ArgList::ArgList()
30
{
31
    argc = 0;
32
    argv = NULL;
33
}
34
35
void ArgList::parse(int argc, char *argv[], const char *spec)
36
{
37
    this->argc = argc;
38
    this->argv = argv;
39
    this->spec = spec;
40
41
    int i;
42
    for (i=1; i<argc; i++)
43
    {
44
        if (strcmp(argv[i], "--")==0)
45
        {
46
            // end of options
47
            i++;
48
            break;
49
        }
50
        if (argv[i][0]=='-' && argv[i][1]=='-')
51
        {
52
            // long option -- treat it liberally for now
53
            const char *eqpos = strchr(argv[i], '=');
54
            if (eqpos)
55
                longOpts[std::string(argv[i]+2, eqpos-argv[i]-2)] = eqpos+1;
56
            else if (i==argc-1)
57
                longOpts[argv[i]+2] = "";
58
            else {
59
                longOpts[argv[i]+2] = argv[i+1];
60
                i++;
61
            }
62
        }
63
        else if (argv[i][0]=='-')
64
        {
65
            // short option
66
            char c = argv[i][1];
67
            if (!isValidOption(c))
68
                throw opp_runtime_error("invalid command-line option %s, try -h for help", argv[i]);
69
70
            std::vector<std::string>& v = shortOpts[c]; // get or create map element
71
            if (hasArg(c))
72
            {
73
                if (argv[i][2])
74
                    v.push_back(argv[i]+2);
75
                else if (i < argc-1)
76
                    v.push_back(argv[++i]);
77
                else if (!hasOptionalArg(c))
78
                    throw opp_runtime_error("command-line option %s is missing required argument", argv[i]);
79
            }
80
            else {
81
                if (argv[i][2])
82
                    throw opp_runtime_error("command-line option -%c expects no argument", argv[i][1]);
83
            }
84
        }
85
        else
86
        {
87
            // end of options
88
            break;
89
        }
90
    }
91
92
    // store the rest of the args
93
    for (; i<argc; i++)
94
    {
95
        params.push_back(argv[i]);
96
    }
97
}
98
99
bool ArgList::isValidOption(char c) const
100
{
101
    return strchr(spec.c_str(), c) != NULL;
102
}
103
104
bool ArgList::hasArg(char c) const
105
{
106
    const char *p = strchr(spec.c_str(), c);
107
    return p && (*(p+1)==':' || *(p+1)=='?');
108
}
109
110
bool ArgList::hasOptionalArg(char c) const
111
{
112
    const char *p = strchr(spec.c_str(), c);
113
    return p && *(p+1)=='?';
114
}
115
116
std::map<std::string,std::string> ArgList::getLongOptions() const
117
{
118
    return longOpts;
119
}
120
121
bool ArgList::optionGiven(char c) const
122
{
123
    return shortOpts.find(c)!=shortOpts.end();
124
}
125
126
const char *ArgList::optionValue(char c, int k) const
127
{
128
    if (shortOpts.find(c)==shortOpts.end())
129
        return NULL;
130
    const std::vector<std::string>& v = shortOpts.find(c)->second; // VC++ has problems with shortOpts[c]
131
    return (k>=0 && k<(int)v.size()) ? v[k].c_str() : NULL;
132
}
133
134
const char *ArgList::argument(int k) const
135
{
136
    return (k>=0 && k<(int)params.size()) ? params[k].c_str() : NULL;
137
}
138