Contribute a failing to compile part of a CLI support implementation.
This commit is contained in:
@@ -244,7 +244,7 @@ COLLECT_FILES(false imguipiemenu_sources src/external/imguipiemenu ".c;.cpp;")
|
||||
set ( util_sources
|
||||
src/util/exception_to_string.cpp
|
||||
)
|
||||
COLLECT_FILES(false noggit_root_headers src/noggit ".h;.hpp")
|
||||
COLLECT_FILES(false noggit_root_headers src/noggit ".h;.hpp;.inl")
|
||||
COLLECT_FILES(true noggit_ui_headers src/noggit/ui ".h;.hpp")
|
||||
COLLECT_FILES(false math_headers src/math ".h;.hpp")
|
||||
COLLECT_FILES(false opengl_headers src/opengl ".h;.hpp")
|
||||
|
||||
@@ -33,7 +33,7 @@ file (READ "${_noggit_revision_template_file}" _template_blob)
|
||||
file (READ "${CMAKE_CURRENT_LIST_FILE}" _self_blob)
|
||||
string (SHA256 _state_hash "${_dirty_marker}${_revision}${_template_blob}${_self_blob}")
|
||||
|
||||
if (EXISTS ${_noggit_revision_output_file})
|
||||
if (EXISTS ${_noggit_revision_state_file})
|
||||
file (READ "${_noggit_revision_state_file}" _old_state_hash)
|
||||
if (_state_hash STREQUAL _old_state_hash)
|
||||
return()
|
||||
|
||||
157
src/noggit/Cli.cpp
Normal file
157
src/noggit/Cli.cpp
Normal file
@@ -0,0 +1,157 @@
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
#include "Cli.inl"
|
||||
|
||||
using namespace noggit;
|
||||
|
||||
template < typename Ty >
|
||||
concept CharOrCStr = std::is_same_v<Ty, char>
|
||||
|| std::is_same_v<Ty, char const*>;
|
||||
|
||||
template < CharOrCStr Str >
|
||||
struct ControllerException
|
||||
{
|
||||
explicit constexpr
|
||||
ControllerException ( Str arg )
|
||||
: arg{arg}
|
||||
{ }
|
||||
|
||||
Str arg;
|
||||
};
|
||||
|
||||
Cli::Cli
|
||||
(
|
||||
std::size_t argC,
|
||||
char const* const* argV
|
||||
)
|
||||
: _args(_countArgs(argC, argV))
|
||||
{
|
||||
try
|
||||
{
|
||||
std::size_t counter{};
|
||||
auto const findHandlerOrThrow{
|
||||
[ this ]
|
||||
< CharOrCStr Str >
|
||||
( Str str )
|
||||
-> ControllerHandler
|
||||
{
|
||||
auto const result{CliAssister::_findControllerInfo(str, _argMapping)};
|
||||
return result ? throw ControllerException{str} : result->second;
|
||||
}};
|
||||
|
||||
for(std::size_t i{}; i < argC; ++i)
|
||||
{
|
||||
if(argV[i][0] == '-')
|
||||
{
|
||||
if(argV[i][1] == '\0')
|
||||
throw "-";
|
||||
|
||||
if(argV[i][1] == '-')
|
||||
{
|
||||
if(argV[i][2] == '\0')
|
||||
throw "--";
|
||||
else
|
||||
{
|
||||
_args[i] = findHandlerOrThrow(&argV[i][2]);
|
||||
++counter;
|
||||
continue;
|
||||
}
|
||||
|
||||
for(std::size_t j{1}; argV[i][j]; ++j, ++counter)
|
||||
_args[counter] = findHandlerOrThrow(argV[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
_args[counter] = (argV[i]);
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
catch ( ControllerException<char> e )
|
||||
{
|
||||
std::cerr << "\nE: Unknown control flag: '" << e.arg << '\'';
|
||||
throw;
|
||||
}
|
||||
catch ( ControllerException<char const*> e )
|
||||
{
|
||||
std::cerr << "\nE: Unknown control statement: '" << e.arg << '\'';
|
||||
throw;
|
||||
}
|
||||
catch ( char const* str )
|
||||
{
|
||||
std::cerr << "\nE: Unknown parameter: '" << str << '\'';
|
||||
throw;
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
struct ControllerNotSatisfied
|
||||
{
|
||||
std::string_view name;
|
||||
};
|
||||
|
||||
auto Cli::exec ( )
|
||||
-> void
|
||||
{
|
||||
StateMachine state{};
|
||||
|
||||
try
|
||||
{
|
||||
for(auto arg{_args.cbegin()}; arg != _args.cend(); )
|
||||
{
|
||||
if(ControllerHandler const* handler{std::get_if<ControllerHandler>(&*arg)}
|
||||
; handler)
|
||||
{
|
||||
if(state.curHandler)
|
||||
throw ControllerNotSatisfied{*CliAssister::_findControllerInfo
|
||||
(state.curHandler, _nameMapping)};
|
||||
|
||||
(*handler)({}) || (state.curHandler = *handler);
|
||||
++arg;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
catch ( ControllerNotSatisfied e )
|
||||
{
|
||||
std::cerr << "\nE: Controller '" << e.name << "' expected an argument.";
|
||||
throw;
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
Cli::StateMachine::StateMachine ( )
|
||||
: curHandler{}, flags{Flags::doContinueExecution}
|
||||
{ }
|
||||
|
||||
constexpr
|
||||
auto Cli::_countArgs
|
||||
(
|
||||
std::size_t argC,
|
||||
char const* const* argV
|
||||
)
|
||||
-> std::size_t
|
||||
{
|
||||
std::size_t result{};
|
||||
|
||||
for(std::size_t i{}; i < argC; ++i)
|
||||
{
|
||||
if(argV[i][0] == '-' && argV[i][1] != '-' && argV[i][1] != '\0')
|
||||
{
|
||||
for(std::size_t j{1}; argV[i][j]; ++j, ++result);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
++result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
111
src/noggit/Cli.hpp
Normal file
111
src/noggit/Cli.hpp
Normal file
@@ -0,0 +1,111 @@
|
||||
#ifndef NOGGIT_SRC_NOGGIT_CLI_HPP
|
||||
#define NOGGIT_SRC_NOGGIT_CLI_HPP
|
||||
|
||||
#include <array>
|
||||
#include <initializer_list>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace noggit
|
||||
{
|
||||
using namespace std::literals;
|
||||
|
||||
class Cli
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
Cli
|
||||
(
|
||||
std::size_t argC,
|
||||
char const* const* argV
|
||||
);
|
||||
auto exec ( )
|
||||
-> void;
|
||||
private:
|
||||
static constexpr
|
||||
auto _countArgs
|
||||
(
|
||||
std::size_t argC,
|
||||
char const* const* argV
|
||||
)
|
||||
-> std::size_t;
|
||||
|
||||
typedef std::vector<std::variant<std::size_t, std::string>> ArgContainer;
|
||||
|
||||
struct ParamInfo
|
||||
{
|
||||
typedef auto(HandlerSignature)
|
||||
(
|
||||
ArgContainer::const_iterator begin,
|
||||
ArgContainer::const_iterator end
|
||||
)
|
||||
-> bool;
|
||||
|
||||
explicit constexpr
|
||||
ParamInfo
|
||||
(
|
||||
std::initializer_list<std::string_view> aliases,
|
||||
std::string_view name,
|
||||
HandlerSignature* handler
|
||||
);
|
||||
|
||||
std::vector<std::string_view> aliases;
|
||||
std::string_view name;
|
||||
HandlerSignature* handler;
|
||||
};
|
||||
|
||||
struct StateMachine
|
||||
{
|
||||
struct Flags
|
||||
{
|
||||
enum : std::size_t
|
||||
{
|
||||
IsControllerSatisfied = 0x1,
|
||||
doContinueExecution = 0x2
|
||||
};
|
||||
};
|
||||
|
||||
StateMachine ( );
|
||||
|
||||
std::size_t curParamIdx;
|
||||
std::size_t flags;
|
||||
};
|
||||
|
||||
static constexpr
|
||||
std::array paramInfos
|
||||
{
|
||||
ParamInfo{{"r", "recovery"}, "Recovery", nullptr}
|
||||
};
|
||||
ArgContainer _args;
|
||||
};
|
||||
|
||||
template < typename Ty >
|
||||
concept ControllerInfo = std::is_same_v<Ty, std::string_view>
|
||||
|| std::is_same_v<Ty, Cli::ControllerHandler>;
|
||||
|
||||
class CliAssister
|
||||
{
|
||||
private:
|
||||
friend class Cli;
|
||||
|
||||
template
|
||||
<
|
||||
ControllerInfo Key,
|
||||
ControllerInfo Value,
|
||||
std::size_t n
|
||||
>
|
||||
requires ( !std::is_same_v<Key, Value> )
|
||||
static constexpr
|
||||
auto _findControllerInfo
|
||||
(
|
||||
Key key,
|
||||
std::array<std::pair<Key, Value>, n> const& info
|
||||
)
|
||||
-> std::optional<Value>;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //NOGGIT_SRC_NOGGIT_CLI_HPP
|
||||
37
src/noggit/Cli.inl
Normal file
37
src/noggit/Cli.inl
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef NOGGIT_SRC_NOGGIT_CLI_INL
|
||||
#define NOGGIT_SRC_NOGGIT_CLI_INL
|
||||
|
||||
#include <algorithm>
|
||||
#include "Cli.hpp"
|
||||
|
||||
namespace noggit
|
||||
{
|
||||
template
|
||||
<
|
||||
ControllerInfo Key,
|
||||
ControllerInfo Value,
|
||||
std::size_t n
|
||||
>
|
||||
requires ( !std::is_same_v<Key, Value> )
|
||||
constexpr
|
||||
auto CliAssister::_findControllerInfo
|
||||
(
|
||||
Key key,
|
||||
std::array<std::pair<Key, Value>, n> const& info
|
||||
)
|
||||
-> std::optional<Value>
|
||||
{
|
||||
auto const result{std::find_if(info.cbegin(), info.cend(),
|
||||
[ key ]
|
||||
( std::pair<Key, Value> const& pair )
|
||||
-> bool
|
||||
{
|
||||
return pair.first == key;
|
||||
})};
|
||||
|
||||
return result == info.cend() ? std::nullopt
|
||||
: std::optional{result->second};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //NOGGIT_SRC_NOGGIT_CLI_INL
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "MapHeaders.h"
|
||||
/*#include "MapHeaders.h"
|
||||
#include "MPQ.h"
|
||||
#include "MakeshiftMt.hpp"
|
||||
|
||||
@@ -145,3 +145,4 @@ MakeshiftMt::~MakeshiftMt( void )
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#include <QStyleFactory>
|
||||
|
||||
#include "revision.h"
|
||||
|
||||
#include "Cli.hpp"
|
||||
|
||||
class Noggit
|
||||
{
|
||||
@@ -341,6 +341,12 @@ namespace
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* command-line mode */
|
||||
if(argc > 1)
|
||||
{
|
||||
noggit::Cli{static_cast<std::size_t>(argc), argv}.exec();
|
||||
}
|
||||
|
||||
noggit::RegisterErrorHandlers();
|
||||
std::set_terminate (noggit_terminate_handler);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user