#include #include #include #include #include #include #include #define HELP 1000 #define LIST 1001 int flagWidth; int flagHeight; std::string flagStr(" "); void drawFlag(const unsigned char flagArray[][3], unsigned char flagStripes) { short i, y, j, uni = 0; short divLen = flagStr.size(); // Hopefully will handle all unicode things in a string for (int k : flagStr) { if (k < 0 && uni != 2) { uni++; } if (uni == 2) { divLen -= 1; uni = 0; } } //std::println("Divided length: {0} ({1} / {2})", (flagWidth / divLen), flagWidth, divLen); for (i = 0; i < flagStripes; i++) { if (flagHeight / flagStripes <= 0) { std::cerr << "Integer too small!" << std::endl; break; } for (y = 0; y < flagHeight / flagStripes; y++) { if (flagStr != " ") { flagStr.shrink_to_fit(); std::print("\x1b[38;2;{0};{1};{2}m", flagArray[i][0], flagArray[i][1], flagArray[i][2]); } else { std::print("\x1b[48;2;{0};{1};{2}m", flagArray[i][0], flagArray[i][1], flagArray[i][2]); } for (j = 0; j < flagWidth / divLen; j++) { std::print("{0}", flagStr); } } std::println("\x1b[0m"); } } int main(int argc, char **argv) { /* * TODO: * - Bi flag handle * - add more flags for inclusivity * - Handle Unicode argv (This fucking bitch is driving me insane I can't take it anymore) * - ^ Handle strings(?) */ //std::setlocale(LC_CTYPE, "de_DE.utf8"); //std::locale::global(std::locale("de_DE.utf8")); static struct option long_options[] { {"help", no_argument, nullptr, HELP}, {"list", no_argument, nullptr, LIST}, {"flag", required_argument, nullptr, 'f'}, {"height", required_argument, nullptr, 'h'}, {"string", required_argument, nullptr, 's'}, {nullptr, 0, nullptr, 0}, }; struct winsize size; ioctl(STDOUT_FILENO, TIOCGWINSZ, &size); flagWidth = size.ws_col; flagHeight = size.ws_row; // All available flags const unsigned char prideFlag[6][3] = {{255, 30, 38}, {255, 141, 0}, {255, 238, 0}, {2, 129, 33}, {0, 76, 255}, {119, 0, 136}}; const unsigned char transFlag[5][3] = {{91, 206, 250}, {245, 169, 184}, {255, 255, 255}, {245, 169, 184}, {91, 206, 250}}; const unsigned char lesbianFlag[5][3] = {{212, 44, 0}, {253, 152, 85}, {255, 255, 255}, {209, 97, 162}, {162, 1, 97}}; const unsigned char dutchFlag[3][3] = {{220, 16, 46}, {255, 255, 255}, {0, 61, 165}}; const unsigned char biFlag[3][3] = {{214, 2, 112}, {155, 79, 150}, {0, 56, 168}}; unsigned char flagStripes; // Array of all available flags const std::string allFlags[] = {"pride", "trans", "lesbian", "dutch", "bi"}; short allFlagsSize = sizeof(allFlags) / sizeof(allFlags[0]); int opt; while ((opt = getopt_long(argc, argv, "h:s:f:", long_options, nullptr)) != -1) { switch (opt) { case '0': std::print("{}", opt); return 1; case 'h': if (argc <= 3) { std::cerr << "You can't run '" << argv[1] << "' alone!\n"; return 1; } else { flagHeight = atoi(argv[optind - 1]); } break; case 's': if (argc == 3 || argc == 2) { std::cerr << "You can't run '" << argv[1] << "' alone!\n"; return 1; } else { flagStr = argv[optind - 1]; // I will keep this at index 0 so it can't even break it for now } break; case 'f': if (optind > argc) { std::cerr << "Missing [flag] argument!\nusage: " << argv[0] << " [-f] [flag]\n"; return 1; } else { std::string strArgv(argv[(optind - 1)]); std::transform(strArgv.begin(), strArgv.end(), strArgv.begin(), ::tolower); if (strArgv.compare(allFlags[0]) == 0) { flagStripes = 6; drawFlag(prideFlag, flagStripes); } else if (strArgv.compare(allFlags[1]) == 0) { flagStripes = 5; drawFlag(transFlag, flagStripes); } else if (strArgv.compare(allFlags[2]) == 0) { flagStripes = 5; drawFlag(lesbianFlag, flagStripes); } else if (strArgv.compare(allFlags[3]) == 0) { flagStripes = 3; drawFlag(dutchFlag, flagStripes); } else if (strArgv.compare(allFlags[4]) == 0) { flagStripes = 3; drawFlag(biFlag, flagStripes); } else { std::cerr << argv[0] << ": invalid option '" << strArgv << "'\n"; std::cerr << "Usage: " << argv[0] << " [OPTION] [VALUE] -f [FLAG]\n"; return 1; } } break; case LIST: std::print("All available [FLAGS]:\n"); for (short k = 0; k < allFlagsSize; k++) { std::print("{0}\n", allFlags[k]); } return 0; case HELP: std::cout << "Usage: " << argv[0] << " [OPTION] [ARGUMENT] -f [FLAG]\n" << "All options:\n" << "\t-f, --flag [FLAG]\t\tPrints the chosen flag\n" << "\t-h, --height [Integer]\t\tPrints the flag with the chosen positive integer\n" << "\t-s, --string \'[String]\'\t\tPrint the chosen flag with the given string (Flag width is not yet perfectly variable)\n" << "\t--list\t\t\t\tList all available flags\n" << "\t--help\t\t\t\tPrints out the help screen\n"; return 0; case '?': std::cerr << "No matching [OPTION]!\n"; return 1; default: std::cerr << "Usage: " << argv[0] << " [OPTION] [VALUE] -f [FLAG]" << std::endl; return 1; } } return 0; }