Command Line Parsing
- Implemented Arguments::extract_command to locate the command keyword in an argument list. - Implemented Arguments::extract_sequence to locate and remove an ID sequence from an argument list. - Added unit test for extract_sequence. - Stubbed all Argument::extract_<object> methods. - Simplified code in (soon to be obsolete) Sequence.cpp.
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
#include <Context.h>
|
||||
#include <Nibbler.h>
|
||||
#include <text.h>
|
||||
#include <util.h>
|
||||
#include <Arguments.h>
|
||||
|
||||
extern Context context;
|
||||
@@ -45,22 +46,11 @@ Arguments::~Arguments ()
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Arguments::capture (int argc, char** argv)
|
||||
void Arguments::capture (int argc, const char** argv)
|
||||
{
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
/*
|
||||
if (i == 0)
|
||||
{
|
||||
std::string::size_type cal = context.program.find ("/cal");
|
||||
if (context.program == "cal" ||
|
||||
(cal != std::string::npos && context.program.length () == cal + 4))
|
||||
this->push_back ("calendar");
|
||||
}
|
||||
else
|
||||
*/
|
||||
if (i > 0)
|
||||
this->push_back (argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -241,3 +231,159 @@ std::string Arguments::combine ()
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Given a vector of command keywords, scan all arguments and locate the first
|
||||
// argument that matches a keyword.
|
||||
bool Arguments::extract_command (
|
||||
const std::vector <std::string>& keywords,
|
||||
std::string& command)
|
||||
{
|
||||
std::vector <std::string>::iterator arg;
|
||||
for (arg = this->begin (); arg != this->end (); ++arg)
|
||||
{
|
||||
std::vector <std::string> matches;
|
||||
if (autoComplete (*arg, keywords, matches) == 1)
|
||||
{
|
||||
if (*arg != matches[0])
|
||||
context.debug ("Arguments::extract_command keyword '" + *arg + "' --> '" + matches[0] + "'");
|
||||
else
|
||||
context.debug ("Arguments::extract_command keyword '" + *arg + "'");
|
||||
|
||||
command = matches[0];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// A sequence can be:
|
||||
//
|
||||
// a single ID: 1
|
||||
// a list of IDs: 1,3,5
|
||||
// a list of IDs: 1 3 5
|
||||
// a range: 5-10
|
||||
// or a combination: 1,3,5-10 12
|
||||
//
|
||||
// If a sequence is followed by a non-number, then subsequent numbers are not
|
||||
// interpreted as IDs. For example:
|
||||
//
|
||||
// 1 2 three 4
|
||||
//
|
||||
// The sequence is "1 2".
|
||||
//
|
||||
// The first number found in the command line is assumed to be a sequence. If
|
||||
// there are two sequences, only the first is recognized, for example:
|
||||
//
|
||||
// 1,2 three 4,5
|
||||
//
|
||||
// The sequence is "1,2".
|
||||
//
|
||||
void Arguments::extract_sequence (std::vector <int>& sequence)
|
||||
{
|
||||
sequence.clear ();
|
||||
std::vector <int> kill;
|
||||
|
||||
bool terminated = false;
|
||||
for (int i = 0; i < this->size (); ++i)
|
||||
{
|
||||
if (!terminated)
|
||||
{
|
||||
bool something = false;
|
||||
|
||||
// The '--' argument shuts off all parsing - everything is an argument.
|
||||
if ((*this)[i] == "--")
|
||||
{
|
||||
terminated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isdigit ((*this)[i][0]))
|
||||
{
|
||||
std::vector <std::string> ranges;
|
||||
split (ranges, (*this)[i], ',');
|
||||
|
||||
std::vector <std::string>::iterator it;
|
||||
for (it = ranges.begin (); it != ranges.end (); ++it)
|
||||
{
|
||||
std::vector <std::string> range;
|
||||
split (range, *it, '-');
|
||||
|
||||
if (range.size () == 1)
|
||||
{
|
||||
if (! digitsOnly (range[0]))
|
||||
throw std::string ("Invalid ID in sequence.");
|
||||
|
||||
int id = (int)strtol (range[0].c_str (), NULL, 10);
|
||||
sequence.push_back (id);
|
||||
something = true;
|
||||
}
|
||||
else if (range.size () == 2)
|
||||
{
|
||||
if (! digitsOnly (range[0]) ||
|
||||
! digitsOnly (range[1]))
|
||||
throw std::string ("Invalid ID in range.");
|
||||
|
||||
int low = (int)strtol (range[0].c_str (), NULL, 10);
|
||||
int high = (int)strtol (range[1].c_str (), NULL, 10);
|
||||
if (low > high)
|
||||
throw std::string ("Inverted sequence range high-low.");
|
||||
|
||||
if (high - low >= ARGUMENTS_SEQUENCE_MAX_RANGE)
|
||||
throw std::string ("ID Range too large.");
|
||||
|
||||
for (int r = low; r <= high; ++r)
|
||||
sequence.push_back (r);
|
||||
|
||||
something = true;
|
||||
}
|
||||
|
||||
// Not a properly formed sequence, therefore probably text.
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Once a sequence has been found, any non-numeric arguments effectively
|
||||
// terminate sequence processing.
|
||||
else if (sequence.size ())
|
||||
terminated = true;
|
||||
}
|
||||
|
||||
if (something)
|
||||
kill.push_back (i);
|
||||
}
|
||||
}
|
||||
|
||||
// Now remove args in the kill list.
|
||||
for (int k = 0; k < kill.size (); ++k)
|
||||
this->erase (this->begin () + kill[k]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO
|
||||
void Arguments::extract_uuids (std::vector <std::string>& uuids)
|
||||
{
|
||||
uuids.clear ();
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO
|
||||
void Arguments::extract_filter ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO
|
||||
void Arguments::extract_modifications ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TODO
|
||||
void Arguments::extract_text ()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user