Compare commits
4 Commits
be08a97275
...
b53999a548
Author | SHA1 | Date |
---|---|---|
![]() |
b53999a548 | |
![]() |
379903d751 | |
![]() |
17792ec5bf | |
![]() |
9ce35b5c6b |
|
@ -61,6 +61,7 @@ create_directory bin/tools
|
||||||
COMPILE_COMMANDS=(
|
COMPILE_COMMANDS=(
|
||||||
"$CXX_WITH_FLAGS src/tools/dumpnbt.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -l:cli.so -o bin/tools/dumpnbt"
|
"$CXX_WITH_FLAGS src/tools/dumpnbt.cpp -I./include -Lbin/lib -l:nbt.so -l:javacompat.so -l:cli.so -o bin/tools/dumpnbt"
|
||||||
"$CXX_WITH_FLAGS src/tools/arraydump.cpp -I./include -Lbin/lib -l:file.so -l:cli.so -o bin/tools/arraydump"
|
"$CXX_WITH_FLAGS src/tools/arraydump.cpp -I./include -Lbin/lib -l:file.so -l:cli.so -o bin/tools/arraydump"
|
||||||
|
"$CXX_WITH_FLAGS src/tools/baseconvert.cpp -I./include -Lbin/lib -l:cli.so -o bin/tools/baseconvert"
|
||||||
#"$CXX_WITH_FLAGS src/tools/hexnet.cpp -I./include -Lbin/lib -l:cli.so -l:libsockpp.so -o bin/tools/hexnet"
|
#"$CXX_WITH_FLAGS src/tools/hexnet.cpp -I./include -Lbin/lib -l:cli.so -l:libsockpp.so -o bin/tools/hexnet"
|
||||||
)
|
)
|
||||||
for command in ${!COMPILE_COMMANDS[@]}; do
|
for command in ${!COMPILE_COMMANDS[@]}; do
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
echo "================================================================================"
|
||||||
|
echo -n "Testing \`baseconvert\`... "
|
||||||
|
|
||||||
|
[ $(baseconvert -d "0xFFFFFFFFFFFFFFFF") = "18446744073709551615" ] \
|
||||||
|
&& [ $(baseconvert -x "0xFFFFFFFFFFFFFFFF") = "0xffffffffffffffff" ] \
|
||||||
|
&& [ $(baseconvert -o "0xFFFFFFFFFFFFFFFF") = "01777777777777777777777" ] \
|
||||||
|
&& [ $(baseconvert -b "0xFFFFFFFFFFFFFFFF") = "0b1111111111111111111111111111111111111111111111111111111111111111" ] \
|
||||||
|
&& [ $(baseconvert -x "0XFFFFFFFFFFFFFFFF") = "0xffffffffffffffff" ] \
|
||||||
|
&& [ $(baseconvert -d "0") = "0" ] \
|
||||||
|
&& [ $(baseconvert -x "0") = "0x0" ] \
|
||||||
|
&& [ $(baseconvert -o "0") = "0" ] \
|
||||||
|
&& [ $(baseconvert -b "0") = "0b0" ] \
|
||||||
|
&& [ $(baseconvert -b "4") = "0b100" ] \
|
||||||
|
&& [ $(baseconvert -x "07777" ) = "0xfff" ] \
|
||||||
|
&& [ $(baseconvert -x "0o7777" ) = "0xfff" ] \
|
||||||
|
&& [ $(baseconvert -x "0O7777" ) = "0xfff" ] \
|
||||||
|
&& [ $(baseconvert -o "0b1000" ) = "010" ] \
|
||||||
|
&& [ $(baseconvert -o "0B1000" ) = "010" ] \
|
||||||
|
&& echo "PASS" \
|
||||||
|
|| echo "FAIL"
|
||||||
|
echo "================================================================================"
|
|
@ -1,5 +1,8 @@
|
||||||
// Copyright 2022, FOSS-VG Developers and Contributers
|
// Copyright 2022, FOSS-VG Developers and Contributers
|
||||||
//
|
//
|
||||||
|
// Author(s):
|
||||||
|
// BodgeMaster, Shwoomple
|
||||||
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify it
|
// This program is free software: you can redistribute it and/or modify it
|
||||||
// under the terms of the GNU Affero General Public License as published
|
// under the terms of the GNU Affero General Public License as published
|
||||||
// by the Free Software Foundation, version 3.
|
// by the Free Software Foundation, version 3.
|
||||||
|
@ -318,6 +321,10 @@ namespace CLI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->additionalInfo != "") {
|
||||||
|
usageString += "\nAdditional Info:\n\n\t" + this->additionalInfo + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
return usageString;
|
return usageString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -746,5 +746,19 @@ int main() {
|
||||||
ASSERT(noCLIParser.getUsage() == "Help: universecreator\n\n\tCreate a universe with a banana and an apple.\n\nUsage: universecreator \n");
|
ASSERT(noCLIParser.getUsage() == "Help: universecreator\n\n\tCreate a universe with a banana and an apple.\n\nUsage: universecreator \n");
|
||||||
std::cout << "Passed no CLI input usage test." << std::endl;
|
std::cout << "Passed no CLI input usage test." << std::endl;
|
||||||
|
|
||||||
|
// additional info test ############################################
|
||||||
|
std::vector<CLI::Flag> additionalInfoCLIFlags;
|
||||||
|
|
||||||
|
std::vector<CLI::Option> additionalInfoCLIOptions;
|
||||||
|
|
||||||
|
std::vector<CLI::Argument> additionalInfoCLIArguments;
|
||||||
|
|
||||||
|
const char** additionalInfoCLICommand = new const char*[1];
|
||||||
|
additionalInfoCLICommand[0] = "universecreator";
|
||||||
|
CLI::ArgumentsParser additionalInfoCLIParser = CLI::ArgumentsParser(1, additionalInfoCLICommand, additionalInfoCLIFlags, additionalInfoCLIOptions, additionalInfoCLIArguments, "Create a universe with a banana and an apple.", "Rick Astley was here.");
|
||||||
|
|
||||||
|
ASSERT(additionalInfoCLIParser.getUsage() == "Help: universecreator\n\n\tCreate a universe with a banana and an apple.\n\nUsage: universecreator \n\nAdditional Info:\n\n\tRick Astley was here.\n");
|
||||||
|
std::cout << "Passed additional info test." << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,9 @@ int main(){
|
||||||
ASSERT(generic.serialize(&vector).errorCode == ErrorCodes::INVALID_TYPE);
|
ASSERT(generic.serialize(&vector).errorCode == ErrorCodes::INVALID_TYPE);
|
||||||
ASSERT(generic.serializeWithoutHeader(&vector).isError);
|
ASSERT(generic.serializeWithoutHeader(&vector).isError);
|
||||||
ASSERT(generic.serializeWithoutHeader(&vector).errorCode == ErrorCodes::INVALID_TYPE);
|
ASSERT(generic.serializeWithoutHeader(&vector).errorCode == ErrorCodes::INVALID_TYPE);
|
||||||
|
// Normally, at this point, we would discard the vector as garbage.
|
||||||
|
// In this case, the assertions below exist to test the common
|
||||||
|
// serializer code.
|
||||||
ASSERT(vector.size() == 6);
|
ASSERT(vector.size() == 6);
|
||||||
ASSERT(
|
ASSERT(
|
||||||
vector.at(0) == 255 &&
|
vector.at(0) == 255 &&
|
||||||
|
@ -46,6 +49,8 @@ int main(){
|
||||||
vector.at(4) == 0 &&
|
vector.at(4) == 0 &&
|
||||||
vector.at(5) == 0
|
vector.at(5) == 0
|
||||||
);
|
);
|
||||||
|
generic.name = tiny_utf8::string(std::string(0x10000, 'E'));
|
||||||
|
ASSERT(generic.serialize(&vector).isError && generic.serialize(&vector).errorCode == ErrorCodes::OVERRUN);
|
||||||
vector.clear();
|
vector.clear();
|
||||||
std::cout << "Passed Generic (super type) test." << std::endl;
|
std::cout << "Passed Generic (super type) test." << std::endl;
|
||||||
|
|
||||||
|
@ -68,7 +73,6 @@ int main(){
|
||||||
ASSERT(!int8_0.serialize(&vector).isError);
|
ASSERT(!int8_0.serialize(&vector).isError);
|
||||||
ASSERT(!int8_1.serialize(&vector).isError);
|
ASSERT(!int8_1.serialize(&vector).isError);
|
||||||
ASSERT(vector.size() == 20);
|
ASSERT(vector.size() == 20);
|
||||||
std::cout << (int) vector.at(9) << std::endl;
|
|
||||||
ASSERT(
|
ASSERT(
|
||||||
vector.at( 0) == 1 &&
|
vector.at( 0) == 1 &&
|
||||||
vector.at( 1) == 0 &&
|
vector.at( 1) == 0 &&
|
||||||
|
@ -112,10 +116,225 @@ int main(){
|
||||||
vector.clear();
|
vector.clear();
|
||||||
std::cout << "Passed Int8 test." << std::endl;
|
std::cout << "Passed Int8 test." << std::endl;
|
||||||
|
|
||||||
//NBT::Tag::Int16 int16_0 = NBT::Tag::Int16();
|
NBT::Tag::Int16 int16_0 = NBT::Tag::Int16();
|
||||||
//int16_0.name = "int16_0";
|
int16_0.name = "int16_0";
|
||||||
//int16_0.setValue(32767);
|
int16_0.setValue(-32768);
|
||||||
//TODO: Check that we actually get overrun when trying to store a name that's too long
|
NBT::Tag::Int16 int16_1 = NBT::Tag::Int16("int16_1", 32767);
|
||||||
|
ASSERT(int16_0.getValue() == -0x8000);
|
||||||
|
ASSERT(int16_1.getValue() == 0x7FFF);
|
||||||
|
ASSERT(int16_0.getTagType() == 2 && int16_1.getTagType() == 2);
|
||||||
|
ASSERT(!int16_0.serialize(&vector).isError);
|
||||||
|
ASSERT(!int16_1.serialize(&vector).isError);
|
||||||
|
ASSERT(vector.size() == 24);
|
||||||
|
ASSERT(
|
||||||
|
vector.at( 0) == 2 &&
|
||||||
|
vector.at( 1) == 0 &&
|
||||||
|
vector.at( 2) == 7 &&
|
||||||
|
vector.at( 3) == 'i' &&
|
||||||
|
vector.at( 4) == 'n' &&
|
||||||
|
vector.at( 5) == 't' &&
|
||||||
|
vector.at( 6) == '1' &&
|
||||||
|
vector.at( 7) == '6' &&
|
||||||
|
vector.at( 8) == '_' &&
|
||||||
|
vector.at( 9) == '0' &&
|
||||||
|
vector.at(10) == 0x80 &&
|
||||||
|
vector.at(11) == 0x00 &&
|
||||||
|
vector.at(12) == 2 &&
|
||||||
|
vector.at(13) == 0 &&
|
||||||
|
vector.at(14) == 7 &&
|
||||||
|
vector.at(15) == 'i' &&
|
||||||
|
vector.at(16) == 'n' &&
|
||||||
|
vector.at(17) == 't' &&
|
||||||
|
vector.at(18) == '1' &&
|
||||||
|
vector.at(19) == '6' &&
|
||||||
|
vector.at(20) == '_' &&
|
||||||
|
vector.at(21) == '1' &&
|
||||||
|
vector.at(22) == 0x7F &&
|
||||||
|
vector.at(23) == 0xFF
|
||||||
|
);
|
||||||
|
vector.clear();
|
||||||
|
int16_0.name = "";
|
||||||
|
ASSERT(!int16_0.serialize(&vector).isError);
|
||||||
|
ASSERT(vector.size() == 5);
|
||||||
|
ASSERT(
|
||||||
|
vector.at(0) == 2 &&
|
||||||
|
vector.at(1) == 0 &&
|
||||||
|
vector.at(2) == 0 &&
|
||||||
|
vector.at(3) == 0x80 &&
|
||||||
|
vector.at(4) == 0
|
||||||
|
);
|
||||||
|
vector.clear();
|
||||||
|
ASSERT(!int16_0.serializeWithoutHeader(&vector).isError);
|
||||||
|
ASSERT(!int16_1.serializeWithoutHeader(&vector).isError);
|
||||||
|
ASSERT(vector.size() == 4);
|
||||||
|
ASSERT(
|
||||||
|
vector.at(0) == 0x80 &&
|
||||||
|
vector.at(1) == 0 &&
|
||||||
|
vector.at(2) == 0x7F &&
|
||||||
|
vector.at(3) == 0xFF
|
||||||
|
);
|
||||||
|
vector.clear();
|
||||||
|
std::cout << "Passed Int16 test." << std::endl;
|
||||||
|
|
||||||
|
NBT::Tag::Int32 int32_0 = NBT::Tag::Int32();
|
||||||
|
int32_0.name = "int32_0";
|
||||||
|
int32_0.setValue(-2147483648);
|
||||||
|
NBT::Tag::Int32 int32_1 = NBT::Tag::Int32("int32_1", 2147483647);
|
||||||
|
ASSERT(int32_0.getValue() == (int32_t) -0x80000000);
|
||||||
|
ASSERT(int32_1.getValue() == 0x7FFFFFFF);
|
||||||
|
ASSERT(int32_0.getTagType() == 3 && int32_1.getTagType() == 3);
|
||||||
|
ASSERT(!int32_0.serialize(&vector).isError);
|
||||||
|
ASSERT(!int32_1.serialize(&vector).isError);
|
||||||
|
ASSERT(vector.size() == 28);
|
||||||
|
ASSERT(
|
||||||
|
vector.at( 0) == 3 &&
|
||||||
|
vector.at( 1) == 0 &&
|
||||||
|
vector.at( 2) == 7 &&
|
||||||
|
vector.at( 3) == 'i' &&
|
||||||
|
vector.at( 4) == 'n' &&
|
||||||
|
vector.at( 5) == 't' &&
|
||||||
|
vector.at( 6) == '3' &&
|
||||||
|
vector.at( 7) == '2' &&
|
||||||
|
vector.at( 8) == '_' &&
|
||||||
|
vector.at( 9) == '0' &&
|
||||||
|
vector.at(10) == 0x80 &&
|
||||||
|
vector.at(11) == 0x00 &&
|
||||||
|
vector.at(12) == 0x00 &&
|
||||||
|
vector.at(13) == 0x00 &&
|
||||||
|
vector.at(14) == 3 &&
|
||||||
|
vector.at(15) == 0 &&
|
||||||
|
vector.at(16) == 7 &&
|
||||||
|
vector.at(17) == 'i' &&
|
||||||
|
vector.at(18) == 'n' &&
|
||||||
|
vector.at(19) == 't' &&
|
||||||
|
vector.at(20) == '3' &&
|
||||||
|
vector.at(21) == '2' &&
|
||||||
|
vector.at(22) == '_' &&
|
||||||
|
vector.at(23) == '1' &&
|
||||||
|
vector.at(24) == 0x7F &&
|
||||||
|
vector.at(25) == 0xFF &&
|
||||||
|
vector.at(26) == 0xFF &&
|
||||||
|
vector.at(27) == 0xFF
|
||||||
|
);
|
||||||
|
vector.clear();
|
||||||
|
int32_0.name = "";
|
||||||
|
ASSERT(!int32_0.serialize(&vector).isError);
|
||||||
|
ASSERT(vector.size() == 7);
|
||||||
|
ASSERT(
|
||||||
|
vector.at(0) == 3 &&
|
||||||
|
vector.at(1) == 0 &&
|
||||||
|
vector.at(2) == 0 &&
|
||||||
|
vector.at(3) == 0x80 &&
|
||||||
|
vector.at(4) == 0 &&
|
||||||
|
vector.at(5) == 0 &&
|
||||||
|
vector.at(6) == 0
|
||||||
|
);
|
||||||
|
vector.clear();
|
||||||
|
ASSERT(!int32_0.serializeWithoutHeader(&vector).isError);
|
||||||
|
ASSERT(!int32_1.serializeWithoutHeader(&vector).isError);
|
||||||
|
ASSERT(vector.size() == 8);
|
||||||
|
ASSERT(
|
||||||
|
vector.at(0) == 0x80 &&
|
||||||
|
vector.at(1) == 0 &&
|
||||||
|
vector.at(2) == 0 &&
|
||||||
|
vector.at(3) == 0 &&
|
||||||
|
vector.at(4) == 0x7F &&
|
||||||
|
vector.at(5) == 0xFF &&
|
||||||
|
vector.at(6) == 0xFF &&
|
||||||
|
vector.at(7) == 0xFF
|
||||||
|
);
|
||||||
|
vector.clear();
|
||||||
|
std::cout << "Passed Int32 test." << std::endl;
|
||||||
|
|
||||||
|
NBT::Tag::Int64 int64_0 = NBT::Tag::Int64();
|
||||||
|
int64_0.name = "int64_0";
|
||||||
|
int64_0.setValue(-9223372036854775808);
|
||||||
|
NBT::Tag::Int64 int64_1 = NBT::Tag::Int64("int64_1", 9223372036854775807);
|
||||||
|
ASSERT(int64_0.getValue() == (int64_t) -0x8000000000000000);
|
||||||
|
ASSERT(int64_1.getValue() == 0x7FFFFFFFFFFFFFFF);
|
||||||
|
ASSERT(int64_0.getTagType() == 4 && int64_1.getTagType() == 4);
|
||||||
|
ASSERT(!int64_0.serialize(&vector).isError);
|
||||||
|
ASSERT(!int64_1.serialize(&vector).isError);
|
||||||
|
ASSERT(vector.size() == 36);
|
||||||
|
ASSERT(
|
||||||
|
vector.at( 0) == 4 &&
|
||||||
|
vector.at( 1) == 0 &&
|
||||||
|
vector.at( 2) == 7 &&
|
||||||
|
vector.at( 3) == 'i' &&
|
||||||
|
vector.at( 4) == 'n' &&
|
||||||
|
vector.at( 5) == 't' &&
|
||||||
|
vector.at( 6) == '6' &&
|
||||||
|
vector.at( 7) == '4' &&
|
||||||
|
vector.at( 8) == '_' &&
|
||||||
|
vector.at( 9) == '0' &&
|
||||||
|
vector.at(10) == 0x80 &&
|
||||||
|
vector.at(11) == 0x00 &&
|
||||||
|
vector.at(12) == 0x00 &&
|
||||||
|
vector.at(13) == 0x00 &&
|
||||||
|
vector.at(14) == 0x00 &&
|
||||||
|
vector.at(15) == 0x00 &&
|
||||||
|
vector.at(16) == 0x00 &&
|
||||||
|
vector.at(17) == 0x00 &&
|
||||||
|
vector.at(18) == 4 &&
|
||||||
|
vector.at(19) == 0 &&
|
||||||
|
vector.at(20) == 7 &&
|
||||||
|
vector.at(21) == 'i' &&
|
||||||
|
vector.at(22) == 'n' &&
|
||||||
|
vector.at(23) == 't' &&
|
||||||
|
vector.at(24) == '6' &&
|
||||||
|
vector.at(25) == '4' &&
|
||||||
|
vector.at(26) == '_' &&
|
||||||
|
vector.at(27) == '1' &&
|
||||||
|
vector.at(28) == 0x7F &&
|
||||||
|
vector.at(29) == 0xFF &&
|
||||||
|
vector.at(30) == 0xFF &&
|
||||||
|
vector.at(31) == 0xFF &&
|
||||||
|
vector.at(32) == 0xFF &&
|
||||||
|
vector.at(33) == 0xFF &&
|
||||||
|
vector.at(34) == 0xFF &&
|
||||||
|
vector.at(35) == 0xFF
|
||||||
|
);
|
||||||
|
vector.clear();
|
||||||
|
int64_0.name = "";
|
||||||
|
ASSERT(!int64_0.serialize(&vector).isError);
|
||||||
|
ASSERT(vector.size() == 11);
|
||||||
|
ASSERT(
|
||||||
|
vector.at( 0) == 4 &&
|
||||||
|
vector.at( 1) == 0 &&
|
||||||
|
vector.at( 2) == 0 &&
|
||||||
|
vector.at( 3) == 0x80 &&
|
||||||
|
vector.at( 4) == 0 &&
|
||||||
|
vector.at( 5) == 0 &&
|
||||||
|
vector.at( 6) == 0 &&
|
||||||
|
vector.at( 7) == 0 &&
|
||||||
|
vector.at( 8) == 0 &&
|
||||||
|
vector.at( 9) == 0 &&
|
||||||
|
vector.at(10) == 0
|
||||||
|
);
|
||||||
|
vector.clear();
|
||||||
|
ASSERT(!int64_0.serializeWithoutHeader(&vector).isError);
|
||||||
|
ASSERT(!int64_1.serializeWithoutHeader(&vector).isError);
|
||||||
|
ASSERT(vector.size() == 16);
|
||||||
|
ASSERT(
|
||||||
|
vector.at( 0) == 0x80 &&
|
||||||
|
vector.at( 1) == 0 &&
|
||||||
|
vector.at( 2) == 0 &&
|
||||||
|
vector.at( 3) == 0 &&
|
||||||
|
vector.at( 4) == 0 &&
|
||||||
|
vector.at( 5) == 0 &&
|
||||||
|
vector.at( 6) == 0 &&
|
||||||
|
vector.at( 7) == 0 &&
|
||||||
|
vector.at( 8) == 0x7F &&
|
||||||
|
vector.at( 9) == 0xFF &&
|
||||||
|
vector.at(10) == 0xFF &&
|
||||||
|
vector.at(11) == 0xFF &&
|
||||||
|
vector.at(12) == 0xFF &&
|
||||||
|
vector.at(13) == 0xFF &&
|
||||||
|
vector.at(14) == 0xFF &&
|
||||||
|
vector.at(15) == 0xFF
|
||||||
|
);
|
||||||
|
vector.clear();
|
||||||
|
std::cout << "Passed Int64 test." << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@ int main(int argc, char* argv[]) {
|
||||||
CLI::ArgumentsParser cliParser = CLI::ArgumentsParser(argc, argv, flags, options, arguments, "Dump files as C++ array literals");
|
CLI::ArgumentsParser cliParser = CLI::ArgumentsParser(argc, argv, flags, options, arguments, "Dump files as C++ array literals");
|
||||||
|
|
||||||
if (cliParser.getFlag("help").value) {
|
if (cliParser.getFlag("help").value) {
|
||||||
std::cout << "I was here" << std::endl;
|
|
||||||
std::cout << cliParser.getUsage() << std::endl;
|
std::cout << cliParser.getUsage() << std::endl;
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
// Copyright 2022, FOSS-VG Developers and Contributers
|
||||||
|
//
|
||||||
|
// Author(s):
|
||||||
|
// BodgeMaster
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify it
|
||||||
|
// under the terms of the GNU Affero General Public License as published
|
||||||
|
// by the Free Software Foundation, version 3.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied
|
||||||
|
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
// See the GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// version 3 along with this program.
|
||||||
|
// If not, see https://www.gnu.org/licenses/agpl-3.0.en.html
|
||||||
|
|
||||||
|
#include <bitset>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../lib/cli.hpp"
|
||||||
|
|
||||||
|
#define EXIT_SUCCESS 0
|
||||||
|
#define EXIT_RUNTIME 1
|
||||||
|
#define EXIT_USAGE 2
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
std::vector<CLI::Flag> flags;
|
||||||
|
flags.push_back(CLI::Flag('x', "hexadecimal", "base 16"));
|
||||||
|
flags.push_back(CLI::Flag('o', "octal", "base 8"));
|
||||||
|
flags.push_back(CLI::Flag('b', "binary", "base 2"));
|
||||||
|
flags.push_back(CLI::Flag('d', "decimal", "base 10"));
|
||||||
|
flags.push_back(CLI::Flag('h', "help", "print help and exit"));
|
||||||
|
flags.push_back(CLI::Flag('l', "license", "print license information and exit"));
|
||||||
|
std::vector<CLI::Option> options;
|
||||||
|
std::vector<CLI::Argument> arguments;
|
||||||
|
arguments.push_back(CLI::Argument("NUMBER", "the number to convert"));
|
||||||
|
CLI::ArgumentsParser cliParser = CLI::ArgumentsParser(argc, argv, flags, options, arguments, "Convert numbers between predefined bases", "This only works for unsigned numbers.\n\tBaseConvert understands the prefixes 0x, 0b, 0o, and 0 in input numbers.");
|
||||||
|
|
||||||
|
if (cliParser.getFlag("help").value) {
|
||||||
|
std::cout << cliParser.getUsage() << std::endl;
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cliParser.getFlag("license").value){
|
||||||
|
std::cout
|
||||||
|
<< "Copyright 2022, FOSS-VG Developers and Contributers\n"
|
||||||
|
<< "\n"
|
||||||
|
<< "BaseConvert is part of the FOSS-VG development tool suite.\n"
|
||||||
|
<< "\n"
|
||||||
|
<< "This program is free software: you can redistribute it and/or modify it\n"
|
||||||
|
<< "under the terms of the GNU Affero General Public License as published\n"
|
||||||
|
<< "by the Free Software Foundation, version 3.\n"
|
||||||
|
<< "\n"
|
||||||
|
<< "This program is distributed in the hope that it will be useful,\n"
|
||||||
|
<< "but WITHOUT ANY WARRANTY; without even the implied\n"
|
||||||
|
<< "warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
|
||||||
|
<< "See the GNU Affero General Public License for more details.\n"
|
||||||
|
<< "\n"
|
||||||
|
<< "You should have received a copy of the GNU Affero General Public License\n"
|
||||||
|
<< "version 3 along with this program.\n"
|
||||||
|
<< "If not, see https://www.gnu.org/licenses/agpl-3.0.en.html"
|
||||||
|
<< std::endl;
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cliParser.wrongUsage) {
|
||||||
|
std::cout << cliParser.getUsage() << std::endl;
|
||||||
|
return EXIT_USAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string numberString = cliParser.getArgument(0).value;
|
||||||
|
uint8_t base = 10;
|
||||||
|
uint64_t* number = new uint64_t;
|
||||||
|
|
||||||
|
if (numberString == "") {
|
||||||
|
std::cerr << "Empty string is not a valid number." << std::endl;
|
||||||
|
return EXIT_RUNTIME;
|
||||||
|
}
|
||||||
|
if (numberString[0] == '0') {
|
||||||
|
if (numberString.substr(0, 2)=="0x" || numberString.substr(0, 2)=="0X") {
|
||||||
|
base = 16;
|
||||||
|
numberString = numberString.substr(2, numberString.length()-2);
|
||||||
|
} else if (numberString.substr(0, 2)=="0b" || numberString.substr(0, 2)=="0B") {
|
||||||
|
base = 2;
|
||||||
|
numberString = numberString.substr(2, numberString.length()-2);
|
||||||
|
} else if (numberString.substr(0, 2)=="0o" || numberString.substr(0, 2)=="0O") {
|
||||||
|
base = 8;
|
||||||
|
numberString = numberString.substr(2, numberString.length()-2);
|
||||||
|
} else {
|
||||||
|
base = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*number = std::stoull(numberString, nullptr, base);
|
||||||
|
|
||||||
|
if (cliParser.getFlag("hexadecimal").value) {
|
||||||
|
std::cout << "0x" << std::hex << *number << std::endl;
|
||||||
|
} else if (cliParser.getFlag("octal").value) {
|
||||||
|
*number==0? std::cout << "0" << std::endl : std::cout << "0" << std::oct << *number << std::endl;
|
||||||
|
} else if (cliParser.getFlag("binary").value) {
|
||||||
|
std::bitset<64> bitset = std::bitset<64>(*number);
|
||||||
|
bool foundFirstBit = false;
|
||||||
|
std::cout << "0b";
|
||||||
|
for (uint8_t i=0; i<64; i++) {
|
||||||
|
if (bitset[63-i]) {
|
||||||
|
std::cout << "1";
|
||||||
|
foundFirstBit = true;
|
||||||
|
} else if (foundFirstBit) {
|
||||||
|
std::cout << "0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundFirstBit) {
|
||||||
|
std::cout << "0";
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
} else if (cliParser.getFlag("decimal").value) {
|
||||||
|
std::cout << *number << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << cliParser.getUsage() << std::endl;
|
||||||
|
return EXIT_USAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete number;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Loading…
Reference in New Issue