270 lines
8.9 KiB
C++
270 lines
8.9 KiB
C++
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
|
*
|
|
* This library is open source and may be redistributed and/or modified under
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
*
|
|
* This library 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
|
|
* OpenSceneGraph Public License for more details.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <osg/ApplicationUsage>
|
|
#include <osg/Math>
|
|
#include <osg/ref_ptr>
|
|
|
|
using namespace osg;
|
|
|
|
ApplicationUsage::ApplicationUsage(const std::string& commandLineUsage):
|
|
_commandLineUsage(commandLineUsage)
|
|
{
|
|
}
|
|
|
|
ApplicationUsage* ApplicationUsage::instance()
|
|
{
|
|
static osg::ref_ptr<ApplicationUsage> s_applicationUsage = new ApplicationUsage;
|
|
return s_applicationUsage.get();
|
|
}
|
|
|
|
void ApplicationUsage::addUsageExplanation(Type type,const std::string& option,const std::string& explanation)
|
|
{
|
|
switch(type)
|
|
{
|
|
case(COMMAND_LINE_OPTION):
|
|
addCommandLineOption(option,explanation);
|
|
break;
|
|
case(ENVIRONMENTAL_VARIABLE):
|
|
addEnvironmentalVariable(option,explanation);
|
|
break;
|
|
case(KEYBOARD_MOUSE_BINDING):
|
|
addKeyboardMouseBinding(option,explanation);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ApplicationUsage::addCommandLineOption(const std::string& option,const std::string& explanation,const std::string& defaultValue)
|
|
{
|
|
_commandLineOptions[option]=explanation;
|
|
_commandLineOptionsDefaults[option]=defaultValue;
|
|
}
|
|
|
|
void ApplicationUsage::addEnvironmentalVariable(const std::string& option,const std::string& explanation, const std::string& defaultValue)
|
|
{
|
|
_environmentalVariables[option]=explanation;
|
|
_environmentalVariablesDefaults[option]=defaultValue;
|
|
}
|
|
|
|
void ApplicationUsage::addKeyboardMouseBinding(const std::string& option,const std::string& explanation)
|
|
{
|
|
_keyboardMouse[option]=explanation;
|
|
}
|
|
|
|
void ApplicationUsage::getFormattedString(std::string& str, const UsageMap& um,unsigned int widthOfOutput,bool showDefaults,const UsageMap& ud)
|
|
{
|
|
|
|
unsigned int maxNumCharsInOptions = 0;
|
|
ApplicationUsage::UsageMap::const_iterator citr;
|
|
for(citr=um.begin();
|
|
citr!=um.end();
|
|
++citr)
|
|
{
|
|
maxNumCharsInOptions = maximum(maxNumCharsInOptions,(unsigned int)citr->first.length());
|
|
}
|
|
|
|
unsigned int fullWidth = widthOfOutput;
|
|
unsigned int optionPos = 2;
|
|
unsigned int explanationPos = optionPos+maxNumCharsInOptions+2;
|
|
unsigned int defaultPos = 0;
|
|
if (showDefaults)
|
|
{
|
|
defaultPos = explanationPos;
|
|
explanationPos = optionPos+8;
|
|
}
|
|
unsigned int explanationWidth = fullWidth-explanationPos;
|
|
|
|
std::string line;
|
|
|
|
for(citr=um.begin();
|
|
citr!=um.end();
|
|
++citr)
|
|
{
|
|
line.assign(fullWidth,' ');
|
|
line.replace(optionPos,citr->first.length(),citr->first);
|
|
|
|
if (showDefaults)
|
|
{
|
|
UsageMap::const_iterator ditr = ud.find(citr->first);
|
|
if (ditr != ud.end())
|
|
{
|
|
line.replace(defaultPos, std::string::npos, "");
|
|
if (ditr->second != "")
|
|
{
|
|
line += "[";
|
|
line += ditr->second;
|
|
line += "]";
|
|
}
|
|
str += line;
|
|
str += "\n";
|
|
line.assign(fullWidth,' ');
|
|
}
|
|
}
|
|
|
|
const std::string& explanation = citr->second;
|
|
std::string::size_type pos = 0;
|
|
std::string::size_type offset = 0;
|
|
bool firstInLine = true;
|
|
if (!explanation.empty())
|
|
{
|
|
while (pos<explanation.length())
|
|
{
|
|
if (firstInLine) offset = 0;
|
|
|
|
// skip any leading white space.
|
|
while (pos<explanation.length() && explanation[pos]==' ')
|
|
{
|
|
if (firstInLine) ++offset;
|
|
++pos;
|
|
}
|
|
|
|
firstInLine = false;
|
|
|
|
std::string::size_type width = minimum((std::string::size_type)(explanation.length()-pos),(std::string::size_type)(explanationWidth-offset));
|
|
std::string::size_type slashn_pos = explanation.find('\n',pos);
|
|
|
|
unsigned int extraSkip = 0;
|
|
bool concatinated = false;
|
|
if (slashn_pos!=std::string::npos)
|
|
{
|
|
if (slashn_pos<pos+width)
|
|
{
|
|
width = slashn_pos-pos;
|
|
++extraSkip;
|
|
firstInLine = true;
|
|
}
|
|
else if (slashn_pos==pos+width)
|
|
{
|
|
++extraSkip;
|
|
firstInLine = true;
|
|
}
|
|
}
|
|
|
|
if (pos+width<explanation.length())
|
|
{
|
|
// now reduce width until we get a space or a return
|
|
// so that we ensure that whole words are printed.
|
|
while (width>0 &&
|
|
explanation[pos+width]!=' ' &&
|
|
explanation[pos+width]!='\n') --width;
|
|
|
|
if (width==0)
|
|
{
|
|
// word must be longer than a whole line so will need
|
|
// to concatenate it.
|
|
width = explanationWidth-1;
|
|
concatinated = true;
|
|
}
|
|
}
|
|
|
|
line.replace(explanationPos+offset,explanationWidth, explanation, pos, width);
|
|
|
|
if (concatinated) { str += line; str += "-\n"; }
|
|
else { str += line; str += "\n"; }
|
|
|
|
// move to the next line of output.
|
|
line.assign(fullWidth,' ');
|
|
|
|
pos += width+extraSkip;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
str += line; str += "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
void ApplicationUsage::write(std::ostream& output, const ApplicationUsage::UsageMap& um,unsigned int widthOfOutput,bool showDefaults,const ApplicationUsage::UsageMap& ud)
|
|
{
|
|
std::string str;
|
|
getFormattedString(str, um, widthOfOutput, showDefaults, ud);
|
|
output << str << std::endl;
|
|
}
|
|
|
|
void ApplicationUsage::write(std::ostream& output, unsigned int type, unsigned int widthOfOutput, bool showDefaults)
|
|
{
|
|
|
|
output << "Usage: "<<getCommandLineUsage()<<std::endl;
|
|
bool needspace = false;
|
|
if ((type&COMMAND_LINE_OPTION) && !getCommandLineOptions().empty())
|
|
{
|
|
if (needspace) output << std::endl;
|
|
output << "Options";
|
|
if (showDefaults) output << " [and default value]";
|
|
output << ":"<<std::endl;
|
|
write(output,getCommandLineOptions(),widthOfOutput,showDefaults,getCommandLineOptionsDefaults());
|
|
needspace = true;
|
|
}
|
|
|
|
if ((type&ENVIRONMENTAL_VARIABLE) && !getEnvironmentalVariables().empty())
|
|
{
|
|
if (needspace) output << std::endl;
|
|
output << "Environmental Variables";
|
|
if (showDefaults) output << " [and default value]";
|
|
output << ":"<<std::endl;
|
|
write(output,getEnvironmentalVariables(),widthOfOutput,showDefaults,getEnvironmentalVariablesDefaults());
|
|
needspace = true;
|
|
}
|
|
|
|
if ((type&KEYBOARD_MOUSE_BINDING) && !getKeyboardMouseBindings().empty())
|
|
{
|
|
if (needspace) output << std::endl;
|
|
output << "Keyboard and Mouse Bindings:"<<std::endl;
|
|
write(output,getKeyboardMouseBindings(),widthOfOutput);
|
|
needspace = true;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void ApplicationUsage::writeEnvironmentSettings(std::ostream& output)
|
|
{
|
|
output << "Current Environment Settings:"<<std::endl;
|
|
|
|
unsigned int maxNumCharsInOptions = 0;
|
|
ApplicationUsage::UsageMap::const_iterator citr;
|
|
for(citr=getEnvironmentalVariables().begin();
|
|
citr!=getEnvironmentalVariables().end();
|
|
++citr)
|
|
{
|
|
std::string::size_type len = citr->first.find_first_of("\n\r\t ");
|
|
if (len == std::string::npos) len = citr->first.size();
|
|
maxNumCharsInOptions = maximum( maxNumCharsInOptions,static_cast<unsigned int>(len));
|
|
}
|
|
|
|
unsigned int optionPos = 2;
|
|
std::string line;
|
|
|
|
for(citr=getEnvironmentalVariables().begin();
|
|
citr!=getEnvironmentalVariables().end();
|
|
++citr)
|
|
{
|
|
line.assign(optionPos+maxNumCharsInOptions+2,' ');
|
|
std::string::size_type len = citr->first.find_first_of("\n\r\t ");
|
|
if (len == std::string::npos) len = citr->first.size();
|
|
line.replace(optionPos,len,citr->first.substr(0,len));
|
|
const char *cp = getenv(citr->first.substr(0, len).c_str());
|
|
if (!cp) cp = "[not set]";
|
|
else if (!*cp) cp = "[set]";
|
|
line += std::string(cp) + "\n";
|
|
|
|
output << line;
|
|
}
|
|
output << std::endl;
|
|
}
|