www.pudn.com > cppcc.rar > cmdline_parser.hh
/* * File: cucu.c * $Id: cmdline_parser.hh,v 1.3 2002/06/26 20:46:03 alec Exp $ * * Author: Alec Panoviciu (alecu@email.com) * * Comments: * * Revision history: * * $Log: cmdline_parser.hh,v $ * Revision 1.3 2002/06/26 20:46:03 alec * g++ 3.x happy * * Revision 1.2 2002/04/29 09:34:10 alec * scanner ptree building compiles * */ /* Copyright (C) 2002 Alexandru Panoviciu (alecu@email.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __CMDLINE_PARSER_HH__ #define __CMDLINE_PARSER_HH__ #include#include #include using namespace std; #include "prop_registry.hh" #include "debug.h" /** * This is the exception class used by the CmdLineParser class. */ class CmdLineParseException : public exception { public: CmdLineParseException (const string &message_) : message(message_) {} CmdLineParseException () : message("Command Line Parse Exception") {} virtual const char* what() const throw() { return message.c_str(); } virtual operator string() const { return message; } ~CmdLineParseException () throw () {} protected: string message; }; inline ostream& operator << (ostream& os, CmdLineParseException &ex) { return os << ex.what(); } /** * A simple command line parser implementation. It supports both short * one-letter (like -abcdef) and long (like --a_longopt --b_something ) * options. Also, options arguments of type string/bool/numeric are * supportd. It supoprts the GNU style "--" options terminator, and automatic * help message dumping. */ class CmdLineParser { /** * A command line atom (or "option" ) is something like "-c" or "-o foo" or * "--enable-things". * * Each atom can contain one or more arguments. furthermore, the same atom * can appear more than once. The \a multi field tells how multiple * occurence should be handled. If it is false, each occurence will override * the previous one. If true, the argument from each occurence is appended * to the property that corresponds to that atom. * * The tag field (corresponding to the tag field used into * the Propregistry) means: * * \li k_string : a parameter followed by a string argument (something like * "--enable this" or "--enable=other"). * * \li k_bool: can be either "--switch=yes" (or, alternatively "--switch * no")) or just "--switch" (yea is implied) or (the short version) "-s". If * multi is enabled, the boolean values are stored in a list for the * corresponding property. Otherwise, the last one will be the property's * value. "true" and "false" in place of yes and no are also supported. * * \li k_int: something like "-n 100" or "--numer 100". The multi parameter * has the same meaning as for k_bool. * * \li k_float: same as k_int. * * The sOpt and lOpt fields are the option's name (i.e. the bi that appears * after the - or --, respectively). Each option can have any of the two * forms or both. * * If the optional field is true, the optino is, well, optional :) * * The description string is a text that indicates the meaning of the * option, from the user's point of view. It is used when dumping the command * line synopsys. * * The prop string is the key of the property that will receive the value(s) * of the option. */ typedef struct t_CmdLineAtom { enum {k_string, k_bool, k_int, k_float} tag; bool multi; bool optional; string sOpt; string lOpt; string prop; string description; t_CmdLineAtom (const string &tag_, bool multi_, bool optional, const string &sOpt_, const string &lOpt_, const string &prop_, const string &description_) : multi(multi_), sOpt(sOpt_), lOpt(lOpt_), prop(prop_), description(description_) { if (tag_ == "s") tag = k_string; else if (tag_ == "b") tag = k_bool; else if (tag_ == "i") tag = k_int; else if (tag_ == "f") tag = k_float; else ASSERT(0, "bad tag string, should be \"s\"/\"b\"/\"i\"/\"f\""); ASSERT((sOpt != "") || (lOpt != ""), "both long and short option strings are empty"); } /** * Returns a string containing the synopsis of this atom. */ operator string () const; /** * Dumps a detailed description of the atom (in the format used by the * "options" part of any decent program that implements "--help". */ ostream& dumpDescription (ostream &os) const; } CmdLineAtom; public: /** * Creates a new CmdLineParser that will parse a command line that obeys the * given format string and will store the corersponding properties into the * given property registry. */ CmdLineParser (const string &progName_, PropRegistry &pr_) : progName(progName_), pr(pr_) {} /** * Parses the given command line and stores all the properties into the * registry. The parsing stops at the first non-option argument (i.e. not * starting with - or --). * * \throw CmdLineparseException if any error was encountered during parsing * the command line. The exception's what message indicates what went wrong. * * \return the number of parsed arguments (the rest up to argv is supposed * to only contain input files or whateer). */ int parse (int argc, char *argv[]) throw (CmdLineParseException); /** * \name Specifying command line syntax * * The methods add a new atom description into the parser's table and return * a ref to the parser object in order to allow chained insertions * (something like: clParaser.add(atom1).add(atom2).add(...);). */ //@{ CmdLineParser& add (const CmdLineAtom &atom) { desc.push_back(atom); return *this; } CmdLineParser& add (const string &tag, bool multi, bool optional, const string &sOpt, const string &lOpt, const string &prop, const string &description) { return add(CmdLineAtom(tag, multi, optional, sOpt, lOpt, prop, description)); } //@} void printUsage (ostream &os); private: /** * The registry where the parsed roperties will be stored by parse. */ PropRegistry ≺ /** * The desription of the cmd line. */ vector desc; /** * The name of the executable. */ string progName; }; #endif /* #ifndef __CMDLINE_PARSER_HH__ */