117 lines
4.3 KiB
C++
117 lines
4.3 KiB
C++
////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// A slash-command parser. The intended use is as follows:
|
|
//
|
|
// SlashCommandParser parser(Command);
|
|
//
|
|
// if parser.Parse("/command1", "syntax1") { ... handle command1 ... }
|
|
// else if parser.Parse("/command2", "syntax2") { ... handle command2 ... }
|
|
// else if parser.Parse("/command3", "syntax3") { ... handle command3 ... }
|
|
// else { ... print an error message ... }
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <string_view>
|
|
#include <map>
|
|
#include <cstdint>
|
|
|
|
class SlashCommandParser
|
|
{
|
|
public:
|
|
struct Value
|
|
{
|
|
std::string s_;
|
|
int64_t i_;
|
|
double d_;
|
|
Value(const std::string &s) : s_(s), i_(0), d_(0) {}
|
|
Value(int64_t i) : s_(), i_(i), d_(0) {}
|
|
Value(double d) : s_(), i_(0), d_(d) {}
|
|
};
|
|
std::vector<Value> args_;
|
|
|
|
private:
|
|
int cursor_;
|
|
std::string command_;
|
|
std::string line_;
|
|
int linelen_;
|
|
std::string error_;
|
|
|
|
static bool ascii_isupper(char c) { return (c >= 'A') && (c <= 'Z'); }
|
|
static bool ascii_islower(char c) { return (c >= 'a') && (c <= 'z'); }
|
|
static bool ascii_isdigit(char c) { return (c >= '0') && (c <= '9'); }
|
|
static bool ascii_isalpha(char c) { return ascii_isupper(c) || ascii_islower(c); }
|
|
static bool ascii_isalnum(char c) { return ascii_isalpha(c) || ascii_isdigit(c); }
|
|
static bool ascii_isspace(char c) { return (c==0)||(c==' ')||(c=='\t')||(c=='\r')||(c=='\n')||(c=='\f')||(c=='\v'); }
|
|
|
|
void skip_white();
|
|
std::string read_word();
|
|
void not_enough_args(const std::string &cmd);
|
|
|
|
|
|
public:
|
|
// Initialize the slash-command parser with the full command line.
|
|
//
|
|
// The command line is stored. The first keyword (the slash-command
|
|
// itself) is extracted and stored. If the command-line doesn't
|
|
// start with a slash-command, an error message is stored.
|
|
//
|
|
// After initializing the parser, you should call Parse once
|
|
// for every known command.
|
|
//
|
|
SlashCommandParser(std::string_view Line);
|
|
|
|
// Parse: Try to parse a slash-command.
|
|
//
|
|
// The intent is that you should call 'Parse' once for every
|
|
// known command. Hopefully, one of these 'Parse' commands
|
|
// will return true. If not, then the command couldn't be parsed.
|
|
//
|
|
// You must pass in the name of a slash-command (eg, "/compile")
|
|
// followed by the argument types that the command accepts.
|
|
//
|
|
// The argument types are represented as a string containing the
|
|
// characters i (for int64), s (for string), and d (for double).
|
|
// For example, if ArgTypes is "sid", then the command expects a
|
|
// string, then an int64, then a double.
|
|
//
|
|
// If the command matches, and the arguments parse correctly,
|
|
// returns true, stores the parsed arguments, and clears the
|
|
// stored error message.
|
|
//
|
|
// If the command matches, but the syntax is wrong, returns false
|
|
// and stores the error message.
|
|
//
|
|
// If the command doesn't match, returns false.
|
|
//
|
|
bool Parse(std::string_view Command, std::string_view ArgTypes);
|
|
|
|
// Error: Declare that parsing has failed, and get an error message.
|
|
//
|
|
// You call this if you tried calling Parse on every known command,
|
|
// and none of the Parse calls returned true. Returns an error
|
|
// message indicating what went wrong.
|
|
//
|
|
std::string Error() const;
|
|
|
|
// Get the Nth argument.
|
|
//
|
|
// After Parse returns true, the parsed arguments are stored in the
|
|
// SlashCommandParser. You can use these functions to fetch the
|
|
// parsed arguments.
|
|
//
|
|
// For example, if you call Parse("/hello", "sid") and it returns
|
|
// true, you should then call StringArg(0), then IntArg(1), then
|
|
// DoubleArg(2) to get all the arguments.
|
|
//
|
|
std::string StringArg(int n) const;
|
|
int64_t IntArg(int n) const;
|
|
double DoubleArg(int n) const;
|
|
};
|
|
|
|
|
|
|