Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gui/src/core/CommandLine.cc @ 1664

Last change on this file since 1664 was 1664, checked in by rgrieder, 16 years ago
  • Finished CommandLineArgument completely. You can also use SetCommandLineSwitch to define boolean switches.
  • Added StaticConversion to Covert.h (compile time type conversion checking)
  • Fixed a bug in Exception
  • Added getAllStrings() to SubString
  • Property svn:eol-style set to native
File size: 6.9 KB
Line 
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#include "CommandLine.h"
30
31namespace orxonox
32{
33    /**
34    @brief
35        Destructor destroys all CommandLineArguments with it.
36    */
37    CommandLine::~CommandLine()
38    {
39        for (std::map<std::string, BaseCommandLineArgument*>::const_iterator it = cmdLineArgs_.begin();
40            it != cmdLineArgs_.end(); ++it)
41        {
42            delete it->second;
43        }
44    }
45
46    /**
47    @brief
48        Returns a unique instance (Meyers Singleton).
49    */
50    CommandLine& CommandLine::_getInstance()
51    {
52        static CommandLine instance;
53        return instance;
54    }
55
56    /**
57    @brief
58        Reads the command line parses the values of each argument.
59        It is then stored in the corresponding CommandLineArgument.
60    @note
61        The reason that you have to provide the string to be parsed as
62        space separted list is because of argc and argv. If you only have
63        a whole string, simply use getAllStrings() of SubString.
64    @param arguments
65        Vector of space separated strings.
66    */
67    void CommandLine::_parse(const std::vector<std::string>& arguments)
68    {
69        // why this? See bFirstTimeParse_ declaration.
70        if (bFirstTimeParse_)
71        {
72            // first shove all the shortcuts in a map
73            for (std::map<std::string, BaseCommandLineArgument*>::const_iterator it = cmdLineArgs_.begin();
74                it != cmdLineArgs_.end(); ++it)
75            {
76                OrxAssert(cmdLineArgsShortcut_.find(it->second->getShortcut()) == cmdLineArgsShortcut_.end(),
77                    "Cannot have two command line shortcut with the same name.");
78                if (it->second->getShortcut() != "")
79                    cmdLineArgsShortcut_[it->second->getShortcut()] = it->second;
80            }
81            bFirstTimeParse_ = false;
82        }
83
84        std::string name;
85        std::string shortcut;
86        std::string value;
87        for (unsigned int i = 0; i < arguments.size(); ++i)
88        {
89            if (arguments[i].size() != 0)
90            {
91                // sure not ""
92                if (arguments[i][0] == '-')
93                {
94                    // start with "-"
95                    if (arguments[i].size() == 1)
96                    {
97                        // argument[i] is "-", probably a minus sign
98                        value += "- ";
99                    }
100                    else if (arguments[i][1] <= 57 && arguments[i][1] >= 48)
101                    {
102                        // negative number as a value
103                        value += arguments[i] + " ";
104                    }
105                    else
106                    {
107                        // can be shortcut or full name argument
108
109                        // save old data first
110                        if (name != "")
111                        {
112                            checkFullArgument(name, value);
113                            name = "";
114                            assert(shortcut == "");
115                        }
116                        else if (shortcut != "")
117                        {
118                            checkShortcut(shortcut, value);
119                            shortcut = "";
120                            assert(name == "");
121                        }
122
123                        if (arguments[i][1] == '-')
124                        {
125                            // full name argument with "--name"
126                            name = arguments[i].substr(2);
127                        }
128                        else
129                        {
130                            // shortcut with "-s"
131                            shortcut = arguments[i].substr(1);
132                        }
133
134                        // reset value string
135                        value = "";
136                    }
137                }
138                else
139                {
140                    // value string
141
142                    if (name == "" && shortcut == "")
143                    {
144                        ThrowException(Argument, "Expected \"-\" or \"-\" in command line arguments.\n");
145                    }
146
147                    // Concatenate strings as long as there's no new argument by "-" or "--"
148                    value += arguments[i] + ' ';
149                }
150            }
151        }
152
153        // parse last argument
154        if (name != "")
155        {
156            checkFullArgument(name, value);
157            assert(shortcut == "");
158        }
159        else if (shortcut != "")
160        {
161            checkShortcut(shortcut, value);
162            assert(name == "");
163        }
164    }
165
166    /**
167    @brief
168        Parses an argument based on its full name.
169    @param name
170        Full name of the argument
171    @param value
172        String containing the value
173    */
174    void CommandLine::checkFullArgument(const std::string& name, const std::string& value)
175    {
176        std::map<std::string, BaseCommandLineArgument*>::const_iterator it = cmdLineArgs_.find(name);
177        if (it == cmdLineArgs_.end())
178            ThrowException(Argument, "Command line argument '" + name + "' does not exist.");
179
180        it->second->parse(value);
181    }
182
183    /**
184    @brief
185        Parses an argument based on its shortcut.
186    @param shortcut
187        Shotcut to the argument
188    @param value
189        String containing the value
190    */
191    void CommandLine::checkShortcut(const std::string& shortcut, const std::string& value)
192    {
193        std::map<std::string, BaseCommandLineArgument*>::const_iterator it = cmdLineArgsShortcut_.find(shortcut);
194        if (it == cmdLineArgsShortcut_.end())
195            ThrowException(Argument, "Command line shortcut '" + shortcut + "' does not exist.");
196
197        it->second->parse(value);
198    }
199
200    std::string CommandLine::getUsageInformation()
201    {
202        CommandLine* inst = &_getInstance();
203        std::string infoStr;
204        for (std::map<std::string, BaseCommandLineArgument*>::const_iterator it = inst->cmdLineArgs_.begin();
205            it != inst->cmdLineArgs_.end(); ++it)
206        {
207            infoStr += "[--" + it->second->getName() + " " + it->second->getInformation() + "] ";
208        }
209        return infoStr;
210    }
211
212}
Note: See TracBrowser for help on using the repository browser.