170 lines
5.5 KiB
C++
170 lines
5.5 KiB
C++
#include "shell.h"
|
|
namespace mshconsole {
|
|
|
|
Command::Command(const string& n, int (*funcptr)(CommandExecutor*,const vector<LongData*>&,const vector<bool>&, const char** argv)) :
|
|
name(n), funcCommand(funcptr){
|
|
checkObj();
|
|
}
|
|
|
|
int Command::execute(const vector<string>* args, CommandExecutor* c){
|
|
if(args==nullptr) return -1;
|
|
vector<LongData*> data;
|
|
for(size_t i=0; i<longOptions.size(); i++){
|
|
data.push_back(new LongData());
|
|
}
|
|
|
|
vector<bool> sLongData;
|
|
for(size_t i=0; i<shortOptions.size(); i++){
|
|
sLongData.push_back(false);
|
|
}
|
|
|
|
string getoptarg;
|
|
for(size_t i=0; i<shortOptions.size(); i++){
|
|
getoptarg.append(1,shortOptions[i]);
|
|
}
|
|
getoptarg+=" -:";
|
|
|
|
vector<char *> argv(args->size());
|
|
size_t i;
|
|
for (i = 0; i < args->size(); ++i)
|
|
{
|
|
argv[i] = const_cast<char*>(&(args->operator[](i)[0]));
|
|
}
|
|
int argc=i;
|
|
//TODO: quotes for long options
|
|
try{
|
|
int c;
|
|
opterr=0;
|
|
optind=1;
|
|
while ((c = getopt (argc, argv.data(), getoptarg.c_str())) != -1){
|
|
if((c>='a'&&c<='z')||(c>='A'&&c>='Z')){
|
|
for(size_t i=0; i<shortOptions.size(); i++){
|
|
if(c==shortOptions[i]){
|
|
sLongData[i]=true;
|
|
}
|
|
}
|
|
}
|
|
else if(c=='-'){
|
|
string l(optarg);
|
|
bool getout = false;
|
|
try{
|
|
for(size_t i=0; i<longOptions.size(); i++){
|
|
if(l.find(longOptions[i]->getArgName()+"=")==0){
|
|
if(!(longOptions.at(i)->hasFlag(LongOption::STRING))){
|
|
throw NotRightArgException();
|
|
}
|
|
data[i]->set(l.substr(longOptions[i]->getArgName().size()+1,l.size()));
|
|
getout = true;
|
|
break;
|
|
}
|
|
if(l==longOptions[i]->getArgName()){
|
|
data[i]->set(true);
|
|
getout=true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
catch(LongData::MultipleDefinitionException){
|
|
getout=false;
|
|
}
|
|
if(!getout) throw OptionNotParsedCorrectlyException(static_cast<string>("--") + optarg);
|
|
}
|
|
else if(c=='?'){
|
|
//if (optopt == 'c')
|
|
// fprintf (stderr, "Option -%c requires an argument.\n", optopt); else
|
|
if (isprint (optopt))
|
|
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
|
|
else
|
|
fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt);
|
|
//return 1;
|
|
}
|
|
else //abort();
|
|
break;
|
|
}
|
|
//demo for debug
|
|
/*
|
|
for(size_t i=0; i<longOptions.size(); i++){
|
|
cout << longOptions[i]->getArgName() << ": ";
|
|
LongData* now = data[i];
|
|
if(now->getState()==LongData::States::STRING) cout << now->getLongData();
|
|
else cout << now->getBoolState();
|
|
cout << "\n";
|
|
}
|
|
for(size_t i=0; i<shortOptions.size(); i++){
|
|
cout << shortOptions[i] << ": " << sLongData[i] << "\n";
|
|
}*/
|
|
}
|
|
catch(OptionNotParsedCorrectlyException e){
|
|
cout << "Error parsing option " << e.getOptarg() << "\n";
|
|
}
|
|
catch(NotRightArgException){
|
|
cout << "Error on options argument type\n";
|
|
}
|
|
return (*funcCommand)(c,data,sLongData, const_cast<const char**>(argv.data()));
|
|
}
|
|
|
|
string Command::getName(){
|
|
return this->name;
|
|
}
|
|
|
|
Command::Command(const Command& old) : name(old.name) , funcCommand(old.funcCommand){
|
|
checkObj();
|
|
}
|
|
|
|
void Command::checkObj(){
|
|
for(unsigned int i=0; i<name.length(); i++){
|
|
if(!((name[i]>'a'&&name[i]<'z')||(name[i]>'A'&&name[i]<'Z'))){
|
|
throw CommandNameNotValidException();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*Command::Options *Command::getCmdOpts() const
|
|
{
|
|
return cmdOpts;
|
|
}
|
|
|
|
void Command::setCmdOpts(Command::Options *value)
|
|
{
|
|
cmdOpts = value;
|
|
}
|
|
|
|
Command::~Command(){
|
|
numCom--;
|
|
}
|
|
|
|
unsigned int Command::numCom = 0;
|
|
|
|
const Command::Options *(Command::defaultOpts) = new Command::Options();
|
|
|
|
string Command::Options::Option::getOShort() const
|
|
{
|
|
return oShort;
|
|
}
|
|
|
|
void Command::Options::Option::setOShort(const string &value)
|
|
{
|
|
oShort = value;
|
|
}
|
|
|
|
string Command::Options::Option::getOLong() const
|
|
{
|
|
return oLong;
|
|
}
|
|
|
|
void Command::Options::Option::setOLong(const string &value)
|
|
{
|
|
oLong = value;
|
|
}
|
|
|
|
void Command::Options::addOption(Command::Options::Option *a){
|
|
for(size_t i=0; i<this->howMany(); i++){
|
|
if(a->getOShort()==(this->operator [](i)->getOShort())||a->getOLong()==(this->operator [](i)->getOLong())){
|
|
throw OptionNameConflictException();
|
|
}
|
|
}
|
|
opts.push_back(a);
|
|
}*/
|
|
|
|
const string Command::LongData::EMPTY("");
|
|
}
|