1 /*************************************************************************** 2 commandline.h 3 W. Michael Brown 4 ------------------- 5 6 Command line parsing stuff.. 7 8 begin : Sun Jun 11 2003 9 copyright : (C) 2003 by W. Michael Brown 10 email : mbrown@nirvana.unm.edu 11 ***************************************************************************/ 12 13 #ifndef COMMANDLINE_H 14 #define COMMANDLINE_H 15 16 #include "error.h" 17 #include "misc.h" 18 #include <map> 19 #include <vector> 20 #include <string> 21 #include <stdlib.h> 22 #include <iostream> 23 using namespace std; 24 25 /// Parsing of command-line parameters and automatic man page generation 26 /** Allows manditory and optional command line arguments to be specified along 27 * with parameters set using flags. For arguments that do not require flags, 28 * a space char is used to set the flag. To specify the command line: 29 * 30 * foo input_file output_file -t signed_number [-o] 31 * 32 * \verbatim CommandLine cl; 33 cl.addmanditory(' ',2); 34 cl.addargname(' ',"input_file"); cl.addargname(' ',"output_file"); 35 cl.addsigned('t',1,1); 36 cl.addargname('t',"arg_name"); 37 cl.adddescription('t',"Manditory parameter allowing signed_numbers"); 38 cl.add('o',0); 39 \endverbatim 40 * To instead specify that the outputfile is an optional argument: 41 * \verbatim cl.addmanditory(' ',2,1) \endverbatim 42 * 43 * A help flag can also be set which does not require other command line 44 * arguments to be set 45 * 46 * When the commandline is parsed, it is asserted that all manditory arguments 47 * and flags are set, that each flag is set with the correct number of 48 * parameters, and that no unknown flags have been set. 49 * 50 * One can check whether or not optional flags have been set using set() or 51 * the [] operator: 52 * \verbatim cl.set('o') <--> cl['o'] \endverbatim 53 * 54 * Man pages can be generated automatically by adding chapters. The SYNOPSIS 55 * and description of commandline arguments and flags is generated 56 * automatically. Examples of chapters that are consistently used are 57 * NAME, VERSION, DESCRIPTION, PARAMETERS, USAGE, EXAMPLES, AUTHORS, BUGS, 58 * SEE ALSO. 59 * 60 * The following characters can be used for formatting in parameter 61 * descriptions and chapters: 62 * \verbatim 63 \t tab 64 \n forced newline 65 .TP new paragraph (margin indented) 66 \\fB all following text is bold 67 \\fI all following text is italic 68 \\fR all following text is regular 69 \endverbatim 70 * 71 * The arguments, flags and parameter_names are automatically formatted 72 * throughout the man page with bold and italic typeface. 73 **/ 74 class CommandLine { 75 public: 76 CommandLine(); 77 ~CommandLine(); 78 79 /// Add an optional argument which takes num parameters 80 /** \note Use ' ' for n to specify an argument with no flag 81 * \param n flag used to pass arguments (i.e. -f) 82 * \param num the number of arguments that must be specified after flag */ 83 void add(char n, unsigned num); 84 /// Add a manditory argument which takes num parameters 85 /** \sa add() **/ 86 void addmanditory(char n, unsigned num); 87 /// Add a flag which can take signed numbers as parameters 88 /** \sa add() **/ 89 void addsigned(char n, unsigned num); 90 91 /// Add an optional flag with minimum and maximum number of args 92 /** \sa add() **/ 93 void add(char n, unsigned num, unsigned man_num); 94 /// Add a manditory flag with minimum and maximum number of args 95 /** \sa add() **/ 96 void addmanditory(char n, unsigned num, unsigned man_num); 97 /// Add a flag with minimum and maximum number of args that takes signed nums 98 /** \sa add() **/ 99 void addsigned(char n, unsigned num, unsigned man_num); 100 101 /// Add a help argument (does not require other manditory arguments be set) 102 /** \sa add() **/ 103 void addhelp(char n, unsigned num); 104 105 /// Specify the names for arguments in the synopsis (for man page) 106 /** The names can be added one by one in the order of the flag parameters **/ 107 void addargname(char n, const string &an); 108 /// Specify the names for arguments in the synopsis (for man page) 109 void addargnames(char n, unsigned num, const string args[]); 110 /// Specify the description for an argument (for the man page SYNOPSIS) 111 /** See the class description for formating characters **/ 112 void adddescription(char n, const string &d); 113 /// Specify the description for an argument (for the man page SYNOPSIS) 114 /** See the class description for formating characters **/ 115 void adddescription(char n, unsigned num, const string d[]); 116 /// Add a man page chapter with title 'name' 117 void addtoman_chapter(const string &name,const string &body); 118 /// Add a man page chapter with title 'name' 119 void addtoman_chapter(const string &name,unsigned line_count, 120 const string body[]); 121 122 /// Returns the number of arguments that are not flags (char n=' ') 123 unsigned argsize(); 124 /// Returns the number of parameters passed for a given flag 125 unsigned argsize(char n); 126 /// Returns true if the optional flag was set on the commandline 127 bool set(char n); 128 /// Returns true if the optional flag was set on the commandline 129 bool operator [](char n); 130 131 /// Force a parameter to be unset 132 void unset(char n); 133 134 /// Return flag parameter or argument as a cstring (0-based index) 135 char *arg(char n, unsigned num); 136 /// Return flag parameter or argument as a integer (0-based index) 137 int argint(char n, unsigned num); 138 /// Return flag parameter or argument as a double (0-based index) 139 double argdouble(char n, unsigned num); 140 /// Return flag parameter or argument as a string (0-based index) 141 string argstring(char n, unsigned num); 142 143 /// Parse the command line arguments 144 bool parse(int argc, char* argv[], Error *error); 145 146 /// Return the program name 147 string program_name(); 148 /// Return a string with the entire commandline as entered 149 string full_command_line(); 150 /// Write out a man_page 151 void write_man_page(ostream & out, const string &version, 152 const string &header); 153 154 /// Advanced writing of man page 155 void writeman_chapter(ostream &out, const string &name, const string &bold, 156 const string &italic, const string ®ular); 157 158 /// Return a string with all of the options in a man page synopsis format 159 string format_synopsis(const string &bold, const string &italic, 160 const string ®ular); 161 /// Write a synopsis in plain text format fitted to a given column width 162 void write_text_synopsis(ostream &out, unsigned column_width); 163 164 private: 165 string full_line; 166 void check(char n); 167 // Returns true if parameters have been set with optional arguments 168 bool optargparams(); 169 170 class Parameter; 171 map<char,Parameter> parameters; 172 173 bool help_set; // True if there is a parameter for getting help 174 char help_param; // Parameter for help 175 176 // Stuff for man page 177 string progname; // The name for the program (argv[0]) 178 unsigned man_numchapters; // Number of chapters in man page 179 map<string,vector<string> > man_chapters; 180 map<unsigned, string> manchapter_order; 181 182 // Format a parameter as a string with argument names 183 string format_parameter(char param, const string &bold, const string &italic, 184 const string ®ular); 185 // Formats the strings in input for a man page by replacing newlines and 186 // adding bold and italic fonts to parameters and arguments respectively 187 vector<string> man_format(const vector<string> &input, const string &bold, 188 const string &italic, const string ®ular); 189 190 }; 191 192 // This class is for internal use within CommandLine 193 class CommandLine::Parameter { 194 public: 195 friend class CommandLine; 196 Parameter(); 197 ~Parameter(); 198 199 private: 200 unsigned num_args; // Maximum number of arguments for the parameter 201 unsigned manditory_args; // Minimum number of arguments for the parameter 202 bool manditory; // This parameter MUST be set 203 204 bool dash; // Allow for signed numbers (dashes in args) 205 206 bool set; // This parameter has been set 207 vector<char *> args; 208 209 // Strings for man page description 210 vector<string> argnames; // Names for each argument to the parameter 211 vector<string> description; // Description for how to set this parameter 212 }; 213 214 #endif 215