diff --git a/.gitignore b/.gitignore index 149298d..9b935aa 100644 --- a/.gitignore +++ b/.gitignore @@ -180,4 +180,4 @@ build/ .html/ .latex/ -out/ \ No newline at end of file +out/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 198c830..b29c88c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,8 +12,12 @@ find_package(libelf REQUIRED) # Find package dependancies list(APPEND CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/build/Debug/generators") -#Linking Libraries -add_executable(${PROJECT_NAME} src/main.cpp src/elf_parser.cpp src/gcc_parse.cpp) +#Creating Executable Target +add_executable(${PROJECT_NAME} src/main.cpp + src/elf_parser.cpp + src/gcc_parse.cpp + src/state_machine.cpp + src/concrete_states.cpp) #Linking Libraries target_link_libraries(${PROJECT_NAME} PUBLIC ctre::ctre libelf::libelf) diff --git a/include/concrete_states.hpp b/include/concrete_states.hpp new file mode 100644 index 0000000..52bc02a --- /dev/null +++ b/include/concrete_states.hpp @@ -0,0 +1,52 @@ +#pragma once +#include +#include "./state.hpp" + +class UserInputState : public State { + public: + void enter(StateContext& context) override; + void handle(StateContext& context) override; + State* exit(StateContext& context) override; +}; + +class ElfParserState : public State { + public: + void enter(StateContext& context) override; + void handle(StateContext& context) override; + State* exit(StateContext& context) override; +}; + +class CallgraphState : public State { + public: + void enter(StateContext& context) override; + void handle(StateContext& context) override; + State* exit(StateContext& context) override; +}; + +class AbiParserState : public State { + public: + void enter(StateContext& context) override; + void handle(StateContext& context) override; + State* exit(StateContext& context) override; +}; + +class ValidatorState : public State { + public: + void enter(StateContext& context) override; + void handle(StateContext& context) override; + State* exit(StateContext& context) override; +}; + +class OutputState : public State { + public: + void enter(StateContext& context) override; + void handle(StateContext& context) override; + State* exit(StateContext& context) override; +}; + +class ErrorState : public State { + public: + void enter(StateContext& context) override; + void handle(StateContext& context) override; + State* exit(StateContext& context) override; +}; \ No newline at end of file diff --git a/include/state.hpp b/include/state.hpp new file mode 100644 index 0000000..cce5b68 --- /dev/null +++ b/include/state.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "./state_machine.hpp" +#include "./state_context.hpp" + +class State { + public: + virtual void enter(StateContext& context) = 0; + virtual void handle(StateContext& context) = 0; + virtual State* exit(StateContext& context) = 0; + + virtual ~State() = default; +}; \ No newline at end of file diff --git a/include/state_context.hpp b/include/state_context.hpp new file mode 100644 index 0000000..dd4a806 --- /dev/null +++ b/include/state_context.hpp @@ -0,0 +1,15 @@ +#pragma once + +/** + * @brief Content in this is temporary. Please change + * them according to what the state desires. All data relating to + * SAFE will be stored here and shared between the states. + * + */ +class StateContext { + public: + void inc_data() {data++;} + int get_data() {return data;} + private: + int data = 0; +}; \ No newline at end of file diff --git a/include/state_machine.hpp b/include/state_machine.hpp new file mode 100644 index 0000000..19ffeec --- /dev/null +++ b/include/state_machine.hpp @@ -0,0 +1,18 @@ +#pragma once +#include "./state.hpp" +#include "./state_context.hpp" + +class State; + +class StateMachine { + public: + StateMachine(); + ~StateMachine(); + State* get_current_state(); + void run_state(); + void transition_state(State* new_state); + private: + State *current_state; + StateContext context; +}; + diff --git a/src/concrete_states.cpp b/src/concrete_states.cpp new file mode 100644 index 0000000..c3eef7a --- /dev/null +++ b/src/concrete_states.cpp @@ -0,0 +1,128 @@ +#include "../include/concrete_states.hpp" +#include "../include/state.hpp" +#include "../include/state_machine.hpp" + +/** + * @brief Content for each of function is temporary. Please change + * them according to what the state desires + * + */ + + +void UserInputState::enter(StateContext& context) { + std::print("Enter User Input State\n"); + std::print("Previous Number: {}\n", context.get_data()); +} + +void UserInputState::handle(StateContext& context) { + std::print("Handle User Input State\n"); + context.inc_data(); +} + +State* UserInputState::exit(StateContext& context) { + std::print("Exit User Input State\n-------------\n"); + std::ignore = context; + return new ElfParserState; +} + + +void ElfParserState::enter(StateContext& context) { + std::print("Enter Elf Parser State\n"); + std::print("Previous Number: {}\n", context.get_data()); +} + +void ElfParserState::handle(StateContext& context) { + std::print("Handle Elf Parser State\n"); + context.inc_data(); +} + +State* ElfParserState::exit(StateContext& context) { + std::print("Exit Elf Parser State\n-------------\n"); + std::ignore = context; + return new CallgraphState; +} + + +void CallgraphState::enter(StateContext& context) { + std::print("Enter Callgraph State\n"); + std::print("Previous Number: {}\n", context.get_data()); +} + +void CallgraphState::handle(StateContext& context) { + std::ignore = context; + std::print("Handle Callgraph State\n"); +} + +State* CallgraphState::exit(StateContext& context) { + std::print("Exit Callgraph State\n-------------\n"); + std::ignore = context; + return new AbiParserState; +} + + +void AbiParserState::enter(StateContext& context) { + std::print("Enter ABI Parser State\n"); + std::print("Previous Number: {}\n", context.get_data()); +} + +void AbiParserState::handle(StateContext& context) { + std::print("Handle ABI Parser State\n"); + context.inc_data(); +} + +State* AbiParserState::exit(StateContext& context) { + std::print("Exit ABI Parser State\n-------------\n"); + std::ignore = context; + return new ValidatorState; +} + + +void ValidatorState::enter(StateContext& context) { + std::print("Enter Validator State\n"); + std::print("Previous Number: {}\n", context.get_data()); +} + +void ValidatorState::handle(StateContext& context) { + std::print("Handle Validator State\n"); + context.inc_data(); +} + +State* ValidatorState::exit(StateContext& context) { + std::print("Exit Validator State\n-------------\n"); + std::ignore = context; + return new OutputState; +} + + +void OutputState::enter(StateContext& context) { + std::print("Enter Output State\n"); + std::print("Previous Number: {}\n", context.get_data()); +} + +void OutputState::handle(StateContext& context) { + std::print("Handle Output State\n"); + context.inc_data(); +} + +State* OutputState::exit(StateContext& context) { + std::print("Exit Output State\n-------------\n"); + std::ignore = context; + return nullptr; +} + + +void ErrorState::enter(StateContext& context) { + std::print("Enter Error State\n"); + std::ignore = context; +} + +void ErrorState::handle(StateContext& context) { + std::print("Handle Error State\n"); + std::ignore = context; +} + +State* ErrorState::exit(StateContext& context) { + std::print("Exit Error State\n-------------\n"); + std::ignore = context; + return nullptr; +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 803741c..6a74de6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,10 @@ * @copyright Copyright (c) 2025 * */ +#include "state.hpp" +#include "state_context.hpp" +#include "concrete_states.hpp" + #include #include @@ -16,5 +20,12 @@ int main(int argc, char** argv) std::ignore = argc; std::ignore = argv; std::println("Hello C++: {}", __cplusplus); + + StateMachine sm; + + while(sm.get_current_state() != nullptr){ + sm.run_state(); + } + return 0; } diff --git a/src/state_machine.cpp b/src/state_machine.cpp new file mode 100644 index 0000000..bcf79cd --- /dev/null +++ b/src/state_machine.cpp @@ -0,0 +1,27 @@ +#include "../include/state.hpp" +#include "../include/concrete_states.hpp" +#include "../include/state_machine.hpp" + +#include + +StateMachine::StateMachine(){ + current_state = new UserInputState; +} + +StateMachine::~StateMachine() { + delete current_state; +} + +State * StateMachine::get_current_state(){ + return current_state; +} + +void StateMachine::run_state() { + current_state->enter(context); + current_state->handle(context); + transition_state (current_state->exit(context)); +} + +void StateMachine::transition_state(State* new_state) { + this->current_state = new_state; +} \ No newline at end of file