root/OpenSceneGraph/trunk/src/osg/ApplicationUsage.cpp @ 13041

Revision 13041, 9.6 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <stdlib.h>
15#include <string.h>
16
17#include <osg/ApplicationUsage>
18#include <osg/Math>
19#include <osg/ref_ptr>
20
21using namespace osg;
22
23ApplicationUsage::ApplicationUsage(const std::string& commandLineUsage):
24    _commandLineUsage(commandLineUsage)
25{
26}
27
28ApplicationUsage* ApplicationUsage::instance()
29{
30    static osg::ref_ptr<ApplicationUsage> s_applicationUsage = new ApplicationUsage;
31    return s_applicationUsage.get();
32}
33
34void ApplicationUsage::addUsageExplanation(Type type,const std::string& option,const std::string& explanation)
35{
36    switch(type)
37    {
38        case(COMMAND_LINE_OPTION):
39            addCommandLineOption(option,explanation);
40            break;
41        case(ENVIRONMENTAL_VARIABLE):
42            addEnvironmentalVariable(option,explanation);
43            break;
44        case(KEYBOARD_MOUSE_BINDING):
45            addKeyboardMouseBinding(option,explanation);
46            break;
47        default:
48            break;
49    }
50}
51
52void ApplicationUsage::addCommandLineOption(const std::string& option,const std::string& explanation,const std::string& defaultValue)
53{
54    _commandLineOptions[option]=explanation;
55    _commandLineOptionsDefaults[option]=defaultValue;
56}
57
58void ApplicationUsage::addEnvironmentalVariable(const std::string& option,const std::string& explanation, const std::string& defaultValue)
59{
60    _environmentalVariables[option]=explanation;
61    _environmentalVariablesDefaults[option]=defaultValue;
62}
63
64void ApplicationUsage::addKeyboardMouseBinding(const std::string& option,const std::string& explanation)
65{
66    _keyboardMouse[option]=explanation;
67}
68
69void ApplicationUsage::getFormattedString(std::string& str, const UsageMap& um,unsigned int widthOfOutput,bool showDefaults,const UsageMap& ud)
70{
71
72    unsigned int maxNumCharsInOptions = 0;
73    ApplicationUsage::UsageMap::const_iterator citr;
74    for(citr=um.begin();
75        citr!=um.end();
76        ++citr)
77    {
78        maxNumCharsInOptions = maximum(maxNumCharsInOptions,(unsigned int)citr->first.length());
79    }
80
81
82    unsigned int fullWidth = widthOfOutput;
83    unsigned int optionPos = 2;
84    unsigned int explanationPos = optionPos+maxNumCharsInOptions+2;
85
86    double ratioOfExplanationToOutputWidth = float(explanationPos)/float(widthOfOutput);
87    double maxRatioOfExplanationToOutputWidth = 0.25f;
88
89    if (ratioOfExplanationToOutputWidth > maxRatioOfExplanationToOutputWidth)
90    {
91        explanationPos = static_cast<unsigned int>(maxRatioOfExplanationToOutputWidth*float(widthOfOutput));
92    }
93
94    unsigned int defaultPos = 0;
95    if (showDefaults)
96    {
97        defaultPos = explanationPos;
98        explanationPos = optionPos+8;
99    }
100    unsigned int explanationWidth = fullWidth-explanationPos;
101
102    std::string line;
103
104    for(citr=um.begin();
105        citr!=um.end();
106        ++citr)
107    {
108        line.assign(fullWidth,' ');
109        line.replace(optionPos,citr->first.length(),citr->first);
110        unsigned int currentEndPos = optionPos + citr->first.length();
111
112        if (showDefaults)
113        {
114
115            UsageMap::const_iterator ditr = ud.find(citr->first);
116            if (ditr != ud.end())
117            {
118                if (currentEndPos+1>=defaultPos)
119                {
120                    str += line; str += "\n";
121                    line.assign(fullWidth,' ');
122                }
123
124                line.replace(defaultPos, std::string::npos, "");
125                if (ditr->second != "")
126                {
127                    line += "[";
128                    line += ditr->second;
129                    line += "]";
130                }
131                str += line;
132                str += "\n";
133                line.assign(fullWidth,' ');
134
135                currentEndPos =  0;
136            }
137        }
138
139        const std::string& explanation = citr->second;
140        std::string::size_type pos = 0;
141        std::string::size_type offset = 0;
142        bool firstInLine = true;
143        if (!explanation.empty())
144        {
145
146            if (currentEndPos+1>explanationPos)
147            {
148                str += line; str += "\n";
149                line.assign(fullWidth,' ');
150            }
151
152            while (pos<explanation.length())
153            {
154                if (firstInLine) offset = 0;
155
156                // skip any leading white space.
157                while (pos<explanation.length() && explanation[pos]==' ')
158                {
159                    if (firstInLine) ++offset;
160                    ++pos;
161                }
162
163                firstInLine = false;
164
165                std::string::size_type width = minimum((std::string::size_type)(explanation.length()-pos),(std::string::size_type)(explanationWidth-offset));
166                std::string::size_type slashn_pos = explanation.find('\n',pos);
167
168                unsigned int extraSkip = 0;
169                bool concatinated = false;
170                if (slashn_pos!=std::string::npos)
171                {
172                    if (slashn_pos<pos+width)
173                    {
174                        width = slashn_pos-pos;
175                        ++extraSkip;
176                        firstInLine = true;
177                    }
178                    else if (slashn_pos==pos+width)
179                    {
180                        ++extraSkip;
181                        firstInLine = true;
182                    }
183                }
184
185                if (pos+width<explanation.length())
186                {
187                    // now reduce width until we get a space or a return
188                    // so that we ensure that whole words are printed.
189                    while (width>0 &&
190                           explanation[pos+width]!=' ' &&
191                           explanation[pos+width]!='\n') --width;
192
193                    if (width==0)
194                    {
195                        // word must be longer than a whole line so will need
196                        // to concatenate it.
197                        width = explanationWidth-1;
198                        concatinated = true;
199                    }
200                }
201
202                line.replace(explanationPos+offset,explanationWidth, explanation, pos, width);
203
204                if (concatinated) { str += line; str += "-\n"; }
205                else { str += line; str += "\n"; }
206
207                // move to the next line of output.
208                line.assign(fullWidth,' ');
209
210                pos += width+extraSkip;
211
212            }
213        }
214        else
215        {
216            str += line; str += "\n";
217        }
218    }
219}
220
221void ApplicationUsage::write(std::ostream& output, const ApplicationUsage::UsageMap& um,unsigned int widthOfOutput,bool showDefaults,const ApplicationUsage::UsageMap& ud)
222{
223    std::string str;
224    getFormattedString(str, um, widthOfOutput, showDefaults, ud);
225    output << str << std::endl;
226}
227
228void ApplicationUsage::write(std::ostream& output, unsigned int type, unsigned int widthOfOutput, bool showDefaults)
229{
230
231    output << "Usage: "<<getCommandLineUsage()<<std::endl;
232    bool needspace = false;
233    if ((type&COMMAND_LINE_OPTION) && !getCommandLineOptions().empty())
234    {
235        output << "Options";
236        if (showDefaults) output << " [and default value]";
237        output << ":"<<std::endl;
238        write(output,getCommandLineOptions(),widthOfOutput,showDefaults,getCommandLineOptionsDefaults());
239        needspace = true;
240    }
241
242    if ((type&ENVIRONMENTAL_VARIABLE) && !getEnvironmentalVariables().empty())
243    {
244        if (needspace) output << std::endl;
245        output << "Environmental Variables";
246        if (showDefaults) output << " [and default value]";
247        output << ":"<<std::endl;
248        write(output,getEnvironmentalVariables(),widthOfOutput,showDefaults,getEnvironmentalVariablesDefaults());
249        needspace = true;
250    }
251
252    if ((type&KEYBOARD_MOUSE_BINDING) && !getKeyboardMouseBindings().empty())
253    {
254        if (needspace) output << std::endl;
255        output << "Keyboard and Mouse Bindings:"<<std::endl;
256        write(output,getKeyboardMouseBindings(),widthOfOutput);
257        needspace = true;
258    }
259
260}
261
262
263void ApplicationUsage::writeEnvironmentSettings(std::ostream& output)
264{
265    output << "Current Environment Settings:"<<std::endl;
266
267    unsigned int maxNumCharsInOptions = 0;
268    ApplicationUsage::UsageMap::const_iterator citr;
269    for(citr=getEnvironmentalVariables().begin();
270        citr!=getEnvironmentalVariables().end();
271        ++citr)
272    {
273        std::string::size_type len = citr->first.find_first_of("\n\r\t ");
274        if (len == std::string::npos) len = citr->first.size();
275        maxNumCharsInOptions = maximum( maxNumCharsInOptions,static_cast<unsigned int>(len));
276    }
277
278    unsigned int optionPos = 2;
279    std::string line;
280
281    for(citr=getEnvironmentalVariables().begin();
282        citr!=getEnvironmentalVariables().end();
283        ++citr)
284    {
285        line.assign(optionPos+maxNumCharsInOptions+2,' ');
286        std::string::size_type len = citr->first.find_first_of("\n\r\t ");
287        if (len == std::string::npos) len = citr->first.size();
288        line.replace(optionPos,len,citr->first.substr(0,len));
289        const char *cp = getenv(citr->first.substr(0, len).c_str());
290        if (!cp) cp = "[not set]";
291        else if (!*cp) cp = "[set]";
292        line += std::string(cp) + "\n";
293
294        output << line;
295    }
296    output << std::endl;
297}
Note: See TracBrowser for help on using the browser.