From 6efe4914533ba5968e438bcbcd17dab352af05c0 Mon Sep 17 00:00:00 2001 From: Joeyrp Date: Wed, 1 Sep 2021 15:58:16 -0400 Subject: [PATCH] Adds command line arguments processor --- CMakeLists.txt | 1 + src/core/core.cpp | 19 ++++--- src/core/core.h | 15 +++--- src/test_main.cpp | 31 ++++++++++-- src/utils/args.cpp | 123 +++++++++++++++++++++++++++++++++++++++++++++ src/utils/args.h | 59 ++++++++++++++++++++++ 6 files changed, 230 insertions(+), 18 deletions(-) create mode 100644 src/utils/args.cpp create mode 100644 src/utils/args.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 21fef1f..70536b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ set(LUNARIUM_SRC "src/utils/HighResTimer.cpp" "src/utils/helpers.cpp" "src/utils/OpRes.cpp" +"src/utils/Args.cpp" ) # add the executable diff --git a/src/core/core.cpp b/src/core/core.cpp index ca58fe9..8ff5ff6 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -7,27 +7,28 @@ ******************************************************************************/ #include "core.h" +#include "Version.h" namespace lunarium { - core* core::mpInstance = nullptr; - core::core() + Core* Core::mpInstance = nullptr; + Core::Core() : mbIsInit(false) { } - core& core::GetInstance() + Core& Core::GetInstance() { if (!mpInstance) { - mpInstance = new core; + mpInstance = new Core; } return *mpInstance; } - void core::Shutdown() + void Core::Shutdown() { if (!mpInstance) return; @@ -38,7 +39,7 @@ namespace lunarium mpInstance = nullptr; } - void core::Initialize(const char* args, std::vector& listeners) + void Core::Initialize(int argc, char** argv, std::vector& listeners) { mpLog = Logger::GetInstance(); @@ -46,14 +47,16 @@ namespace lunarium { mpLog->AddListener(listeners[i]); } + + mpLog->Log(LogCategory::CORE, LogLevel::INFO, "Running Lunarium version %s", Version::GetVersion().ToString().c_str()); } - bool core::IsInit() const + bool Core::IsInit() const { return mbIsInit; } - const State& core::GetState() const + const State& Core::GetState() const { return mState; } diff --git a/src/core/core.h b/src/core/core.h index b05b55b..4946006 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -11,31 +11,32 @@ #include "state.h" #include +#include namespace lunarium { - class core + class Core { public: - static core& GetInstance(); + static Core& GetInstance(); static void Shutdown(); - void Initialize(const char* args, std::vector& listeners); + void Initialize(int argc, char** argv, std::vector& listeners); bool IsInit() const; const State& GetState() const; private: // DATA - static core* mpInstance; + static Core* mpInstance; bool mbIsInit; State mState; Logger* mpLog; private: // HIDDEN METHODS - core(); - core(const core&) = delete; - core& operator=(const core&) = delete; + Core(); + Core(const Core&) = delete; + Core& operator=(const Core&) = delete; }; } diff --git a/src/test_main.cpp b/src/test_main.cpp index 4f0fc86..a1cc886 100644 --- a/src/test_main.cpp +++ b/src/test_main.cpp @@ -10,6 +10,7 @@ #include "utils/OpRes.h" #include "core/state.h" #include "core/Version.h" +#include "utils/args.h" extern "C" { @@ -33,15 +34,39 @@ int main(int argc, char** argv) // VERSION TEST std::cout << "Hello yall\n"; - // std::cout << "This is " << argv[0] << " Version " << Lunarium_VERSION_MAJOR - // << "." << Lunarium_VERSION_MINOR - // << "." << Lunarium_VERSION_PATCH << '\n'; std::cout << "This is " << argv[0] << " Version " << lunarium::Version::GetVersion().ToString() << "\n"; glm::vec3 testVec = glm::vec3(1.0f, 2.0f, 3.0f); std::cout << "\ntestVec: (" << testVec.x << ", " << testVec.y << ", " << testVec.z << ")\n"; + // Args testing + std::vector sd; + sd.push_back({ "t", true}); + sd.push_back({ "d", true}); + sd.push_back({ "h", false}); + lunarium::Args args(argc, argv, '-', sd); + + if (args.ContainsSwitch("t")) + { + std::cout << "t switch is: " << args.GetSwitchValue("t") << "\n"; + } + + if (args.ContainsSwitch("d")) + { + std::cout << "d switch is: " << args.GetSwitchValue("d") << "\n"; + } + + if (args.ContainsSwitch("h")) + { + std::cout << "h switch is found!\n"; + } + + if (args.GetNumPositionalArgs() > 1) + { + std::cout << "First position argument: " << args.GetArgAtPosition(1) << std::endl; + } + // LUA TEST std::cout << "\nTesting LUA: a = 7 + 4\n"; lua_State* L = luaL_newstate(); diff --git a/src/utils/args.cpp b/src/utils/args.cpp new file mode 100644 index 0000000..2e70afd --- /dev/null +++ b/src/utils/args.cpp @@ -0,0 +1,123 @@ +/****************************************************************************** +* File - args.cpp +* Author - Joey Pollack +* Date - 2021/09/01 (y/m/d) +* Mod Date - 2021/09/01 (y/m/d) +* Description - Processes command line arguments. +******************************************************************************/ + +#include "Args.h" +#include + +namespace lunarium +{ + + Args::Args(int argc, char** argv, char switch_char, std::vector& switches) + : mNumArgs(argc), mSwitchChar(switch_char) + { + for (int i = 0; i < switches.size(); i++) + { + mSwitchHasValue.insert( { switches[i].symbol, switches[i].expect_value } ); + } + + for (int i = 0; i < mNumArgs; i++) + { + mArgs.push_back(std::string(argv[i])); + } + + Process(); + } + + const std::vector& Args::GetPositionalArgs() const + { + return mPositionalArgs; + } + + const std::map& Args::GetSwitchArgs() const + { + return mSwitchArgs; + } + + int Args::GetNumPositionalArgs() const + { + return mPositionalArgs.size(); + } + + // Does no error checking. + const std::string& Args::GetArgAtPosition(int pos) const + { + return mPositionalArgs[pos]; + } + + bool Args::ContainsSwitch(std::string s) const + { + return mSwitchArgs.find(s) != mSwitchArgs.end(); + } + + // Does no error checking. + const std::string& Args::GetSwitchValue(std::string s) const + { + return mSwitchArgs.find(s)->second; + } + + const std::vector& Args::GetRawArgs() const + { + return mArgs; + } + + void Args::Process() + { + for (int i = 0; i < mNumArgs; i++) + { + bool isSwitch = (mArgs[i][0] == mSwitchChar); + + if (isSwitch) + { + int curPos = 1; + std::ostringstream iss; + + // This is a switch need to store everything after the switch char + while (curPos < mArgs[i].size()) + { + iss << mArgs[i][curPos]; + curPos++; + } + + // Store the switch + std::string skey = iss.str(); + std::string svalue = ""; + + // check that this is a valid switch + auto siter = mSwitchHasValue.find(skey); + if (siter != mSwitchHasValue.end()) + { + // Need to also consume the next arg in the vector + // if this switch has a value + if (siter->second) + { + i++; + curPos = 0; + iss.str(""); + iss.clear(); + + while (curPos < mArgs[i].size()) + { + iss << mArgs[i][curPos]; + curPos++; + } + + svalue = iss.str(); + } + + mSwitchArgs.insert( { skey, svalue } ); + + } + + } + else + { + mPositionalArgs.push_back(mArgs[i]); + } + } + } +} \ No newline at end of file diff --git a/src/utils/args.h b/src/utils/args.h new file mode 100644 index 0000000..814b304 --- /dev/null +++ b/src/utils/args.h @@ -0,0 +1,59 @@ +/****************************************************************************** +* File - args.h +* Author - Joey Pollack +* Date - 2021/09/01 (y/m/d) +* Mod Date - 2021/09/01 (y/m/d) +* Description - Processes command line arguments. +******************************************************************************/ + +#ifndef ARGS_H_ +#define ARGS_H_ + +#include +#include +#include + +namespace lunarium +{ + class Args + { + public: + + struct SwitchDesc + { + std::string symbol; + bool expect_value; + }; + + public: + Args(int argc, char** argv, char switch_char, std::vector& switches); + + const std::vector& GetPositionalArgs() const; + const std::map& GetSwitchArgs() const; + + int GetNumPositionalArgs() const; + const std::string& GetArgAtPosition(int pos) const; + + bool ContainsSwitch(std::string) const; + const std::string& GetSwitchValue(std::string) const; + + const std::vector& GetRawArgs() const; + + private: + std::vector mPositionalArgs; + std::map mSwitchArgs; + + std::map mSwitchHasValue; + + // Raw args + char mSwitchChar; + int mNumArgs; + std::vector mArgs; + + private: // Helpers + void Process(); + + }; +} + +#endif // ARGS_H_ \ No newline at end of file