20
20
#include "Puma/ParserKey.h"
22
22
//#include <iostream>
23
24
using namespace std;
28
OptsParser::OptsParser (int argc, char **argv, const Option *opts) : m_opts (opts) {
29
for (int idx = 1; idx < argc; idx++) {
30
m_argv.push_back (argv[idx]);
32
m_curarg = m_tonext = m_number = 0;
36
OptsParser::OptsParser (const string &line, const Option *opts) : m_opts (opts) {
37
tokenize (line, m_argv, " \t\n\r");
38
m_curarg = m_tonext = m_number = 0;
42
int OptsParser::getOption () {
46
if (m_curarg < m_argv.size ()) {
49
const string &arg (m_argv[m_curarg]);
50
if (ParserKey::isLongKey (arg) && arg.length () > ParserKey::getLongKeyLength ()) {
51
m_number = getLongOption (arg);
52
} else if (ParserKey::isKey (arg) && arg.length () > 1) {
53
m_number = getShortOption (arg);
55
//cout << "no option: " << arg << endl;
65
int OptsParser::getLongOption (const string &arg) {
67
const Option *opts = m_opts;
68
unsigned int keyLen = ParserKey::getLongKeyLength ();
70
// search for long option name in arg
71
while (opts->number != 0) {
72
if (opts->name != NULL) {
73
if ((opts->args != AT_NONE) ||
74
((arg.length () - keyLen) == strlen (opts->name))) {
75
if (arg.find (opts->name) == keyLen)
82
// if we found an option go on with processing
86
// option possibly has arguments
87
if (opts->args != AT_NONE) {
88
if (processOption (arg, (unsigned int)strlen (opts->name) +
89
ParserKey::getLongKeyLength (),opts->args) == false)
92
m_opt = arg.substr (0, strlen (opts->name) + ParserKey::getLongKeyLength ());
93
//cout << "found long option: " << arg << " with argument " << getArgument () << endl;
95
//cout << "unknown long option: " << arg << endl;
103
int OptsParser::getShortOption (const string &arg) {
105
const Option *opts = m_opts;
107
// search for short option
108
while (opts->number != 0 && opts->key != arg[1]) {
112
// ok we found a short option that fits
116
if (processOption (arg, 2,opts->args) == false){
120
//cout << "found short option: " << arg << " with argument " << getArgument () << endl;
123
//cout << "unknown short option: " << arg << endl;
130
// process option and option argument.
131
// there can AT_NONE, a AT_MANDATORY or an AT_OPTIONAL option argument.
132
bool OptsParser::processOption (const string &arg, unsigned int len,ArgType argtype) {
134
// set current option
135
m_opt = arg.substr (0, len);
137
// if there should be no argument provided don't process it
138
if (argtype == AT_NONE){
142
// if there are characters behind the end of the option name,
143
// treat them as option argument
144
if (arg.length () > len) {
145
m_arg = strip (arg.substr (len, arg.length () - len));
148
// if ARGV contains at least one more element
149
// check if it is an option argument
150
else if (m_curarg + 1 < m_argv.size () ) {
152
// if the next element of ARGV is NOT an other option treat it as option argument
153
// otherwise m_arg will continue containing an empty string
154
const string &next_argv(m_argv[m_curarg + 1]);
155
if (! ( (ParserKey::isLongKey(next_argv) && next_argv.length() > ParserKey::getLongKeyLength()) ||
156
(ParserKey::isKey(next_argv) && next_argv.length() > ParserKey::getKeyLength())))
158
m_arg = strip(next_argv);
164
// return false if there should be an argument
165
if( m_arg.empty() && argtype == AT_MANDATORY){
173
bool OptsParser::revokeArgument () {
182
int OptsParser::getCurrentArgNum () const {
186
int OptsParser::getNextArgNum () const {
187
return m_curarg + m_tonext + 1 ;
191
int OptsParser::getResult () const {
196
const string &OptsParser::getArgument () const {
201
const string &OptsParser::getOptionName () const {
29
OptsParser::OptsParser(int argc, char **argv, const Option *opts) : m_opts(opts)
31
for (int idx = 0; idx < argc; idx++)
33
m_argv.push_back (argv[idx]);
41
OptsParser::OptsParser(const string &line, const Option *opts) : m_opts(opts)
43
tokenize (line, m_argv, " \t\n\r");
44
m_curarg = m_tonext = m_number = 0;
47
int OptsParser::getOption ()
53
if (m_curarg < m_argv.size())
56
const string &arg (m_argv[m_curarg]);
63
if ( ParserKey::isLongKey(arg) &&
64
( arg.length() > ParserKey::getLongKeyLength() )
69
else if ( ( ParserKey::isKey(arg)) &&
70
( arg.length() > ParserKey::getKeyLength() )
81
if (m_number != NOOPTION)
83
// search options in argument string
84
curOpt=findOption(arg,isLong);
86
// if we found an option go on with processing
87
if((curOpt != NULL) && (curOpt->number != 0))
90
if (processOption(arg, curOpt, isLong) == false)
96
m_number = curOpt->number;
101
//cout << "no option: " << arg << endl;
110
int OptsParser::getRawOption ()
114
m_curarg += m_tonext;
115
if (m_curarg < m_argv.size ())
119
m_arg = strip (m_argv[m_curarg]);
126
const Puma::OptsParser::Option* OptsParser::findOption(const string &arg, bool isLong)
130
const Option *curOpt = m_opts;
131
const Option *selOpt = NULL;
132
unsigned int selOptLength=0;
134
// search for long option name in arg
135
while (curOpt->number != 0)
138
if((isLong == true) && (curOpt->longName != NULL))
140
keyLen = ParserKey::getLongKeyLength();
141
curName=curOpt->longName;
143
else if(curOpt->shortName != NULL)
145
keyLen = ParserKey::getKeyLength();
146
curName=curOpt->shortName;
155
* - name is not null AND
156
* - selected option is either null OR shorter than
157
* the currently analyzed option AND
158
* - the current option receives a parameter OR is exactly as long
159
* as passed argument AND
160
* - the string passed as argument starts at the position after
164
( ! curName.empty() ) &&
165
((selOpt == NULL) || (selOptLength <= curName.length()) ) &&
166
( (curOpt->argType != AT_NONE) || ((arg.length() - keyLen) == curName.length()) ) &&
167
( arg.find(curName) == keyLen )
171
selOptLength = curName.length();
178
// process option and option argument.
179
// there can AT_NONE, a AT_MANDATORY or an AT_OPTIONAL option argument.
180
bool OptsParser::processOption (const string &arg, const Option* curOpt,bool isLong)
186
len = (ParserKey::getLongKeyLength() + strlen(curOpt->longName));
190
len = (ParserKey::getKeyLength() + strlen(curOpt->shortName));
193
// set current option
194
m_opt = arg.substr (0, len);
196
// if there should be no argument provided do not proceed
197
if (curOpt->argType == AT_NONE)
202
// if there are characters behind the end of the option name,
203
// treat them as option parameter
204
if (arg.length() > len)
206
m_arg = strip(arg.substr(len, arg.length() - len));
209
// if ARGV contains at least one more element
210
// check if it is an option argument
211
else if ((m_curarg + 1) < m_argv.size() )
214
// if the next element of ARGV is NOT an other option treat it as option argument
215
// otherwise m_arg will continue containing an empty string
216
const string &next_argv(m_argv[m_curarg + 1]);
217
if (! ( (ParserKey::isLongKey(next_argv) && next_argv.length() > ParserKey::getLongKeyLength()) ||
218
(ParserKey::isKey(next_argv) && next_argv.length() > ParserKey::getKeyLength())))
220
m_arg = strip(next_argv);
225
// return false if there should be an argument
226
if( m_arg.empty() && curOpt->argType == AT_MANDATORY)
235
int OptsParser::getResult () const
241
const string &OptsParser::getArgument () const {
246
const string &OptsParser::getOptionName () const {
250
int OptsParser::getCurrentArgNum () const {
254
int OptsParser::getNextArgNum () const {
255
return m_curarg + m_tonext;
206
258
} // namespace Puma