diff --git a/msh-console-library/CMakeLists.txt b/msh-console-library/CMakeLists.txt index e3b1fe4..3ded61d 100644 --- a/msh-console-library/CMakeLists.txt +++ b/msh-console-library/CMakeLists.txt @@ -4,22 +4,19 @@ project(msh-console-library) cmake_minimum_required(VERSION 2.8) -set(compilable OFF) -if(${compilable}) - SET(CMAKE_CXX_FLAGS "-std=c++11") - FILE(GLOB sources *.cpp) - FILE(GLOB headers *.h) +SET(CMAKE_CXX_FLAGS "-std=c++11") +FILE(GLOB sources *.cpp) +FILE(GLOB headers *.h) - set(lib OFF) - if(${lib}) - MESSAGE( STATUS "Building .so.1") - #compile the library - # Create a library which includes the source listed. - # The extension is already found. Any number of sources could be listed here. - list(REMOVE_ITEM SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp) - add_library (mshconsole SHARED ${SRC_LIST}) - else(${lib}) - MESSAGE( STATUS "Building exec (debug only)") - add_executable(${PROJECT_NAME} ${sources} ${headers}) - endif(${lib}) -endif(${compilable}) +set(lib OFF) +if(${lib}) + MESSAGE( STATUS "Building .so.1") + #compile the library + # Create a library which includes the source listed. + # The extension is already found. Any number of sources could be listed here. + list(REMOVE_ITEM SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp) + add_library (mshconsole SHARED ${SRC_LIST}) +else(${lib}) + MESSAGE( STATUS "Building exec (debug only)") + add_executable(${PROJECT_NAME} ${sources} ${headers}) +endif(${lib}) diff --git a/msh-console-library/command.cpp b/msh-console-library/command.cpp index e358820..46348ff 100644 --- a/msh-console-library/command.cpp +++ b/msh-console-library/command.cpp @@ -1,29 +1,37 @@ #include "shell.h" namespace mshconsole { - Command::Command(const string& n, int (*funcptr)(CommandExecutor*,const vector&,const vector&, const char** argv)) : + Command::Command(const string& n, int (*funcptr)(CommandExecutor* whoExecuted,const Datas& data, const vector argv)) : name(n), funcCommand(funcptr){ checkObj(); } + void Command::addOption(Option *a){ + if(a->getOptionName().length()==1){ + shortOpts.push_back(a); + } + else longOpts.push_back(a); + } + int Command::execute(const vector* args, CommandExecutor* c){ if(args==nullptr) return -1; - vector data; - for(size_t i=0; i sLongData; - for(size_t i=0; igetOptionName()[0]); } getoptarg+=" -:"; + //creating argv as char** for getopt compatibility vector argv(args->size()); size_t i; for (i = 0; i < args->size(); ++i) @@ -31,6 +39,7 @@ namespace mshconsole { argv[i] = const_cast(&(args->operator[](i)[0])); } int argc=i; + //TODO: quotes for long options try{ int c; @@ -38,9 +47,10 @@ namespace mshconsole { 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; igetOptionName()[0]){ + shortData[i]->set(true); + break; } } } @@ -48,59 +58,77 @@ namespace mshconsole { string l(optarg); bool getout = false; try{ - for(size_t i=0; igetArgName()+"=")==0){ - if(!(longOptions.at(i)->hasFlag(LongOption::STRING))){ + for(size_t i=0; igetOptionName()+"=")==0){ + if(!(longOpts[i]->hasFlag(Option::STRING))){ throw NotRightArgException(); } - data[i]->set(l.substr(longOptions[i]->getArgName().size()+1,l.size())); + longData[i]->set(l.substr(longOpts[i]->getOptionName().size()+1,l.size())); getout = true; break; } - if(l==longOptions[i]->getArgName()){ - data[i]->set(true); + if(l==longOpts[i]->getOptionName()){ + longData[i]->set(true); getout=true; break; } } } - catch(LongData::MultipleDefinitionException){ + catch(Data::MultipleDefinitionException){ getout=false; } if(!getout) throw OptionNotParsedCorrectlyException(static_cast("--") + 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; + return -1; } else //abort(); break; } - //demo for debug + + //demo of all options for debug (code to check) /* - for(size_t i=0; igetArgName() << ": "; + for(size_t i=0; igetOptionName() << ": "; 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(argv.data())); + + //making one big Data vector + shortOpts.insert( + shortOpts.end(), + std::make_move_iterator(longOpts.begin()), + std::make_move_iterator(longOpts.end()) + ); + + //deleting options and command name from argv + argv.erase(argv.begin()); //argv[0] = command name + for(int i=0; ihowMany(); 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(""); + const string Command::Data::EMPTY(""); } diff --git a/msh-console-library/command.h b/msh-console-library/command.h index 67e9e6d..003b5c7 100644 --- a/msh-console-library/command.h +++ b/msh-console-library/command.h @@ -2,7 +2,8 @@ #define COMMAND_H #include #include -#include "shell.h" +//#include "shell.h" +#include "option.h" #include "commandexecutor.h" using std::string; @@ -22,13 +23,13 @@ namespace mshconsole{ class CommandNameNotValidException {}; class NotRightArgException {}; - - vector shortOptions; const string name; void checkObj(); + vector longOpts; + vector shortOpts; public: - class LongData{ + class Data{ public: enum States{ STRING=4, @@ -38,77 +39,42 @@ namespace mshconsole{ class MultipleDefinitionException{}; private: - string sLongData; + string sData; + const Option* of; enum States state; static const string EMPTY; - bool isSLongDataValorized; + bool isSDataValorized; + Data(const Option* o) : sData(), state(Data::FALSE), isSDataValorized(false), of(o) {} public: - LongData() : sLongData(), state(LongData::FALSE), isSLongDataValorized(false) {} - void set(bool b){ - if(isSLongDataValorized) throw MultipleDefinitionException(); - b ? state=LongData::TRUE : state=LongData::FALSE; - isSLongDataValorized=true; - } - void set(const string& s){ - if(isSLongDataValorized) throw MultipleDefinitionException(); - state=LongData::STRING; - sLongData=s; - isSLongDataValorized=true; - } - enum LongData::States getState() const{ - return state; - } - const string& getLongData() const{ - if(state!=LongData::STRING) return EMPTY; - else return sLongData; - } - bool getBoolState() const{ - return state!=LongData::FALSE; - } + void set(bool b); + void set(const string& s); + enum States getState() const; + const string& getData() const; + bool getBoolState() const; + friend class Command; + friend class Datas; }; - Command(const string& n, int (*funcptr)(CommandExecutor*, const vector&, const vector&, const char** argv)); + class Datas : public vector{ + public: + Data* getOptData(const string& optionName) const; + }; + + Command(const string& n, int (*funcptr)(CommandExecutor* whoExecuted,const Datas& data, const vector argv)); Command(const Command&); ~Command(); string getName(); int execute(const vector*, CommandExecutor*); + void addOption(Option* a); - class LongOption{ - string argName; - public: - enum States{ - STRING=2, - BOOL=1 - }; - private: - enum States want; - public: - LongOption(const string& s, enum States b) : argName(s), want(b) {} - enum States getWant() const{ - return want; - } - const string& getArgName(){ - return argName; - } - bool hasFlag(enum States s){ - return want & s; - } - }; - void addLongOption(LongOption* a){ - longOptions.push_back(a); - } - void addShortOption(char a){ - shortOptions.push_back(a); - } private: - vector longOptions; - int (*funcCommand)(CommandExecutor*,const vector&, const vector&, const char** argv); + int (*funcCommand)(CommandExecutor* whoExecuted,const Datas& data, const vector argv); }; - inline Command::LongOption::States operator|(Command::LongOption::States a, Command::LongOption::States b){ - return static_cast(static_cast(a) | static_cast(b)); - } + + + } diff --git a/msh-console-library/data.cpp b/msh-console-library/data.cpp new file mode 100644 index 0000000..3fdf9c8 --- /dev/null +++ b/msh-console-library/data.cpp @@ -0,0 +1,30 @@ +#include "command.h" + +namespace mshconsole{ + void Command::Data::set(bool b){ + if(isSDataValorized) throw MultipleDefinitionException(); + b ? state=Data::TRUE : state=Data::FALSE; + isSDataValorized=true; + } + void Command::Data::set(const string& s){ + if(isSDataValorized) throw MultipleDefinitionException(); + state=Data::STRING; + sData=s; + isSDataValorized=true; + } + enum Command::Data::States Command::Data::getState() const{ + return state; + } + const string& Command::Data::getData() const{ + if(state!=Data::STRING) return EMPTY; + else return sData; + } + bool Command::Data::getBoolState() const{ + return state!=Data::FALSE; + } + Command::Data* Command::Datas::getOptData(const string& opt) const{ + for(size_t i=0; iof->getOptionName()==opt) return operator[](i); + } + } +} diff --git a/msh-console-library/option.cpp b/msh-console-library/option.cpp new file mode 100644 index 0000000..36a565e --- /dev/null +++ b/msh-console-library/option.cpp @@ -0,0 +1,17 @@ +#include "option.h" + +namespace mshconsole{ + Option::Option(const string &s, States b): optionName(s), want(b){ + if(optionName.length()<1){ + throw OptionNameEmptyException{}; + } + } + + const string& Option::getOptionName() const{ + return optionName; + } + + bool Option::hasFlag(enum States s) const{ + return want & s; + } +} diff --git a/msh-console-library/option.h b/msh-console-library/option.h new file mode 100644 index 0000000..992c4c9 --- /dev/null +++ b/msh-console-library/option.h @@ -0,0 +1,20 @@ +#include +using std::string; + +namespace mshconsole{ + class Option{ + string optionName; + class OptionNameEmptyException{}; + public: + enum States{ + STRING=2, + BOOL=1 + }; + private: + enum States want; + public: + Option(const string& s, enum States b); + const string& getOptionName() const; + bool hasFlag(enum States s) const; + }; +}