git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@641 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
504
tools/pymol_asphere/src/commandline.cpp
Executable file
504
tools/pymol_asphere/src/commandline.cpp
Executable file
@ -0,0 +1,504 @@
|
||||
/***************************************************************************
|
||||
commandline.cpp
|
||||
W. Michael Brown
|
||||
-------------------
|
||||
|
||||
Command line parsing stuff..
|
||||
* Add argument with ' ' for arguments that do not use - (i.e. filenames)
|
||||
* Manditory for the ' ' requires only 1 argument regardless of the number
|
||||
- use argsize;
|
||||
|
||||
begin : Sun Jun 11 2003
|
||||
copyright : (C) 2003 by W. Michael Brown
|
||||
email : mbrown@nirvana.unm.edu
|
||||
***************************************************************************/
|
||||
|
||||
#include "commandline.h"
|
||||
|
||||
CommandLine::Parameter::Parameter() {
|
||||
num_args=0;
|
||||
manditory_args=0;
|
||||
manditory=false;
|
||||
dash=false;
|
||||
set=false;
|
||||
}
|
||||
|
||||
CommandLine::Parameter::~Parameter() {}
|
||||
|
||||
CommandLine::CommandLine() {
|
||||
help_set=false;
|
||||
progname="";
|
||||
|
||||
// Set up the default man chapters
|
||||
manchapter_order[0]="NAME";
|
||||
man_chapters["NAME"].clear();
|
||||
manchapter_order[1]="VERSION";
|
||||
man_chapters["VERSION"].clear();
|
||||
manchapter_order[2]="SYNOPSIS";
|
||||
man_chapters["SYNOPSIS"].clear();
|
||||
manchapter_order[3]="DESCRIPTION";
|
||||
man_chapters["DESCRIPTION"].clear();
|
||||
manchapter_order[4]="PARAMETERS";
|
||||
man_chapters["PARAMETERS"].clear();
|
||||
man_numchapters=5;
|
||||
}
|
||||
|
||||
CommandLine::~CommandLine() {
|
||||
}
|
||||
|
||||
void CommandLine::addargname(char n, const string &an) {
|
||||
parameters[n].argnames.push_back(an);
|
||||
}
|
||||
|
||||
void CommandLine::adddescription(char n, const string &d) {
|
||||
parameters[n].description.push_back(d);
|
||||
}
|
||||
|
||||
// Returns the argument size for a parameter
|
||||
unsigned CommandLine::argsize(char n) {
|
||||
return parameters[n].args.size();
|
||||
}
|
||||
|
||||
bool CommandLine::operator [](char n) {
|
||||
return set(n);
|
||||
}
|
||||
|
||||
string CommandLine::program_name() {
|
||||
return progname;
|
||||
}
|
||||
|
||||
string CommandLine::full_command_line() {
|
||||
return full_line;
|
||||
}
|
||||
|
||||
// ----------------- Add allowed arguments
|
||||
|
||||
void CommandLine::add(char n, unsigned num) {
|
||||
check(n);
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory_args=num;
|
||||
}
|
||||
|
||||
// Where num represents maximum number of arguments and man_num represents
|
||||
// manditory number of arguments for a parameter
|
||||
void CommandLine::add(char n, unsigned num, unsigned man_num) {
|
||||
check(n);
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory_args=man_num;
|
||||
}
|
||||
|
||||
void CommandLine::addmanditory(char n, unsigned num) {
|
||||
check(n);
|
||||
parameters[n].manditory_args=num;
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory=true;
|
||||
}
|
||||
|
||||
// Where num represents maximum number of arguments and man_num represents
|
||||
// manditory number of arguments for a parameter
|
||||
void CommandLine::addmanditory(char n, unsigned num, unsigned man_num) {
|
||||
check(n);
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory_args=man_num;
|
||||
parameters[n].manditory=true;
|
||||
}
|
||||
|
||||
// Allow parameter that takes signed numbers as input
|
||||
void CommandLine::addsigned(char n, unsigned num) {
|
||||
check(n);
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory_args=num;
|
||||
parameters[n].dash=true; // Allow dashes in arguments
|
||||
}
|
||||
|
||||
// Allow parameter that takes signed numbers as input
|
||||
void CommandLine::addsigned(char n, unsigned num, unsigned man_num) {
|
||||
check(n);
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory_args=man_num;
|
||||
parameters[n].dash=true; // Allow dashes in arguments
|
||||
}
|
||||
|
||||
void CommandLine::addhelp(char n, unsigned num) {
|
||||
check(n);
|
||||
parameters[n].num_args=num;
|
||||
parameters[n].manditory_args=num;
|
||||
|
||||
help_set=true;
|
||||
help_param=n;
|
||||
}
|
||||
|
||||
// Add descriptions for man pages
|
||||
void CommandLine::addargnames(char n, unsigned num, const string args[]) {
|
||||
for (unsigned i=0; i<num; i++)
|
||||
parameters[n].argnames.push_back(args[i]);
|
||||
}
|
||||
|
||||
void CommandLine::adddescription(char n, unsigned num, const string d[]) {
|
||||
for (unsigned i=0; i<num; i++)
|
||||
parameters[n].description.push_back(d[i]);
|
||||
}
|
||||
|
||||
void CommandLine::addtoman_chapter(const string &name, const string &body) {
|
||||
if (man_chapters.find(name)==man_chapters.end()) {
|
||||
manchapter_order[man_numchapters]=name;
|
||||
man_numchapters++;
|
||||
}
|
||||
man_chapters[name].push_back(body);
|
||||
}
|
||||
|
||||
void CommandLine::addtoman_chapter(const string &name, unsigned line_count,
|
||||
const string body[]) {
|
||||
if (man_chapters.find(name)==man_chapters.end()) {
|
||||
manchapter_order[man_numchapters]=name;
|
||||
man_numchapters++;
|
||||
}
|
||||
for (unsigned i=0; i<line_count; i++)
|
||||
man_chapters[name].push_back(body[i]);
|
||||
}
|
||||
|
||||
void CommandLine::check(char n) {
|
||||
map<char,Parameter>::iterator m;
|
||||
m=parameters.find(n);
|
||||
if (m!=parameters.end()) {
|
||||
cerr << "DEVELOPER ERROR: Parameter: " << n << " set twice!\n";
|
||||
cerr << "commandline.h: Exiting...\n\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
bool CommandLine::optargparams() {
|
||||
map<char,Parameter>::iterator m;
|
||||
for (m=parameters.begin(); m!=parameters.end(); m++)
|
||||
if (m->second.manditory_args<m->second.num_args)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns the number of arguments that are not parameters (' ' name)
|
||||
unsigned CommandLine::argsize() {
|
||||
return parameters[' '].args.size();
|
||||
}
|
||||
|
||||
// Whether or not this parameter was set
|
||||
bool CommandLine::set(char n) {
|
||||
return parameters[n].set;
|
||||
}
|
||||
|
||||
// Force a parameter to be unset
|
||||
void CommandLine::unset(char n) {
|
||||
parameters[n].set=false;
|
||||
}
|
||||
|
||||
char* CommandLine::arg(char n, unsigned num) {
|
||||
return parameters[n].args[num];
|
||||
}
|
||||
|
||||
int CommandLine::argint(char n, unsigned num) {
|
||||
return atoi(parameters[n].args[num]);
|
||||
}
|
||||
|
||||
double CommandLine::argdouble(char n, unsigned num) {
|
||||
return atof(parameters[n].args[num]);
|
||||
}
|
||||
|
||||
string CommandLine::argstring(char n, unsigned num) {
|
||||
string s;
|
||||
s=parameters[n].args[num];
|
||||
return s;
|
||||
}
|
||||
|
||||
bool CommandLine::parse(int argc, char* argv[], Error *error) {
|
||||
unsigned i;
|
||||
map<char,Parameter>::iterator m;
|
||||
char flag;
|
||||
int parameter; // Set to the parameter that arguments are being parsed
|
||||
|
||||
progname=a::filenameonly(argv[0]);
|
||||
full_line=string(argv[0]);
|
||||
for (unsigned i=1; i<unsigned(argc); i++)
|
||||
full_line+=' '+string(argv[i]);
|
||||
|
||||
int argnum=1;
|
||||
while (argnum<argc) {
|
||||
// Set an argument
|
||||
if (argv[argnum][0]!='-') {
|
||||
if (parameters[' '].args.size()==parameters[' '].num_args) {
|
||||
error->addwarning(3,9,"CommandLine","Invalid Command Line Argument: "+
|
||||
string(argv[argnum]));
|
||||
return false;
|
||||
}
|
||||
parameters[' '].set=true;
|
||||
parameters[' '].args.push_back(argv[argnum]);
|
||||
argnum++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set a parameter
|
||||
flag=argv[argnum][1];
|
||||
m=parameters.find(flag);
|
||||
if (m==parameters.end()) {
|
||||
error->addwarning(4,9,"CommandLine","Invalid Command Line Parameter: "+
|
||||
string(argv[argnum]));
|
||||
return false;
|
||||
}
|
||||
// Make sure all required arguments are set before parameters with
|
||||
// optional arguments
|
||||
if (m->second.manditory_args<m->second.num_args)
|
||||
if (parameters[' '].args.size()<parameters[' '].num_args) {
|
||||
error->buffer() << "Parameters with optional arguments must be "
|
||||
<< "placed after manditory commandline arguments";
|
||||
error->addbuf(5,9,"CommandLine");
|
||||
return false;
|
||||
}
|
||||
|
||||
parameter=argnum;
|
||||
argnum++;
|
||||
m->second.set=true;
|
||||
|
||||
// Get the parameter arguments
|
||||
for (i=0; i<m->second.num_args; i++) {
|
||||
// Make sure we are not at the end of the parameter list
|
||||
if (argnum>=argc)
|
||||
if (m->second.args.size()<m->second.manditory_args) {
|
||||
error->buffer() << "Invalid Number of Arguments: -" << m->first
|
||||
<< " requires " << m->second.num_args
|
||||
<< " arguments!";
|
||||
error->addbuf(5,9,"CommandLine");
|
||||
return false;
|
||||
} else
|
||||
break;
|
||||
|
||||
// Assure the right number of arguments for signed numbers
|
||||
if (argv[argnum][0]=='-' && m->second.dash==true)
|
||||
if (!isdigit(argv[argnum][1]))
|
||||
if (m->second.args.size()<m->second.manditory_args) {
|
||||
error->buffer() << "Invalid Number of Arguments: -" << m->first
|
||||
<< " requires " << m->second.num_args
|
||||
<< " arguments!";
|
||||
error->addbuf(5,9,"CommandLine");
|
||||
return false;
|
||||
} else
|
||||
break;
|
||||
|
||||
// Assure the right number of arguments for other numbers
|
||||
if (argv[argnum][0]=='-' && m->second.dash==false)
|
||||
if (m->second.args.size()<m->second.manditory_args) {
|
||||
error->buffer() << "Invalid Number of Arguments: -" << m->first
|
||||
<< " requires " << m->second.num_args
|
||||
<< " arguments!";
|
||||
error->addbuf(5,9,"CommandLine");
|
||||
return false;
|
||||
} else
|
||||
break;
|
||||
|
||||
m->second.args.push_back(argv[argnum]);
|
||||
argnum++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If help was set, we do not need to check for manditory args
|
||||
if (help_set)
|
||||
if (parameters[help_param].set)
|
||||
return true;
|
||||
|
||||
// Assure that the manditory arguments were set for commandline
|
||||
if (parameters[' '].manditory)
|
||||
if (parameters[' '].args.size()<parameters[' '].manditory_args) {
|
||||
error->addwarning(6,9,"CommandLine","Missing Required Argument!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assure that manditory arguments were set for parameters!
|
||||
for (m=parameters.begin(); m!=parameters.end(); m++) {
|
||||
if (m->second.manditory)
|
||||
if (m->second.set==false) {
|
||||
error->buffer() << "Missing Required Argument: \n\n";
|
||||
if (m->first!=' ')
|
||||
error->buffer() << "-" << m->first << " must be set!";
|
||||
error->addbuf(7,9,"CommandLine");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommandLine::write_man_page(ostream & out, const string &version,
|
||||
const string &header) {
|
||||
unsigned i;
|
||||
map<char,Parameter>::iterator m;
|
||||
string bold="\\fB";
|
||||
string italic="\\fI";
|
||||
string regular="\\fR";
|
||||
|
||||
out << ".TH " << program_name() << " 1 \"" << a::date()
|
||||
<< "\"" << " \"" << program_name() << " (" << header << ") "
|
||||
<< version << "\" \"" << header << '\"' << endl;
|
||||
|
||||
// Go through the chapters
|
||||
map<unsigned,string>::iterator mc;
|
||||
for (mc=manchapter_order.begin(); mc!=manchapter_order.end(); mc++) {
|
||||
// NAME Section
|
||||
if (mc->second=="NAME") {
|
||||
out << ".SH NAME\n" << bold << program_name() << regular;
|
||||
if (man_chapters["NAME"].size()!=0) {
|
||||
out << " - ";
|
||||
for (i=0; i<man_chapters["NAME"].size(); i++)
|
||||
out << man_chapters["NAME"][i];
|
||||
}
|
||||
out << endl;
|
||||
continue;
|
||||
} // end NAME
|
||||
|
||||
// SYNOPSIS section
|
||||
if (mc->second=="SYNOPSIS" && man_chapters["SYNOPSIS"].empty()) {
|
||||
out << ".PD 2\n.SH SYNOPSIS\n.PD 1\n.TP\n";
|
||||
if (program_name().length()>6)
|
||||
out << bold << program_name() << regular << " ";
|
||||
else
|
||||
out << ".B " << program_name() << endl;
|
||||
out << format_synopsis(bold,italic,regular) << endl;
|
||||
if (program_name().length()>6)
|
||||
out << ".br\n";
|
||||
if (parameters[' '].num_args!=0 && optargparams())
|
||||
out << ".PD 2\n.PP\nParameters with optional arguments should be placed "
|
||||
<< "after manditory commandline arguments.\n";
|
||||
continue;
|
||||
} // end SYNOPSIS
|
||||
|
||||
// PARAMETERS
|
||||
if (mc->second=="PARAMETERS") {
|
||||
if (!(parameters.size()==0 ||
|
||||
(parameters.size()==1 && (parameters.begin())->first==' '))) {
|
||||
out << ".PD 2\n.SH PARAMETERS\n.PD 1\n";
|
||||
for (m=parameters.begin(); m!=parameters.end(); m++) {
|
||||
if (m->first==' ')
|
||||
continue;
|
||||
out << ".TP\n";
|
||||
out << format_parameter(m->first,bold,italic,regular) << endl;
|
||||
if (format_parameter(m->first,"","","").length()>6)
|
||||
out << ".PD 0\n.TP\n.PP\n.PD 1\n";
|
||||
// Output the description
|
||||
vector<string> fdesc=man_format(m->second.description,bold,
|
||||
italic,regular);
|
||||
for (i=0; i<fdesc.size(); i++)
|
||||
out << fdesc[i];
|
||||
out << endl;
|
||||
} // end for m=
|
||||
}
|
||||
continue;
|
||||
} // end PARAMETERS
|
||||
writeman_chapter(out,mc->second,bold,italic,regular);
|
||||
}
|
||||
}
|
||||
|
||||
void CommandLine::writeman_chapter(ostream &out,const string &name,
|
||||
const string &bold, const string &italic,
|
||||
const string ®ular) {
|
||||
if (man_chapters[name].empty())
|
||||
return;
|
||||
|
||||
out << ".PD 2\n.SH " << name << "\n.PD 1\n";
|
||||
|
||||
vector<string> formatted=man_format(man_chapters[name],bold,italic,regular);
|
||||
for (unsigned i=0; i<formatted.size(); i++)
|
||||
out << formatted[i];
|
||||
out << endl;
|
||||
}
|
||||
|
||||
string CommandLine::format_synopsis(const string &bold, const string &italic,
|
||||
const string ®ular) {
|
||||
string s;
|
||||
map<char,Parameter>::iterator m;
|
||||
bool space=false;
|
||||
|
||||
s=format_parameter(' ',bold,italic,regular)+" ";
|
||||
for (m=parameters.begin(); m!=parameters.end(); m++) {
|
||||
if (m->first==' ')
|
||||
continue;
|
||||
if (space)
|
||||
s+=' ';
|
||||
space=true;
|
||||
if (m->second.manditory==false)
|
||||
s+='[';
|
||||
s+=format_parameter(m->first,bold,italic,regular);
|
||||
if (m->second.manditory==false)
|
||||
s+="]";
|
||||
} // end for
|
||||
return s;
|
||||
}
|
||||
|
||||
// Write a synopsis in plain text format fitted to a given column width
|
||||
void CommandLine::write_text_synopsis(ostream &out, unsigned column_width) {
|
||||
string s=format_synopsis("","","");
|
||||
vector<string> lines;
|
||||
a::format_fit(column_width-program_name().length()-1,s,lines);
|
||||
out << program_name() << " ";
|
||||
for (unsigned i=0; i<lines.size(); i++) {
|
||||
out << lines[i] << endl;
|
||||
for (unsigned j=0; j<(program_name().length()+1); j++)
|
||||
out << " ";
|
||||
}
|
||||
out << endl;
|
||||
}
|
||||
|
||||
string CommandLine::format_parameter(char param, const string &bold,
|
||||
const string &italic,
|
||||
const string ®ular) {
|
||||
Parameter &p=parameters[param];
|
||||
|
||||
string strp="";
|
||||
if (param!=' ')
|
||||
strp=bold+"-"+param+regular;
|
||||
|
||||
if (p.num_args!=0)
|
||||
for (unsigned i=0; i<p.argnames.size(); i++) {
|
||||
if (!(param==' ' && i==0)) // Ignore first space on command args
|
||||
strp+=' ';
|
||||
if (i>=p.manditory_args)
|
||||
strp+='[';
|
||||
if (param!=' ')
|
||||
strp+=italic+p.argnames[i]+regular;
|
||||
else
|
||||
strp+=p.argnames[i];
|
||||
if (i>=p.manditory_args)
|
||||
strp+=']';
|
||||
}
|
||||
|
||||
if (p.argnames.size()<p.num_args)
|
||||
strp+=" [...]";
|
||||
|
||||
return strp;
|
||||
}
|
||||
|
||||
vector<string> CommandLine::man_format(const vector<string> &input,
|
||||
const string &bold, const string &italic,
|
||||
const string ®ular) {
|
||||
vector<string> output;
|
||||
map<char,Parameter>::iterator m;
|
||||
|
||||
for (unsigned i=0; i<input.size(); i++) {
|
||||
string temp=input[i];
|
||||
a::str_replace("\n","\n.PD 0\n.PP\n.PD 1\n",temp);
|
||||
a::str_replace(".EN","\n.EN\n",temp);
|
||||
a::str_replace(".EQ","\n.EQ\n",temp);
|
||||
a::str_replace(".TP","\n.PD 0\n.TP\n.PP\n.PD 1\n",temp);
|
||||
a::str_replace(program_name(),bold+program_name()+regular,temp);
|
||||
for (m=parameters.begin(); m!=parameters.end(); m++) {
|
||||
if (m->first!=' ') {
|
||||
string source="-";
|
||||
source+=m->first;
|
||||
a::str_replace(source,bold+source+regular,temp);
|
||||
}
|
||||
for (unsigned j=0; j<m->second.argnames.size(); j++)
|
||||
a::str_replace(m->second.argnames[j],
|
||||
italic+m->second.argnames[j]+regular,temp);
|
||||
}
|
||||
output.push_back(temp);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user