Compare commits
4 Commits
b18a97713d
...
efa4fa560e
Author | SHA1 | Date |
---|---|---|
BodgeMaster | efa4fa560e | |
BodgeMaster | 4c3d2fdbbf | |
BodgeMaster | 3b1d288d1e | |
BodgeMaster | 362ec5f4f9 |
|
@ -73,7 +73,7 @@ mkdir -pv bin/tools
|
||||||
# add compile commands to this array
|
# add compile commands to this array
|
||||||
COMPILE_COMMANDS=(
|
COMPILE_COMMANDS=(
|
||||||
"$CXX_WITH_FLAGS src/tools/dumpnbt.cpp -Lbin/lib -l:nbt.so -o bin/tools/dumpnbt"
|
"$CXX_WITH_FLAGS src/tools/dumpnbt.cpp -Lbin/lib -l:nbt.so -o bin/tools/dumpnbt"
|
||||||
"$CXX_WITH_FLAGS src/tools/hexnet.cpp -Ldependencies/sockpp-0.7.1/build -l:libsockpp.so -Idependencies/sockpp-0.7.1/include -o bin/tools/hexnet"
|
"$CXX_WITH_FLAGS src/tools/hexnet.cpp -Lbin/lib -l:cli.so -l:libsockpp.so -Idependencies/sockpp-0.7.1/include -o bin/tools/hexnet"
|
||||||
)
|
)
|
||||||
for command in ${!COMPILE_COMMANDS[@]}; do
|
for command in ${!COMPILE_COMMANDS[@]}; do
|
||||||
echo "${COMPILE_COMMANDS[command]}"
|
echo "${COMPILE_COMMANDS[command]}"
|
||||||
|
|
|
@ -19,5 +19,11 @@ rm -rv ./bin
|
||||||
rm -vf .endianness
|
rm -vf .endianness
|
||||||
rm -vf resources/check_endianness
|
rm -vf resources/check_endianness
|
||||||
mkdir -v ./bin
|
mkdir -v ./bin
|
||||||
|
mkdir -v ./bin/lib
|
||||||
|
|
||||||
|
ln -vs ../../dependencies/sockpp-0.7.1/build/libsockpp.so bin/lib/
|
||||||
|
ln -vs ../../dependencies/sockpp-0.7.1/build/libsockpp.so.0 bin/lib/
|
||||||
|
ln -vs ../../dependencies/sockpp-0.7.1/build/libsockpp.so.0.7.1 bin/lib/
|
||||||
|
|
||||||
set -v
|
set -v
|
||||||
echo -n "" > ./bin/.placeholder
|
echo -n "" > ./bin/.placeholder
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace CLI {
|
||||||
}
|
}
|
||||||
|
|
||||||
// using int here bc that's how main() is defined
|
// using int here bc that's how main() is defined
|
||||||
ArgumentsParser::ArgumentsParser(int argc, const char* argv[], std::vector<Flag> flags, std::vector<UnpositionalArgument> unpositionalArguments, std::vector<PositionalArgument> positionalArguments) {
|
ArgumentsParser::ArgumentsParser(int argc, const char* const argv[], std::vector<Flag> flags, std::vector<UnpositionalArgument> unpositionalArguments, std::vector<PositionalArgument> positionalArguments) {
|
||||||
this->wrongUsage = false;
|
this->wrongUsage = false;
|
||||||
this->wrongUsageMessages = std::vector<std::string>();
|
this->wrongUsageMessages = std::vector<std::string>();
|
||||||
this->programName = std::string(argv[0]);
|
this->programName = std::string(argv[0]);
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace CLI {
|
||||||
std::vector<std::string> wrongUsageMessages;
|
std::vector<std::string> wrongUsageMessages;
|
||||||
|
|
||||||
// using int here bc that's how main() is defined
|
// using int here bc that's how main() is defined
|
||||||
ArgumentsParser(int argc, const char* argv[], std::vector<Flag> flags, std::vector<UnpositionalArgument> unpositionalArguments, std::vector<PositionalArgument> positionalArguments);
|
ArgumentsParser(int argc, const char* const argv[], std::vector<Flag> flags, std::vector<UnpositionalArgument> unpositionalArguments, std::vector<PositionalArgument> positionalArguments);
|
||||||
~ArgumentsParser();
|
~ArgumentsParser();
|
||||||
|
|
||||||
ErrorOr<bool> getFlag(char shortName);
|
ErrorOr<bool> getFlag(char shortName);
|
||||||
|
|
|
@ -34,7 +34,6 @@ int main(int argc, char* argv[]) {
|
||||||
// test -0 -ab -12345 --long-flag -cconcatenated -d separate-value -efdouble-concatenated "positional argument 0" -gh concatenated-separate-value --long-argument-with-value-included="included value" --long-argument-with-value-separated "separate value" "positional argument 1" "positional argument 2"
|
// test -0 -ab -12345 --long-flag -cconcatenated -d separate-value -efdouble-concatenated "positional argument 0" -gh concatenated-separate-value --long-argument-with-value-included="included value" --long-argument-with-value-separated "separate value" "positional argument 1" "positional argument 2"
|
||||||
|
|
||||||
std::vector<CLI::Flag> flags;
|
std::vector<CLI::Flag> flags;
|
||||||
//flags.push_back(CLI::Flag(shortName, longName, description));
|
|
||||||
flags.push_back(CLI::Flag('0', "00000", "a short flag on its own"));
|
flags.push_back(CLI::Flag('0', "00000", "a short flag on its own"));
|
||||||
flags.push_back(CLI::Flag('a', "aaaaa", "concatenated short flags"));
|
flags.push_back(CLI::Flag('a', "aaaaa", "concatenated short flags"));
|
||||||
flags.push_back(CLI::Flag('b', "bbbbb", "concatenated short flags"));
|
flags.push_back(CLI::Flag('b', "bbbbb", "concatenated short flags"));
|
||||||
|
@ -148,6 +147,7 @@ int main(int argc, char* argv[]) {
|
||||||
ASSERT(parser.getPositionalArgument(2).value=="positional argument 2");
|
ASSERT(parser.getPositionalArgument(2).value=="positional argument 2");
|
||||||
ASSERT(!parser.getUnpositionalArgument('z').isError);
|
ASSERT(!parser.getUnpositionalArgument('z').isError);
|
||||||
ASSERT(parser.getUnpositionalArgument('z').errorCode == ErrorCodes::NOT_PRESENT);
|
ASSERT(parser.getUnpositionalArgument('z').errorCode == ErrorCodes::NOT_PRESENT);
|
||||||
|
ASSERT(parser.getUnpositionalArgument('z').value == std::string(""));
|
||||||
|
|
||||||
std::cout << "Passed valid input test." << std::endl;
|
std::cout << "Passed valid input test." << std::endl;
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
|
||||||
#define usage std::cerr << "Usage: " << argv[0] << " [-4|-6] [-t|-u] <<host> <port> | -l <port>>" << std::endl << "<port> may be hexadecimal (prefixed with 0x) or binary (prefixed with 0b)." << std::endl
|
#include "../lib/error.h++"
|
||||||
|
#include "../lib/cli.h++"
|
||||||
|
|
||||||
#define EXIT_SUCCESS 0
|
#define EXIT_SUCCESS 0
|
||||||
#define EXIT_RUNTIME 1
|
#define EXIT_RUNTIME 1
|
||||||
|
@ -33,117 +34,47 @@ int main(int argc, char* argv[]){
|
||||||
bool tcp = true;
|
bool tcp = true;
|
||||||
bool udp = true;
|
bool udp = true;
|
||||||
bool listen = false;
|
bool listen = false;
|
||||||
std::string host = "";
|
std::string host;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
if (argc<2) {
|
|
||||||
usage;
|
|
||||||
return EXIT_USAGE;
|
|
||||||
}
|
|
||||||
for (int i=1; i<argc; i++) {
|
|
||||||
std::string argument(argv[i]);
|
|
||||||
if (argument=="-4") {
|
|
||||||
ipv4 = true;
|
|
||||||
ipv6 = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (argument=="-6") {
|
|
||||||
ipv4 = false;
|
|
||||||
ipv6 = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (argument=="-t") {
|
|
||||||
tcp = true;
|
|
||||||
udp = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (argument=="-u") {
|
|
||||||
tcp = false;
|
|
||||||
udp = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (argument=="-l") {
|
|
||||||
listen = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (argument=="-h") {
|
|
||||||
usage;
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
if (argument=="--help") {
|
|
||||||
usage;
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
if (!listen && i==argc-2) {
|
|
||||||
host = argument;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (i==argc-1) {
|
|
||||||
if (!listen && host=="") {
|
|
||||||
std::cerr << "Not running in listen mode and no host specified." << std::endl;
|
|
||||||
return EXIT_USAGE;
|
|
||||||
}
|
|
||||||
if (argument.substr(0, 2)=="0b" || argument.substr(0, 2)=="0B") {
|
|
||||||
// check for 16 bit binary number
|
|
||||||
for (char const &digit : argument.substr(2,argument.length())) {
|
|
||||||
if (digit=='0' || digit=='1') {
|
|
||||||
;
|
|
||||||
} else {
|
|
||||||
std::cerr << argument << " is not a valid port." << std::endl;
|
|
||||||
usage;
|
|
||||||
return EXIT_USAGE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (argument.length()>18) {
|
|
||||||
std::cerr << argument << " is too big for a valid port." << std::endl;
|
|
||||||
usage;
|
|
||||||
return EXIT_USAGE;
|
|
||||||
}
|
|
||||||
port = (uint16_t) std::stoul(argument.substr(2, argument.length()), nullptr, 2);
|
|
||||||
} else if (argument.substr(0, 2)=="0x" || argument.substr(0, 2)=="0X") {
|
|
||||||
// check for four digit hex number
|
|
||||||
for (char const &digit : argument.substr(2,argument.length())) {
|
|
||||||
if (std::isxdigit(digit)==0) {
|
|
||||||
std::cerr << argument << " is not a valid port." << digit << std::endl;
|
|
||||||
usage;
|
|
||||||
return EXIT_USAGE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (argument.length()>6) {
|
|
||||||
std::cerr << argument << " is too big for a valid port." << std::endl;
|
|
||||||
usage;
|
|
||||||
return EXIT_USAGE;
|
|
||||||
}
|
|
||||||
port = (uint16_t) std::stoul(argument.substr(2, argument.length()), nullptr, 16);
|
|
||||||
} else {
|
|
||||||
// check for decimal number between 0 and 65536 exclusively
|
|
||||||
for (char const &digit : argument) {
|
|
||||||
if (std::isdigit(digit)==0) {
|
|
||||||
std::cerr << argument << " is not a valid port." << std::endl;
|
|
||||||
usage;
|
|
||||||
return EXIT_USAGE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// using unsigned long here because that's how stoul()
|
|
||||||
// is defined
|
|
||||||
unsigned long argumentNumber = std::stoul(argument, nullptr, 10);
|
|
||||||
if (argumentNumber > 65535) {
|
|
||||||
std::cerr << argument << " is too big for a valid port." << std::endl;
|
|
||||||
usage;
|
|
||||||
return EXIT_USAGE;
|
|
||||||
}
|
|
||||||
port = (uint16_t) argumentNumber;
|
|
||||||
}
|
|
||||||
break; // last argument anyway
|
|
||||||
}
|
|
||||||
usage;
|
|
||||||
return EXIT_USAGE;
|
|
||||||
}
|
|
||||||
// Argument parsing end ############################################
|
|
||||||
|
|
||||||
if (!listen) {
|
std::vector<CLI::Flag> flags;
|
||||||
//TODO: verify that host is possibly a valid host (or usage error)
|
flags.push_back(CLI::Flag('4', "ipv4", "use IPv4, defaults to both when -4 and -6 are omitted, otherwise uses what is specified"));
|
||||||
//TODO: look up host if necessary, determine IPv4 or IPv6 mode if necessary
|
flags.push_back(CLI::Flag('6', "ipv6", "use IPv6, defaults to both when -4 and -6 are omitted, otherwise uses what is specified"));
|
||||||
std::cerr << "Client mode not implemented" << std::endl;
|
flags.push_back(CLI::Flag('t', "tcp", "use TCP, defaults to both when -t and -u are omitted, otherwise uses what is specified"));
|
||||||
return EXIT_UNIMPLEMENTED;
|
flags.push_back(CLI::Flag('u', "udp", "use UDP, defaults to both when -t and -u are omitted, otherwise uses what is specified"));
|
||||||
|
|
||||||
|
std::vector<CLI::UnpositionalArgument> unpositionalArguments;
|
||||||
|
unpositionalArguments.push_back(CLI::UnpositionalArgument('c', "connect", "HOST", "connect to HOST, listen for incoming connections if omitted"));
|
||||||
|
|
||||||
|
std::vector<CLI::PositionalArgument> positionalArguments;
|
||||||
|
positionalArguments.push_back(CLI::PositionalArgument("PORT", "the port to use"));
|
||||||
|
|
||||||
|
CLI::ArgumentsParser cliParser = CLI::ArgumentsParser(argc, argv, flags, unpositionalArguments, positionalArguments);
|
||||||
|
|
||||||
|
if (cliParser.wrongUsage) {
|
||||||
|
//TODO: spit out usage information generated by the parser
|
||||||
|
return EXIT_USAGE;
|
||||||
}
|
}
|
||||||
|
if (cliParser.getFlag('4').value || cliParser.getFlag('6').value) {
|
||||||
|
ipv4 = cliParser.getFlag('4').value;
|
||||||
|
ipv6 = cliParser.getFlag('6').value;
|
||||||
|
}
|
||||||
|
if (cliParser.getFlag('t').value || cliParser.getFlag('u').value) {
|
||||||
|
tcp = cliParser.getFlag('t').value;
|
||||||
|
udp = cliParser.getFlag('u').value;
|
||||||
|
}
|
||||||
|
if (cliParser.getUnpositionalArgument('c').errorCode == ErrorCodes::NOT_PRESENT) {
|
||||||
|
listen = true;
|
||||||
|
}
|
||||||
|
host = cliParser.getUnpositionalArgument('c').value;
|
||||||
|
//FIXME: use a function that returns a fixed-width data type instead
|
||||||
|
port = (uint16_t) std::stoi(cliParser.getPositionalArgument(0).value);
|
||||||
|
|
||||||
|
std::cerr << "Port: " << (int) port << std::endl;
|
||||||
|
std::cerr << (listen? "Listening" : "Host: ") << host << std::endl;
|
||||||
|
std::cerr << "IPv4: " << (ipv4? "yes" : "no") << std::endl;
|
||||||
|
std::cerr << "IPv6: " << (ipv6? "yes" : "no") << std::endl;
|
||||||
|
std::cerr << "TCP: " << ( tcp? "yes" : "no") << std::endl;
|
||||||
|
std::cerr << "UDP: " << ( udp? "yes" : "no") << std::endl;
|
||||||
|
return EXIT_UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue