1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
/* Copyright (C) 1999-2004 University of Oxford */
/* CCOPYRIGHT */
#include "options.h"
#include <fstream>
namespace Utilities {
using namespace std;
BaseOption * OptionParser::find_matching_option(const string& optstr)
{
for(Options::iterator o = options_.begin();
o != options_.end();
++o)
if((*o)->matches(optstr))
return *o;
return 0;
}
unsigned int OptionParser::parse_option(const string& optstr, const string& valstr,
char *argv[], int valpos, int argc)
throw(X_OptionError)
{
BaseOption * theOption = 0;
if((theOption = find_matching_option(optstr)) == 0)
throw X_OptionError(optstr, "Option doesn't exist");
if(theOption->unset() || (overWriteMode_==Allow))
{
if(theOption->has_arg()) {
if(valstr.length() > 0) {
if(theOption->set_value(valstr,argv,valpos,argc))
return 1 + theOption->nrequired();
else {
string errstr = "Couldn't set_value! valstr=\"" + valstr;
for (int nn=valpos+1; nn<=valpos + theOption->nrequired(); nn++) {
if (nn<argc) errstr += " " + string(argv[nn]);
}
throw X_OptionError(optstr, errstr + "\"");
}
} else if(!theOption->optional()) {
throw X_OptionError(optstr, "Missing non-optional argument");
}
}
if(theOption->optional())
theOption->use_default_value();
else
theOption->set_value(string());
return 1;
}
else
{
if( overWriteMode_!= Ignore)
throw X_OptionError(optstr, "Option already set");
else
return 1;
}
throw X_OptionError(optstr);
return 0;
}
unsigned int OptionParser::parse_long_option(const string& str)
{
string optstr(str);
string valstr;
string::size_type pos = 0;
if((pos = str.find("=", 0)) != string::npos) {
optstr = str.substr(0, pos);
valstr = str.substr(pos + 1, str.length() - pos + 1);
}
parse_option(optstr, valstr, 0,0,0);
return 1;
}
unsigned int OptionParser::parse_config_file(const string& filename)
{
ifstream cf(filename.c_str());
if(cf.fail())
throw X_OptionError(filename, "Couldn't open the file");
OverwriteMode oldMode=overWriteMode_;
overWriteMode_=Ignore;
string optstr; char buffer[1024];
while (cf >> optstr) {
if(optstr[0] == '#')
cf.getline(buffer, 1024); // Read and discard the rest of this line
else if(optstr.substr(0,2) == "--")
parse_long_option(optstr); // Parse a long option
else {
cf.getline(buffer, 1024);
parse_option(optstr, string(buffer), 0, 0, 0);
}
}
overWriteMode_=oldMode;
return 1;
}
unsigned int OptionParser::parse_command_line(unsigned int argc,
char **argv, int skip)
{
unsigned int optpos = 1 + skip;
unsigned int valpos = 1 + skip;
while(optpos < argc) {
unsigned int increments = 0;
string optstr(argv[optpos]), valstr;
if(optstr[0] != '-') // End of parsable options
break;
if(optstr[1] == '-') { // Parse a long opt
increments = parse_long_option(optstr);
optpos += increments;
} else {
valpos = optpos + 1;
for(unsigned int i = 1; i < optstr.length(); ++i)
{
string suboptstr = "-" + optstr.substr(i, 1);
if (valpos<argc) valstr=string(argv[valpos]); else valstr=string();
increments = parse_option(suboptstr, valstr, argv, valpos, argc);
valpos += increments - 1;
}
optpos = valpos;
}
}
return optpos; // User should process any remaining args
}
std::ostream& operator<<(std::ostream& os, const OptionParser p)
{
for(OptionParser::Options::const_iterator o = p.options_.begin();
o != p.options_.end(); ++o)
os << *(*o) << std::endl;
return os;
}
}
|