Skip to content

Commit

Permalink
merge(gui): Args Parsing
Browse files Browse the repository at this point in the history
Args Parsing
  • Loading branch information
ManuelR-T authored May 21, 2024
2 parents 2d161e1 + fa01ae4 commit 18f2eec
Show file tree
Hide file tree
Showing 9 changed files with 345 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
zappy_server
zappy_ai
zappy_gui

doc/html
*.o

Cargo.lock
Expand Down
29 changes: 7 additions & 22 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,17 @@
## Makefile
##

all: gui server ai
MODULES := gui server ai

gui:
@make -C gui

ai:
@make -C ai
all: zappy_gui zappy_server zappy_ai

server:
@make -C server
zappy_%:
@make -C $*

clean:
@make clean -C gui
@make clean -C ai
@make clean -C server

fclean:
@make fclean -C gui
@make fclean -C ai
@make fclean -C server

tests_run:
@make tests_run -C gui
@make tests_run -C ai
@make tests_run -C server
clean fclean tests_run:
$(foreach M,$(MODULES), make -C $M $@;)

re: fclean all

.PHONY: all clean fclean re gui ai server tests_run
.PHONY: clean fclean re tests_run
2 changes: 1 addition & 1 deletion doxy.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = Raytracer
PROJECT_NAME = Zappy
PROJECT_NUMBER = 1.0
PROJECT_BRIEF =
PROJECT_LOGO =
Expand Down
13 changes: 10 additions & 3 deletions gui/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@ CFLAGS = -Wall -Wextra -Werror -std=c++20

NAME = ../zappy_gui

SRC = $(BASE_SRC)
BASE_SRC = src/Main.cpp
SRC = $(BASE_SRC) \
$(addsuffix .cpp, \
$(addprefix src/, \
$(addprefix ArgParser/, \
ArgParser \
) \
) \
)
BASE_SRC = src/main.cpp

OBJ = $(SRC:.cpp=.o)

Expand All @@ -38,7 +45,7 @@ $(TEST_NAME): $(SRC) $(TEST_SRC)
-o $(TEST_NAME)

tests_run: $(TEST_NAME)
./$(TEST_NAME)
./$(TEST_NAME) -h 123 -p 123123

re: fclean all

Expand Down
120 changes: 120 additions & 0 deletions gui/src/ArgParser/ArgParser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
** EPITECH PROJECT, 2024
** Zappy
** File description:
** ArgParser
*/

#include "ArgParser.hpp"

bool ArgParser::has(const std::string &param) const
{
return params_.find(param) != params_.end();
}

template <>
bool ArgParser::get<bool>(const std::string &param) const
{
if (params_.find(param) == params_.end()) {
throw ArgParserException(
"Parameter not found: " + param, "ArgParser::get"
);
} else if (types_.at(param) != typeid(bool).name()) {
throw ArgParserException(
"Type mismatch for parameter: " + param, "ArgParser::get"
);
}
std::string value = params_.at(param);
if (value == "true") {
return true;
} else if (value == "false") {
return false;
} else {
throw ArgParserException(
"Invalid value for bool: " + value, "ArgParser::get<bool>"
);
}
}

template <>
std::string ArgParser::get<std::string>(const std::string &param) const
{
if (params_.find(param) == params_.end()) {
throw ArgParserException(
"Parameter not found: " + param, "ArgParser::get"
);
}
return params_.at(param);
}

void ArgParser::checkMandatoryArgs(const std::set<std::string> &providedArgs
) const
{
for (const auto &arg : mandatoryArgs_) {
if (providedArgs.find(arg) == providedArgs.end()) {
throw ArgParserException(
"Mandatory parameter missing: " + arg,
"ArgParser::checkMandatoryArgs"
);
}
}
}

bool ArgParser::isValidType(const std::string &key, const std::string &value)
const
{
std::istringstream ss(value);
if (types_.at(key) == typeid(int).name()) {
int intValue;
ss >> intValue;
return !ss.fail() && ss.eof();
} else if (types_.at(key) == typeid(bool).name()) {
return (value == "true" || value == "false");
} else if (types_.at(key) == typeid(std::string).name()) {
return true;
}
return false;
}

void ArgParser::parse(int argc, char *argv[])
{
std::set<std::string> providedArgs;

for (int i = 1; i < argc; i++) {
std::string param(argv[i]);

if (param[0] == '-') {
std::string key = param.substr(1);

if (i + 1 < argc) {
std::string value = argv[++i];

if (types_.find(key) != types_.end()) {
if (!isValidType(key, value)) {
throw ArgParserException(
"Invalid value for parameter: " + key,
"ArgParser::parseArgs"
);
}
params_[key] = value;
providedArgs.insert(key);
} else {
throw ArgParserException(
"Unknown parameter: " + key, "ArgParser::parseArgs"
);
}
} else {
throw ArgParserException(
"Missing value for parameter: " + key,
"ArgParser::parseArgs"
);
}
} else {
throw ArgParserException(
"Invalid parameter format: " + param, "ArgParser::parseArgs"
);
}
}

checkMandatoryArgs(providedArgs);
}
121 changes: 121 additions & 0 deletions gui/src/ArgParser/ArgParser.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
** EPITECH PROJECT, 2024
** Zappy
** File description:
** ArgParser
*/

#pragma once

#include <map>
#include <set>
#include <sstream>
#include <string>
#include <typeinfo>

#include "ArgParserException.hpp"

/**
* @class ArgParser
* @brief A class to parse and handle command-line arguments.
*
* This class provides methods to parse command-line arguments, set default
* values for parameters, check for the presence of parameters, and retrieve
* parameter values with type safety.
*/
class ArgParser {
public:
ArgParser() = default;
~ArgParser() = default;

/**
* @brief Parses command-line arguments.
*
* @param argc The number of command-line arguments.
* @param argv The array of command-line arguments.
*/
void parse(int argc, char *argv[]);

/**
* @brief Checks if a parameter is present.
*
* @param param The name of the parameter to check.
* @return true if the parameter is present, false otherwise.
*/
bool has(const std::string &param) const;

/**
* @brief Sets a default value for a parameter.
*
* @tparam T The type of the parameter value.
* @param param The name of the parameter.
* @param value The default value of the parameter.
* @param mandatory Whether the parameter is mandatory (default is false).
* @return A reference to the ArgParser object.
*/
template <typename T>
ArgParser &setDefault(
const std::string &param,
T value,
bool mandatory = false
)
{
std::stringstream ss;
ss << value;
params_[param] = ss.str();
types_[param] = typeid(T).name();
if (mandatory) {
mandatoryArgs_.insert(param);
}
return *this;
}

/**
* @brief Retrieves the value of a parameter.
*
* @tparam T The type of the parameter value.
* @param param The name of the parameter.
* @return The value of the parameter.
* @throws ArgParserException if the parameter is not found or if there is a
* type mismatch.
*/
template <typename T>
T get(const std::string &param) const
{
if (params_.find(param) == params_.end()) {
throw ArgParserException(
"Parameter not found: " + param, "ArgParser::get"
);
} else if (types_.at(param) != typeid(T).name()) {
throw ArgParserException(
"Type mismatch for parameter: " + param, "ArgParser::get"
);
}
std::istringstream ss(params_.at(param));
T value;

ss >> value;
return value;
}

private:
std::map<std::string, std::string> params_;
std::map<std::string, std::string> types_;
std::set<std::string> mandatoryArgs_;
/**
* @brief Checks if all mandatory arguments are provided.
*
* @param providedArgs The set of provided argument names.
* @throws ArgParserException if a mandatory argument is missing.
*/
void checkMandatoryArgs(const std::set<std::string> &providedArgs) const;

/**
* @brief Validates the type of a parameter value.
*
* @param key The name of the parameter.
* @param value The value of the parameter as a string.
* @return true if the type is valid, false otherwise.
*/
bool isValidType(const std::string &key, const std::string &value) const;
};
53 changes: 53 additions & 0 deletions gui/src/ArgParser/ArgParserException.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
** EPITECH PROJECT, 2024
** Zappy
** File description:
** ArgParserException
*/

#pragma once

#include <exception>
#include <string>

/**
* @class ArgParserException
* @brief Exception class for argument parser errors.
*/
class ArgParserException : public std::exception {
public:
/**
* @brief Constructs an ArgParserException.
*
* @param what A description of the error.
* @param where The location where the exception was thrown (default: "?").
*/
ArgParserException(const std::string &what, const std::string &where = "?")
: what_(what), where_(where)
{
}

/**
* @brief Returns the description of the error.
*
* @return A C-string containing the error description.
*/
const char *what() const noexcept override
{
return what_.c_str();
}

/**
* @brief Returns the location where the exception was thrown.
*
* @return A C-string containing the location description.
*/
const char *where() const noexcept
{
return where_.c_str();
}

private:
std::string what_;
std::string where_;
};
11 changes: 0 additions & 11 deletions gui/src/Main.cpp

This file was deleted.

Loading

0 comments on commit 18f2eec

Please sign in to comment.