256 lines
5.7 KiB
C++
256 lines
5.7 KiB
C++
#include "options.hpp"
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
ztd::option_error::option_error(error_type type, const std::string& option)
|
|
{
|
|
opt=option;
|
|
switch(type)
|
|
{
|
|
case unknown_option : msg = "Unkown option: " + opt; break;
|
|
case takes_no_arg : msg = "Option " + opt + " doesn't take an argument"; break;
|
|
case missing_arg : msg = "Option " + opt + " needs an argument"; break;
|
|
}
|
|
}
|
|
|
|
std::vector<std::string> ztd::argVector(int argc, char** argv)
|
|
{
|
|
std::vector<std::string> out;
|
|
for(int i=1;i<argc; i++)
|
|
{
|
|
out.push_back(std::string(argv[i]));
|
|
}
|
|
return out;
|
|
}
|
|
|
|
ztd::option::option()
|
|
{
|
|
shortDef=false;
|
|
longDef=false;
|
|
takesArgument=false;
|
|
activated=false;
|
|
charName=0;
|
|
}
|
|
|
|
ztd::option::option(char c, bool arg, std::string helptext, std::string argname)
|
|
{
|
|
//char
|
|
shortDef=true;
|
|
charName=c;
|
|
//string
|
|
longDef=false;
|
|
strName="";
|
|
//arg
|
|
takesArgument=arg;
|
|
arg_name=argname;
|
|
//help
|
|
help_text=helptext;
|
|
//init
|
|
activated=false;
|
|
}
|
|
|
|
ztd::option::option(std::string const& str, bool arg, std::string helptext, std::string argname)
|
|
{
|
|
//char
|
|
shortDef=false;
|
|
charName=0;
|
|
//string
|
|
longDef=true;
|
|
strName=str;
|
|
//arg
|
|
takesArgument=arg;
|
|
arg_name=argname;
|
|
//help
|
|
help_text=helptext;
|
|
//init
|
|
activated=false;
|
|
}
|
|
|
|
ztd::option::option(char c, std::string const& str, bool arg, std::string helptext, std::string argname)
|
|
{
|
|
//char
|
|
shortDef=true;
|
|
charName=c;
|
|
//string
|
|
longDef=true;
|
|
strName=str;
|
|
//arg
|
|
takesArgument=arg;
|
|
arg_name=argname;
|
|
//help
|
|
help_text=helptext;
|
|
//init
|
|
activated=false;
|
|
}
|
|
|
|
ztd::option::option(const option& opt)
|
|
{
|
|
//char
|
|
shortDef=opt.shortDef;
|
|
charName=opt.charName;
|
|
//string
|
|
longDef=opt.longDef;
|
|
strName=opt.strName;
|
|
//arg
|
|
takesArgument=opt.takesArgument;
|
|
arg_name=opt.arg_name;
|
|
//help
|
|
help_text=opt.help_text;
|
|
//init
|
|
activated=false;
|
|
}
|
|
|
|
void ztd::option::print_help(int leftpad, int rightpad) const
|
|
{
|
|
//prepadding
|
|
printf("%*s", -1*leftpad, "");
|
|
|
|
//short def
|
|
if(this->shortDef)
|
|
{
|
|
printf("-%c ", this->charName);
|
|
rightpad -= 3;
|
|
}
|
|
|
|
//longdef
|
|
if(this->longDef)
|
|
{
|
|
printf("--%s ", this->strName.c_str());
|
|
rightpad -= 3 + this->strName.size();
|
|
}
|
|
|
|
//argument
|
|
if(this->takesArgument)
|
|
{
|
|
printf("<%s>", arg_name.c_str());
|
|
rightpad -= arg_name.size() + 2;
|
|
}
|
|
|
|
printf("%*s%s", -1*rightpad, "", help_text.c_str());
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
void ztd::option_set::print_help(int leftpad, int rightpad) const
|
|
{
|
|
for(auto it : this->m_options)
|
|
it.print_help(leftpad,rightpad);
|
|
}
|
|
|
|
ztd::option* ztd::option_set::find(char c)
|
|
{
|
|
for( auto it=m_options.begin() ; it!=m_options.end() ; it++ )
|
|
{
|
|
if(it->shortDef && it->charName == c)
|
|
return &*it;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
ztd::option* ztd::option_set::find(std::string const& str)
|
|
{
|
|
for( auto it=m_options.begin() ; it!=m_options.end() ; it++ )
|
|
{
|
|
if(it->longDef && it->strName == str)
|
|
return &*it;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
std::vector<std::string> ztd::option_set::process(std::vector<std::string> arguments)
|
|
{
|
|
std::vector<std::string> out;
|
|
unsigned int i=0;
|
|
for( auto it = arguments.begin(); it!=arguments.end() ; it++ )
|
|
{
|
|
if( (*it).size()>0 && (*it)[0]=='-' )
|
|
{
|
|
if((*it).size()>1 && (*it)[1]=='-')
|
|
{
|
|
std::size_t eqn=(*it).find('=');
|
|
if(eqn == std::string::npos)
|
|
{
|
|
ztd::option* popt = this->find( (*it).substr(2,eqn-2) );
|
|
if(popt == nullptr)
|
|
{
|
|
throw ztd::option_error(ztd::option_error::unknown_option, "--" + (*it).substr(2,eqn-2));
|
|
}
|
|
if(popt->takesArgument)
|
|
{
|
|
if( ++it == arguments.end() ) //finishes here
|
|
{
|
|
throw ztd::option_error(ztd::option_error::missing_arg, "--" + popt->strName);
|
|
}
|
|
popt->activated = true;
|
|
popt->argument = (*it);
|
|
}
|
|
else
|
|
popt->activated = true;
|
|
}
|
|
else
|
|
{
|
|
ztd::option* popt = this->find( (*it).substr(2,eqn-2) );
|
|
if(popt == nullptr)
|
|
{
|
|
throw ztd::option_error(ztd::option_error::unknown_option, "--" +(*it).substr(2,eqn-2));
|
|
}
|
|
if(!popt->takesArgument)
|
|
{
|
|
throw ztd::option_error(ztd::option_error::takes_no_arg, "--" + popt->strName);
|
|
}
|
|
popt->argument = (*it).substr(eqn+1,(*it).size()-eqn-1 );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
i=1;
|
|
ztd::option* popt=nullptr;
|
|
bool tstop=false;
|
|
while( !tstop && it!=arguments.end() && (*it).size()>i )
|
|
{
|
|
popt=this->find((*it)[i]);
|
|
if(popt==nullptr) //not found: error
|
|
{
|
|
throw ztd::option_error(ztd::option_error::unknown_option, std::string("-") + (*it)[i] );
|
|
}
|
|
if(popt->takesArgument) //no argument
|
|
{
|
|
i++;
|
|
if((*it).size()<=i) //finishes here
|
|
{
|
|
if( ++it == arguments.end() )
|
|
{
|
|
throw ztd::option_error(ztd::option_error::missing_arg, std::string("-") + popt->charName );
|
|
}
|
|
popt->activated = true;
|
|
popt->argument = (*it);
|
|
tstop = true;
|
|
}
|
|
else //continue
|
|
{
|
|
if( (*it)[i] != '=') //incorrect
|
|
{
|
|
throw ztd::option_error(ztd::option_error::missing_arg, std::string("-") + popt->charName );
|
|
}
|
|
i++;
|
|
popt->argument = (*it).substr(i , (*it).size()-i );
|
|
popt->activated = true;
|
|
tstop=true;
|
|
}
|
|
}
|
|
else //no argument
|
|
popt->activated = true;
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
out.push_back(*it);
|
|
}
|
|
if(it == arguments.end())
|
|
break;
|
|
}
|
|
return out;
|
|
}
|