X-Git-Url: https://git.armaanb.net/?p=gen-shell.git;a=blobdiff_plain;f=src%2FSarge%2Fsrc%2Fsarge.cpp;fp=src%2FSarge%2Fsrc%2Fsarge.cpp;h=0000000000000000000000000000000000000000;hp=eb7d14fbe7836f683540dfd461d04ee8ef2bb30d;hb=11665c1b3741eaf7c4cc51f54ce7c5b8f8467f18;hpb=d8afd601de1f0d8afe6eff61d40ff52d21d90fd8 diff --git a/src/Sarge/src/sarge.cpp b/src/Sarge/src/sarge.cpp deleted file mode 100644 index eb7d14f..0000000 --- a/src/Sarge/src/sarge.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* - sarge.cpp - Implementation file for the Sarge command line argument parser project. - - Revision 0 - - Features: - - - - Notes: - - - - 2019/03/16, Maya Posch - -*/ - - -#include "sarge.h" - -#include - - -// --- SET ARGUMENT --- -void Sarge::setArgument(std::string arg_short, std::string arg_long, std::string desc, bool hasVal) { - std::unique_ptr arg(new Argument); - arg->arg_short = arg_short; - arg->arg_long = arg_long; - arg->description = desc; - arg->hasValue = hasVal; - args.push_back(std::move(arg)); - - // Set up links. - if (!arg_short.empty()) { - argNames.insert(std::pair(arg_short, args.back().get())); - } - - if (!arg_long.empty()) { - argNames.insert(std::pair(arg_long, args.back().get())); - } -} - - -// --- SET ARGUMENTS --- -void Sarge::setArguments(std::vector args) { - for (Argument a : args) { - setArgument(a.arg_short, a.arg_long, a.description, a.hasValue); - } -} - - -// --- PARSE ARGUMENTS --- -bool Sarge::parseArguments(int argc, char** argv) { - // The first argument is the name of the executable. After it we loop through the remaining - // arguments, linking flags and values. - execName = std::string(argv[0]); - bool expectValue = false; - std::map::const_iterator flag_it; - for (int i = 1; i < argc; ++i) { - // Each flag will start with a '-' character. Multiple flags can be joined together in the - // same string if they're the short form flag type (one character per flag). - std::string entry(argv[i]); - - if (expectValue) { - // Copy value. - flag_it->second->value = entry; - expectValue = false; - } - else if (entry.compare(0, 1, "-") == 0) { - if (textArguments.size() > 0) { - std::cerr << "Flags not allowed after text arguments." << std::endl; - } - - // Parse flag. - // First check for the long form. - if (entry.compare(0, 2, "--") == 0) { - // Long form of flag. - entry.erase(0, 2); // Erase the double dash since we no longer need it. - - flag_it = argNames.find(entry); - if (flag_it == argNames.end()) { - // Flag wasn't found. Abort. - std::cerr << "Long flag " << entry << " wasn't found." << std::endl; - return false; - } - - // Mark as found. - flag_it->second->parsed = true; - ++flagCounter; - - if (flag_it->second->hasValue) { - expectValue = true; // Next argument has to be a value string. - } - } - else { - // Parse short form flag. Parse all of them sequentially. Only the last one - // is allowed to have an additional value following it. - entry.erase(0, 1); // Erase the dash. - for (int i = 0; i < entry.length(); ++i) { - std::string k(&(entry[i]), 1); - flag_it = argNames.find(k); - if (flag_it == argNames.end()) { - // Flag wasn't found. Abort. - std::cerr << "Short flag " << k << " wasn't found." << std::endl; - return false; - } - - // Mark as found. - flag_it->second->parsed = true; - ++flagCounter; - - if (flag_it->second->hasValue) { - if (i != (entry.length() - 1)) { - // Flag isn't at end, thus cannot have value. - std::cerr << "Flag " << k << " needs to be followed by a value string." - << std::endl; - return false; - } else { - expectValue = true; // Next argument has to be a value string. - } - } - } - } - } - else { - // Add to text argument vector. - textArguments.push_back(entry); - } - } - - parsed = true; - - return true; -} - - -// --- GET FLAG --- -// Returns whether the flag was found, along with the value if relevant. -bool Sarge::getFlag(std::string arg_flag, std::string &arg_value) { - if (!parsed) { return false; } - - std::map::const_iterator it = argNames.find(arg_flag); - if (it == argNames.end()) { return false; } - if (!it->second->parsed) { return false; } - - if (it->second->hasValue) { arg_value = it->second->value; } - - return true; -} - - -// --- EXISTS --- -// Returns whether the flag was found. -bool Sarge::exists(std::string arg_flag) { - if (!parsed) { return false; } - - std::map::const_iterator it = argNames.find(arg_flag); - if (it == argNames.end()) { return false; } - if (!it->second->parsed) { return false; } - - return true; -} - - -// --- GET TEXT ARGUMENT --- -// Updates the value parameter with the text argument (unbound value) if found. -// Index starts at 0. -// Returns true if found, else false. -bool Sarge::getTextArgument(uint32_t index, std::string &value) { - if (index < textArguments.size()) { value = textArguments.at(index); return true; } - - return false; -} - - -// --- PRINT HELP --- -// Prints out the application description, usage and available options. -void Sarge::printHelp() { - std::cout << std::endl << description << std::endl; - std::cout << std::endl << "Usage:" << std::endl; - std::cout << "\t" << usage << std::endl; - std::cout << std::endl; - std::cout << "Options: " << std::endl; - - // Determine whitespace needed between arg_long and description. - int count = 1; - std::vector >::const_iterator it; - for (it = args.cbegin(); it != args.cend(); ++it) { - if ((*it)->arg_long.size() > count) { - count = (*it)->arg_long.size(); - } - } - - count += 3; // Number of actual spaces between the longest arg_long and description. - - // Print out the options. - for (it = args.cbegin(); it != args.cend(); ++it) { - std::cout << ((*it)->arg_short.empty() ? " " : "-" + (*it)->arg_short + ", ") - << "--" << (*it)->arg_long; - std::cout << std::string(count - (*it)->arg_long.size(), ' ') << (*it)->description - << std::endl; - } -}