Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/pch/src/core/CommandLine.h @ 3149

Last change on this file since 3149 was 3149, checked in by rgrieder, 15 years ago

Extracted OrxAssert from Exception.h to OrxAssert.h since it doesn't really have anything to do with exceptions.

  • Property svn:eol-style set to native
File size: 8.1 KB
RevLine 
[1663]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#ifndef _CommandLine_H__
30#define _CommandLine_H__
31
32#include "CorePrereqs.h"
33#include <map>
34#include "util/Convert.h"
[1755]35#include "util/Debug.h"
[3149]36#include "util/OrxAssert.h"
[2087]37#include "util/MultiType.h"
[1663]38
39#define SetCommandLineArgument(name, defaultValue) \
[2103]40    orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \
[1670]41    = orxonox::CommandLine::addArgument(#name, defaultValue)
[1664]42#define SetCommandLineSwitch(name) \
[2103]43    orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \
[1670]44    = orxonox::CommandLine::addArgument(#name, false)
[1663]45
[1664]46
[1663]47namespace orxonox
48{
[1664]49    /**
50    @brief
[2087]51        Container class for a command line argument of any type supported by MultiType.
[1664]52
[2087]53        Whenever you want to have an option specified by a command line switch,
54        you need to first define it with SetCommandLineArgument(name, defaultValue).
55        It is then added to a map and possibly changed when the command line is being parsed.
56        If the option was not given, you can detect this by asking hasDefaultValue().
57
58        There is a possibility to define a short cut so you can write "-p 20" instead of "--port 20".
59        Note the difference between "-" and "--"!
60        Also, there is no restriction to the number of strings you add after --name.
61        So "--startVector (2, 4, 5)" is perfectly legal.
62
63        Retrieving an argument is possible with the getCommandLineArgument function of the
64        CommandLine class. It is a Singleton, but the public interface is static.
[1664]65    */
[2087]66    class _CoreExport CommandLineArgument
[1663]67    {
68        friend class CommandLine;
69
70    public:
[1664]71        //! Tells whether the value has been changed by the command line.
[1663]72        bool hasDefaultValue() const { return bHasDefaultValue_; }
[1664]73        //! Returns the name of the argument.
[1663]74        const std::string& getName() const { return name_; }
[1664]75
76        //! Returns the shortcut (example: "-p 22" for "--port 22") of the argument.
77        //! Evaluates to "" if none there is none.
[1663]78        const std::string& getShortcut() const { return shortcut_; }
[1664]79        //! Sets the shortcut for the argument
[2087]80        CommandLineArgument& shortcut(const std::string& shortcut)
[1663]81        { this->shortcut_ = shortcut; return *this; }
82
[1664]83        //! Returns the usage information
84        const std::string& getInformation() const { return this->usageInformation_; }
85        //! Sets the option information when displaying orxonox usage.
[2087]86        CommandLineArgument& information(const std::string& usage)
[1664]87        { this->usageInformation_ = usage; return *this; }
88
[2087]89        //! Returns the actual value of the argument. Can be equal to default value.
90        MultiType getValue() const { return value_; }
91        //! Returns the given default value as type T.
92        MultiType getDefaultValue() const { return defaultValue_; }
93
94    private:
95        //! Constructor initialises both value_ and defaultValue_ with defaultValue.
96        CommandLineArgument(const std::string& name, const MultiType& defaultValue)
[1670]97            : bHasDefaultValue_(true)
98            , name_(name)
[2087]99            , value_(defaultValue)
100            , defaultValue_(defaultValue)
[1663]101        { }
102
[1664]103        //! Undefined copy constructor
[2087]104        CommandLineArgument(const CommandLineArgument& instance);
105        ~CommandLineArgument() { }
[1663]106
[1664]107        //! Parses the value string of a command line argument.
[2087]108        void parse(const std::string& value);
[1663]109
[1664]110        //! Tells whether the value has been changed by the command line.
[1663]111        bool bHasDefaultValue_;
112
113    private:
[1664]114        std::string name_;             //!< Name of the argument
115        std::string shortcut_;         //!< Shortcut of the argument. @see getShortcut().
116        std::string usageInformation_; //!< Tells about the usage of this parameter
[1663]117
[2087]118        MultiType value_;            //!< The actual value
119        MultiType defaultValue_;     //!< Default value. Should not be changed.
[1663]120    };
121
122
[1664]123    /**
124    @brief
125        Global interface to command line options.
126        Allows to add and retrieve command line arguments. Also does the parsing.
127    @note
128        Internally it is a Singleton, but the public interface is static.
129    @see
130        CommandLineArgument
131    */
[1663]132    class _CoreExport CommandLine
133    {
134    public:
135
[1664]136        //! Parse redirection to internal member method.
[2103]137        static void parseAll(int argc, char** argv) { _getInstance()._parseAll(argc, argv); }
[1663]138
[1664]139        static std::string getUsageInformation();
140
[2087]141        static const CommandLineArgument* getArgument(const std::string& name);
[1664]142        //! Writes the argument value in the given parameter.
[1663]143        template <class T>
[1670]144        static void getValue(const std::string& name, T* value)
[2087]145        { *value = (T)(getArgument(name)->getValue()); }
146        static MultiType getValue(const std::string& name)
147        { return getArgument(name)->getValue(); }
[1664]148        template <class T>
[2087]149        static CommandLineArgument& addArgument(const std::string& name, T defaultValue);
[1663]150
[2087]151        static bool existsArgument(const std::string& name)
152        {
153            std::map<std::string, CommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name);
154            return !(it == _getInstance().cmdLineArgs_.end());
155        }
156
[2662]157        static void destroyAllArguments();
[2087]158
[1663]159    private:
[1664]160        //! Constructor initialises bFirstTimeParse_ with true.
[1663]161        CommandLine() : bFirstTimeParse_(true) { }
[1664]162        //! Undefined copy constructor
[1663]163        CommandLine(const CommandLine& instance);
164        ~CommandLine();
165
166        static CommandLine& _getInstance();
167
[2103]168        void _parseAll(int argc, char** argv);
[1664]169        void _parse(const std::vector<std::string>& arguments);
[1663]170        void checkFullArgument(const std::string& name, const std::string& value);
171        void checkShortcut(const std::string& shortcut, const std::string& value);
172
[1664]173        /**
[2087]174            Tells whether we parsed for the first time. The CommmandLineArguments are added before main().
[1664]175            So when we call parse() the first time, we need to create a map with all shortcuts since these
176            get added after addCommandLineArgument().
177        */
[1663]178        bool bFirstTimeParse_;
179
[1664]180        //! Holds all pointers to the arguments and serves as a search map by name.
[2087]181        std::map<std::string, CommandLineArgument*> cmdLineArgs_;
[2662]182        //! Search map by shortcut for the arguments.
[2087]183        std::map<std::string, CommandLineArgument*> cmdLineArgsShortcut_;
[1663]184    };
185
[2087]186    template <>
187    inline void CommandLine::getValue<std::string>(const std::string& name, std::string* value)
[1663]188    {
[2087]189        *value = (std::string)(getArgument(name)->getValue().getString());
[1663]190    }
191
[1664]192    /**
193    @brief
194        Adds a new CommandLineArgument to the internal map.
195        Note that only such arguments are actually valid.
196    @param name
197        Name of the argument. Shortcut can be added later.
198    @param defaultValue
199        Default value that is used when argument was not given.
200    */
[1663]201    template <class T>
[2087]202    CommandLineArgument& CommandLine::addArgument(const std::string& name, T defaultValue)
[1663]203    {
[2087]204        OrxAssert(!_getInstance().existsArgument(name),
[1663]205            "Cannot add a command line argument with name '" + name + "' twice.");
206
[2087]207        return *(_getInstance().cmdLineArgs_[name] = new CommandLineArgument(name, defaultValue));
[1663]208    }
209}
210
211#endif /* _CommandLine_H__ */
Note: See TracBrowser for help on using the repository browser.