L
@Schlangenmensch So?
#include <map>
#include <vector>
#include <algorithm>
#include <iostream>
#include <string>
enum class Symbol
{
NA,
SLEEP,
TARGET,
ACTION1,
ACTION2
};
enum class Action
{
A,
B,
C
};
typedef struct action_args
{
std::string target;
int val;
int magic;
int sleep;
} ACTION_ARGS;
void action1(std::string target, int val)
{
std::cout << "action1: " << target << ", " << val << std::endl;
}
void action2(std::string target, int val, int magic)
{
std::cout << "action2: " << target << ", " << val << ", " << magic << std::endl;
}
void action3(int sleep)
{
std::cout << "action3: " << sleep << std::endl;
}
void exitApp(std::string cause)
{
std::cout << "WRONG: " << cause << std::endl;
std::exit(0);
}
int main(int argc, char *argv[])
{
// default values
std::string target = "0.0.0.0";
int sleep = 1000;
std::map<int, std::map<Symbol, int>> fsm;
fsm[0][Symbol::SLEEP] = 1;
fsm[0][Symbol::TARGET] = 2;
fsm[0][Symbol::ACTION1] = 3;
fsm[0][Symbol::ACTION2] = 3;
fsm[1][Symbol::TARGET] = 3;
fsm[1][Symbol::ACTION1] = 3;
fsm[1][Symbol::ACTION2] = 3;
fsm[2][Symbol::SLEEP] = 3;
fsm[2][Symbol::ACTION1] = 3;
fsm[2][Symbol::ACTION2] = 3;
fsm[3][Symbol::ACTION1] = 3;
fsm[3][Symbol::ACTION2] = 3;
std::vector<std::pair<Action, ACTION_ARGS>> actions;
// parse command line
int i = 1;
int state = 0;
while (i < argc)
{
std::string arg{argv[i++]};
size_t equals = arg.find('=');
if (equals != std::string::npos)
{
std::string key = arg.substr(0, equals);
std::string value = arg.substr(equals + 1);
Symbol symbol = Symbol::NA;
if (key == "sleep")
{
symbol = Symbol::SLEEP;
}
if (key == "target")
{
symbol = Symbol::TARGET;
}
if (key == "a")
{
symbol = Symbol::ACTION1;
}
if (key == "b")
{
symbol = Symbol::ACTION2;
}
if (symbol == Symbol::NA)
{
exitApp("Unkown arg");
}
if (!fsm[state].count(symbol))
{
exitApp("Not allowed arg");
}
if (symbol == Symbol::SLEEP)
{
sleep = std::stoi(value);
}
if (symbol == Symbol::TARGET)
{
target = value;
}
if (symbol == Symbol::ACTION1)
{
actions.emplace_back(std::pair(Action::A, ACTION_ARGS{target, std::stoi(value), -1, sleep}));
actions.emplace_back(std::pair(Action::C, ACTION_ARGS{"", -1, -1, sleep}));
}
if (symbol == Symbol::ACTION2)
{
actions.emplace_back(std::pair(Action::B, ACTION_ARGS{target, std::stoi(value), 1000, sleep}));
actions.emplace_back(std::pair(Action::C, ACTION_ARGS{"", -1, -1, sleep}));
}
state = fsm[state][symbol];
}
}
if (actions.empty())
{
exitApp("No args ...");
}
actions.pop_back(); // Pop last unneeded action
// Perfom actions
for (const auto &action : actions)
{
const auto &a = action.second;
switch (action.first)
{
case Action::A:
{
action1(a.target, a.val);
break;
}
case Action::B:
{
action2(a.target, a.val, a.magic);
break;
}
case Action::C:
{
action3(a.sleep);
break;
}
default:
exitApp("Should not happen");
}
}
return 0;
}
Ungetestet. Und es ist länger geworden... Das muss doch irgendwie eleganter und robuster gehen?
$ ./a.out target=localhost sleep=2500 a=123 a=23 b=34 a=1
action1: localhost, 123
action3: 2500
action1: localhost, 23
action3: 2500
action2: localhost, 34, 1000
action3: 2500
action1: localhost, 1
Was ist, wenn stoi einen schlechten Tag hat? Und... das ACTION_ARGS ist doch unschön.