#include using namespace osg; std::string ArgumentParser::getProgramName() const { if (_argc>0) return std::string(_argv[0]); return ""; } int ArgumentParser::find(const std::string& str) const { for(int pos=1;pos<*_argc;++pos) { if (str==_argv[pos]) return pos; } return 0; } bool ArgumentParser::match(int pos, const std::string& str) const { return pos<*_argc && str==_argv[pos]; } bool ArgumentParser::isOption(int pos) const { return (pos<*_argc && _argv[pos][0]=='-'); } bool ArgumentParser::isString(int pos) const { return pos<*_argc && !isOption(pos); } bool ArgumentParser::isNumber(int pos) const { if (pos>=*_argc) return false; bool hadPlusMinus = false; bool hadDecimalPlace = false; bool hadExponent = false; bool couldBeInt = true; bool couldBeFloat = true; int noZeroToNine = 0; const char* ptr = _argv[pos]; // check if could be a hex number. if (strncmp(ptr,"0x",2)==0) { // skip over leading 0x, and then go through rest of string // checking to make sure all values are 0...9 or a..f. ptr+=2; while ( *ptr!=0 && ((*ptr>='0' && *ptr<='9') || (*ptr>='a' && *ptr<='f') || (*ptr>='A' && *ptr<='F')) ) { ++ptr; } // got to end of string without failure, therefore must be a hex integer. if (*ptr==0) return true; } ptr = _argv[pos]; // check if a float or an int. while (*ptr!=0 && couldBeFloat) { if (*ptr=='+' || *ptr=='-') { if (hadPlusMinus) { couldBeInt = false; couldBeFloat = false; } else hadPlusMinus = true; } else if (*ptr>='0' && *ptr<='9') { noZeroToNine++; } else if (*ptr=='.') { if (hadDecimalPlace) { couldBeInt = false; couldBeFloat = false; } else { hadDecimalPlace = true; couldBeInt = false; } } else if (*ptr=='e' || *ptr=='E') { if (hadExponent || noZeroToNine==0) { couldBeInt = false; couldBeFloat = false; } else { hadExponent = true; couldBeInt = false; hadDecimalPlace = false; hadPlusMinus = false; noZeroToNine=0; } } else { couldBeInt = false; couldBeFloat = false; } ++ptr; } if (couldBeInt && noZeroToNine>0) return true; if (couldBeFloat && noZeroToNine>0) return true; return false; } bool ArgumentParser::containsOptions() const { for(int pos=1;pos<*_argc;++pos) { if (isOption(pos)) return true; } return false; } void ArgumentParser::remove(int pos,int num) { if (num==0) return; for(;pos+num<*_argc;++pos) { _argv[pos]=_argv[pos+num]; } for(;pos<*_argc;++pos) { _argv[pos]=0; } *_argc-=num; } bool ArgumentParser::read(const std::string& str) { int pos=find(str); if (pos<=0) return false; remove(pos); return true; } bool ArgumentParser::read(const std::string& str,std::string& value1) { int pos=find(str); if (pos<=0) return false; if (!isString(pos+1)) { reportError("argument to `"+str+"` is missing"); return false; } value1 = _argv[pos+1]; remove(pos,2); return true; } bool ArgumentParser::read(const std::string& str,std::string& value1,std::string& value2) { int pos=find(str); if (pos<=0) return false; if (!isString(pos+1) || !isString(pos+2) ) { reportError("argument to `"+str+"` is missing"); return false; } value1 = _argv[pos+1]; value2 = _argv[pos+2]; remove(pos,3); return true; } bool ArgumentParser::read(const std::string& str,std::string& value1,std::string& value2,std::string& value3) { int pos=find(str); if (pos<=0) return false; if (!isString(pos+1) || !isString(pos+2) || !isString(pos+3)) { reportError("argument to `"+str+"` is missing"); return false; } value1 = _argv[pos+1]; value2 = _argv[pos+2]; value3 = _argv[pos+3]; remove(pos,4); return true; } bool ArgumentParser::read(const std::string& str,float& value1) { int pos=find(str); if (pos<=0) return false; if (!isNumber(pos+1)) { reportError("argument to `"+str+"` is missing"); return false; } value1 = atof(_argv[pos+1]); remove(pos,2); return true; } bool ArgumentParser::read(const std::string& str,float& value1,float& value2) { int pos=find(str); if (pos<=0) return false; if (!isNumber(pos+1) || !isNumber(pos+2) ) { reportError("argument to `"+str+"` is missing"); return false; } value1 = atof(_argv[pos+1]); value2 = atof(_argv[pos+2]); remove(pos,3); return true; } bool ArgumentParser::read(const std::string& str,float& value1,float& value2,float& value3) { int pos=find(str); if (pos<=0) return false; if (!isNumber(pos+1) || !isNumber(pos+2) || !isNumber(pos+3)) { reportError("argument to `"+str+"` is missing"); return false; } value1 = atof(_argv[pos+1]); value2 = atof(_argv[pos+2]); value3 = atof(_argv[pos+3]); remove(pos,4); return true; } bool ArgumentParser::errors(ErrorSeverity severity) const { for(ErrorMessageMap::const_iterator itr=_errorMessageMap.begin(); itr!=_errorMessageMap.end(); ++itr) { if (itr->second>=severity) return true; } return false; } void ArgumentParser::reportError(const std::string& message,ErrorSeverity severity) { _errorMessageMap[message]=severity; } void ArgumentParser::reportRemainingOptionsAsUnrecognized(ErrorSeverity severity) { for(int pos=1;possecond>=severity) { output<first<