update shit
This commit is contained in:
		| @ -1,4 +1,6 @@ | ||||
| #include "CmdHelper.hpp" | ||||
| #include "TerminalHelper.hpp" | ||||
| #include <stdexcept> | ||||
|  | ||||
| namespace Unvirt { | ||||
| 	namespace CmdHelper { | ||||
| @ -14,7 +16,7 @@ namespace Unvirt { | ||||
| 			; | ||||
| 		} | ||||
|  | ||||
| 		std::vector<std::string> CmdSplitter::Convert(std::string& u8cmd) { | ||||
| 		std::vector<std::string> CmdSplitter::Convert(const std::string& u8cmd) { | ||||
| 			// set up variables | ||||
| 			std::vector<std::string> result; | ||||
| 			std::string buffer; | ||||
| @ -69,11 +71,77 @@ namespace Unvirt { | ||||
|  | ||||
| #pragma region interactive cmd helper classes | ||||
|  | ||||
| 		SubCmd::SubCmd() { | ||||
|  | ||||
| 		OptionsDescription::OptionsDescription() : | ||||
| 			mLongNameDict(), mShortNameMapping(), mPositionalArgMapping() { | ||||
| 			; | ||||
| 		} | ||||
| 		OptionsDescription::~OptionsDescription() { ; } | ||||
|  | ||||
| 		void OptionsDescription::AddOption( | ||||
| 			const char* fullname, char shortname, CmdArgType type, const char* description) { | ||||
| 			// pre-check | ||||
| 			if (fullname == nullptr || | ||||
| 				fullname[0] == '\0' || | ||||
| 				fullname[0] == '-') | ||||
| 				throw std::invalid_argument("Invalid Option Long Name."); | ||||
|  | ||||
| 			// construct data | ||||
| 			std::string sfullname(fullname); | ||||
| 			OptionDescription data{ | ||||
| 				fullname, shortname, type, (description != nullptr ? description : "") | ||||
| 			}; | ||||
|  | ||||
| 			// check requirement | ||||
| 			if (mLongNameDict.contains(sfullname)) throw std::invalid_argument("Duplicated Option Long Name."); | ||||
| 			if (shortname != '\0') | ||||
| 				if (mShortNameMapping.contains(shortname)) throw std::invalid_argument("Duplicated Option Short Name."); | ||||
|  | ||||
| 			// add them | ||||
| 			mShortNameMapping.emplace(shortname, sfullname); | ||||
| 			mLongNameDict.emplace(sfullname, std::move(data)); | ||||
| 		} | ||||
|  | ||||
| 		SubCmd::~SubCmd() { | ||||
| 		void OptionsDescription::AddPositionalOption(const char* corresponding_longname) { | ||||
| 			// pre-check | ||||
| 			if (corresponding_longname == nullptr) throw std::invalid_argument("Invalid Option Long Name."); | ||||
|  | ||||
| 			// construct data | ||||
| 			std::string fullname(corresponding_longname); | ||||
|  | ||||
| 			// check requirement | ||||
| 			if (!mLongNameDict.contains(fullname)) throw std::invalid_argument("No Matched Option."); | ||||
| 			if (!mPositionalArgMapping.empty()) { | ||||
| 				for (const auto& i : mPositionalArgMapping) { | ||||
| 					if (i == fullname)throw std::invalid_argument("Duplicated Option."); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			// set value | ||||
| 			mPositionalArgMapping.push_back(std::move(fullname)); | ||||
| 		} | ||||
|  | ||||
| 		void OptionsDescription::PrintHelp(FILE* f) { | ||||
| 			fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("Allowed Options: \n")), f); | ||||
| 			for (const auto& [key, value] : mLongNameDict) { | ||||
| 				fprintf(f, "--%s\t%s\n", value.mLongName.c_str(), value.mDescription.c_str()); | ||||
| 			} | ||||
|  | ||||
| 			if (!mPositionalArgMapping.empty()) { | ||||
| 				fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("\nPositional Options: \n")), f); | ||||
| 				for (const auto& i : mPositionalArgMapping) { | ||||
| 					fprintf(f, "[%s] ", i.c_str()); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
|  | ||||
| 		VariablesMap::VariablesMap() { | ||||
| 		} | ||||
|  | ||||
| 		VariablesMap::~VariablesMap() { | ||||
| 		} | ||||
|  | ||||
|  | ||||
| #pragma endregion | ||||
|  | ||||
|  | ||||
| @ -4,6 +4,7 @@ | ||||
| #include <string> | ||||
| #include <functional> | ||||
| #include <vector> | ||||
| #include <unordered_map> | ||||
|  | ||||
| namespace Unvirt { | ||||
| 	namespace CmdHelper { | ||||
| @ -15,7 +16,7 @@ namespace Unvirt { | ||||
| 			CmdSplitter& operator=(const CmdSplitter&) = delete; | ||||
| 			~CmdSplitter(); | ||||
|  | ||||
| 			std::vector<std::string> Convert(std::string& u8cmd); | ||||
| 			std::vector<std::string> Convert(const std::string& u8cmd); | ||||
| 		private: | ||||
| 			char mCmdChar; | ||||
| 			std::string* mBuffer; | ||||
| @ -120,13 +121,68 @@ namespace Unvirt { | ||||
| 			} | ||||
| 		}; | ||||
|  | ||||
| 		class SubCmd { | ||||
| 		enum class CmdArgType { | ||||
| 			NONE, | ||||
| 			STRING, | ||||
| 			INT | ||||
| 		}; | ||||
|  | ||||
| 		struct OptionDescription { | ||||
| 			std::string mLongName; | ||||
| 			char mShortName; | ||||
| 			CmdArgType mType; | ||||
| 			std::string mDescription; | ||||
| 		}; | ||||
|  | ||||
| 		class OptionsDescription { | ||||
| 		public: | ||||
| 			SubCmd(); | ||||
| 			~SubCmd(); | ||||
| 			OptionsDescription(); | ||||
| 			OptionsDescription(const OptionsDescription&) = delete; | ||||
| 			OptionsDescription& operator=(const OptionsDescription&) = delete; | ||||
| 			~OptionsDescription(); | ||||
|  | ||||
| 			/// <summary> | ||||
| 			/// Add an option | ||||
| 			/// </summary> | ||||
| 			/// <param name="fullname">The long name of this option. Should NOT be blank or NULL.</param> | ||||
| 			/// <param name="shortname">A single char for the short name of this option. Leave ZERO to omit this.</param> | ||||
| 			/// <param name="type">The value type of this option. Set to CmdArgType::NONE to indicate this is a switch (no value).</param> | ||||
| 			/// <param name="sescription">The description of this option. This can be NULL.</param> | ||||
| 			void AddOption(const char* fullname, char shortname, CmdArgType type, const char* sescription); | ||||
| 			void AddPositionalOption(const char* corresponding_longname); | ||||
|  | ||||
| 			void PrintHelp(FILE* f); | ||||
| 		private: | ||||
| 			std::unordered_map<std::string, OptionDescription> mLongNameDict; | ||||
| 			std::unordered_map<char, std::string> mShortNameMapping; | ||||
| 			std::vector<std::string> mPositionalArgMapping; | ||||
| 		}; | ||||
|  | ||||
| 		struct AnyVariable { | ||||
| 			CmdArgType mType; | ||||
| 			void* mData; | ||||
| 		}; | ||||
|  | ||||
| 		class VariablesMap { | ||||
| 		private: | ||||
| 			std::unordered_map<std::string, AnyVariable> mDataPair; | ||||
|  | ||||
| 		public: | ||||
| 			VariablesMap(); | ||||
| 			~VariablesMap(); | ||||
|  | ||||
| 			void Clear(void); | ||||
| 			bool AddPair(std::string& name, CmdArgType t, std::string& val); | ||||
| 			bool Contain(const char* probe); | ||||
| 			template<typename T> | ||||
| 			T* GetData(const char* opt) { | ||||
| 				; | ||||
| 			} | ||||
| 		}; | ||||
|  | ||||
| 		struct CmdRegisteryEntry { | ||||
| 			OptionsDescription mOptDesc; | ||||
| 			std::function<void(OptionsDescription&, VariablesMap&)> mBindProc; | ||||
| 		}; | ||||
|  | ||||
| 		class InteractiveCmd { | ||||
| @ -137,7 +193,9 @@ namespace Unvirt { | ||||
| 			void Run(void); | ||||
|  | ||||
| 		private: | ||||
| 			//std::unordered_map<std::string, CmdRegisteryEntry> mCmdDispatcher; | ||||
| 			bool AnalyzeCmd(std::vector<std::string>& args); | ||||
| 			void PrintHelp(FILE* f); | ||||
| 			std::unordered_map<std::string, CmdRegisteryEntry> mCmdDispatcher; | ||||
|  | ||||
|  | ||||
| 		}; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user