From 1d8445b8461f558987067d870f0f11cdc84b4f35 Mon Sep 17 00:00:00 2001 From: manuel Date: Sat, 31 Oct 2009 16:11:26 +0100 Subject: pushing task1 to repo --- task1/getoptwrapper.cpp | 191 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 task1/getoptwrapper.cpp (limited to 'task1/getoptwrapper.cpp') diff --git a/task1/getoptwrapper.cpp b/task1/getoptwrapper.cpp new file mode 100644 index 0000000..1efd603 --- /dev/null +++ b/task1/getoptwrapper.cpp @@ -0,0 +1,191 @@ +/** + * $Id: getoptwrapper.cpp 2 2009-10-31 02:48:23Z l0728348 $ + * + * Copyright 2009 + * + * @author Manuel Mausz (0728348) + * @brief Wraps around getopt_long() using two classes + * class CommandOption represents a valid commandline option + * class CommandOptionParse calls getopt_long + * and generates usage message + */ + +#include +#include +#include +#include +#include +#include "getoptwrapper.h" + +using namespace std; + +CommandOptionParse::CommandOptionList cmdoptionlist; + +/*----------------------------------------------------------------------------*/ + +const std::string CommandOption::printParameters() +{ + ostringstream oss; + + if (!m_longopt.empty() && m_shortopt != 0) + oss << "-" << m_shortopt << " [ --" << m_longopt << " ]"; + else if (!m_longopt.empty() && m_shortopt == 0) + oss << "--" << m_longopt; + else if (m_longopt.empty() && m_shortopt != 0) + oss << "-" << m_shortopt; + + if (m_type == needArg) + oss << " arg"; + else if (m_type == optArg) + oss << " [ arg ]"; + + return oss.str(); +} + +/*----------------------------------------------------------------------------*/ + +void CommandOption::foundOption(const char *value) +{ + m_count++; + if (value != NULL) + m_value = value; +} + +/*----------------------------------------------------------------------------*/ + +bool CommandOptionParse::parse() +{ + CommandOptionList::iterator it; + + /* build optstring */ + m_optstring = ""; + for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it) + { + CommandOption *opt = *it; + if (opt->m_shortopt == 0) + continue; + + m_optstring += opt->m_shortopt; + if (opt->m_type == CommandOption::needArg) + m_optstring += ':'; + if (opt->m_type == CommandOption::optArg) + m_optstring += "::"; + } + + /* build longopts */ + if (m_longopts != NULL) + delete[] m_longopts; + m_longopts = new option[m_cmdlist.size() + 1]; + int i = 0; + for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it) + { + CommandOption *opt = *it; + if (opt->m_longopt.empty()) + continue; + + m_longopts[i].name = opt->m_longopt.c_str(); + m_longopts[i].has_arg = opt->m_type; + m_longopts[i].flag = 0; + m_longopts[i].val = 0; + ++i; + } + + /* append NULL-row */ + m_longopts[i].name = 0; + m_longopts[i].has_arg = 0; + m_longopts[i].flag = 0; + m_longopts[i].val = 0; + + //opterr = 0; // no errors from getopt_long! + int opt; + int optindex = 0; + while ((opt = getopt_long(m_argc, m_argv, m_optstring.c_str(), m_longopts, &optindex)) != -1) + { + if (opt == '?') + return 0; + + for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it) + { + CommandOption *option = *it; + if (opt == 0) + { + if (option->m_longopt == m_longopts[optindex].name) + option->foundOption(optarg); + } + else if (opt == option->m_shortopt) + option->foundOption(optarg); + } + } + + return 1; +} + +/*----------------------------------------------------------------------------*/ + +const std::string CommandOptionParse::usage() +{ + ostringstream oss; + string me(m_argv[0]); + + /* build usage/synopsis */ + oss << "Usage: "; + if (!m_synopsis.empty()) + { + oss << me << " " << m_synopsis.at(0) << endl; + for (unsigned i = 1; i < m_synopsis.size(); ++i) + oss << " " << me << " " << m_synopsis.at(i) << endl; + } + else + oss << me << " [OPTION]..." << endl; + + /* find maximum width of options */ + CommandOptionList::iterator it; + unsigned width = 20; // default + for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it) + { + stringstream tmpss; + tmpss << (*it)->printParameters(); + width = (max)(width, static_cast(tmpss.str().size())); + } + width += 2; + + /* print allowed options + description */ + oss << endl << m_description << ":" << endl; + for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it) + { + oss << " " << setw(width) << left << (*it)->printParameters() + << (*it)->m_description << endl; + } + + return oss.str(); +} + +/*----------------------------------------------------------------------------*/ + +CommandOption& CommandOptionParse::operator[](const std::string& longopt) +{ + CommandOptionList::iterator it; + for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it) + { + CommandOption *opt = *it; + if (opt->m_longopt == longopt) + return *opt; + } + throw out_of_range("option not found"); +} + +/*----------------------------------------------------------------------------*/ + +CommandOption& CommandOptionParse::operator[](const char shortopt) +{ + CommandOptionList::iterator it; + for (it = m_cmdlist.begin(); it != m_cmdlist.end(); ++it) + { + CommandOption *opt = *it; + if (opt->m_shortopt == shortopt) + return *opt; + } + throw out_of_range("option not found"); +} + +/* vim: set et sw=2 ts=2: */ -- cgit v1.2.3