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 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
|
//
// srecord - manipulate eprom load files
// Copyright (C) 1998, 1999, 2002, 2003, 2006, 2007 Peter Miller
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program 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
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//
#ifndef INCLUDE_ARGLEX_H
#define INCLUDE_ARGLEX_H
#include <lib/format_printf.h>
#include <list>
#include <vector>
#include <string>
#define ARGLEX_END_MARKER {0,0}
/**
* The arglex class is used to implement a lexical analizer for command
* line arguments. Each comamnd line argument is analized to determine
* if it is a number, a string (file name) or an option.
*/
class arglex
{
public:
/**
* The "normal" command line tokens common to all programs.
*/
enum
{
token_eoln,
token_help,
token_license,
token_number,
token_option,
token_page_width,
token_page_length,
token_stdio,
token_string,
token_tracing,
token_verbose,
token_version,
token_MAX
};
/**
* The value_ty struct is used to represent the value of a
* command line argument.
*/
struct value_ty
{
/**
* The literal string value of the token.
*/
const char *alv_string;
/**
* The integer vale of the token. Only meaningful
* for token_number, otherwise zero.
*/
long alv_number;
};
/**
* The table_ty struct is used to repesent a row of a
* commandline option table, used to match option names with
* their corresponding tokens.
*/
struct table_ty
{
/**
* The name of the commen line option.
*/
const char *name;
/**
* The corresponding token.
*/
int token;
};
/**
* The fatal_error method may be used to print a fatal error
* message, and then exit via the usage() method.
*
* @param fmt
* The format of the string - it controls the rest of the
* arguments. See printf(3) for more information.
* @note
* This method never returns.
*/
void fatal_error(const char *fmt, ...) FORMAT_PRINTF(2, 3);
private:
/**
* The arguments instance variable is used to remember the
* remaining command lie arguments.
*/
std::list<std::string> arguments;
/**
* The token instance variable tracks the current token in the
* parse sequence.
*/
int token;
/**
* The value_string_ instance variable tracks the value of the
* current command line argument.
*/
std::string value_string_;
/**
* The value_number_ instance variable tracks the numeric value
* of the current command line argument. Usually zero unless
* the current command line argument is a number.
*/
long value_number_;
/**
* The table_ptr_vec_t type is used to declare the 'tables'
* instance variable. Also used to simplify the code use to
* manipulate the 'tables' instance variable.
*/
typedef std::vector<const table_ty *> table_ptr_vec_t;
/**
* The tables instance variable tracks the command line token
* tables to be scanned to determine if a command line argument
* is a particular token. There is usually one per derived
* class. Append more tables with the 'table_set' method.
*/
table_ptr_vec_t tables;
/**
* The pushback instance variable tracks command line argument
* (or, often, portions of command line arguments) which have
* been "pushed back" to be re-scanned later.
*/
std::list<std::string> pushback;
protected:
/**
* The table_set method is used to append more command line
* token tables to the list of tables to be scanned. Usually one
* per derived class.
*/
void table_set(const table_ty *);
public:
/**
* The default constructor.
*/
arglex();
/**
* The copy constructor.
*/
arglex(arglex &);
/**
* The normal constructor. The argv and argv should be those
* passed to main(). Not manipulation is required.
*/
arglex(int argc, char **argv);
/**
* The destructor.
*/
virtual ~arglex();
/**
* The token_cur method is used to get the type of the current
* token.
*/
int token_cur() const { return token; }
/**
* The token_next method is used to advance to the next command
* line option and determine what type of token it is.
* It returns the type of the token; this value may also be
* fetched using the token_cur method.
*/
int token_next();
/**
* The token_first method is used to fetch the fisrt command
* like token (rather than use the token_next method). This does
* standard "help" and "version" options.
*/
int token_first();
/**
* The value_string method is used to get the string value of
* the current token.
*/
const std::string &value_string() const { return value_string_; }
/**
* The value_number method is used to get the numeric value of
* the current token.
*/
long value_number() const { return value_number_; }
/**
* The token_name method is used to turn a token type number
* into an equivalent string. Useful for some error messages.
*/
const char *token_name(int);
/**
* The usage method is used to print a usage summary.
* This is a fatal error; this method does not return.
*/
void usage() const;
/**
* The help method is used to print a help message.
*/
void help(const char * = 0) const;
/**
* The version method is used to print a version message.
*/
void version() const;
/**
* The license method is used to print the license conditions
* of the program.
*/
void license() const;
/**
* The bad_argument method is used to print an error message
* when the current token is inappropriate, then it calls usage,
* which exits. This method does not return.
*/
void bad_argument() const;
/**
* The usage_tail_set method is used to set the end of the
* command line to be printed as part of the usage method.
*/
void usage_tail_set(const char *);
/**
* The default_command_line_processing method is used to process
* command line arguments not handled by the derived class.
*/
virtual void default_command_line_processing();
private:
/**
* The usage_tail_ instance variable tracks the end part of
* the command line printed by the 'usage' method.
* Defaults to the empty string.
*/
mutable const char *usage_tail_;
/**
* The usage_tail_get method is used to get the tail end of
* the command line to be printed by the 'usage' method.
*/
const char *usage_tail_get() const;
/**
* The read_arguments_file method is used to process @filename
* command line arguments. The file is read and separated into
* space separated words, and each word added to the arguments
* instance variable in the appropriate sequence.
*
* Blank lines are ignored.
* Comments (starting with '#' until end of line) are ignored.
*
* @param filename
* The name of the file (not including the @) to be read.
*/
void read_arguments_file(const char *filename);
};
/**
* The arglex_compare function is used to compare a command line string
* with a formal spec of the option, to see if they compare equal.
*
* The actual is case-insensitive. Uppercase in the formal means a
* mandatory character, while lower case means optional. Any number of
* consecutive optional characters may be supplied by actual, but none
* may be skipped, unless all are skipped to the next non-lower-case
* letter.
*
* The underscore (_) is like a lower-case minus, it matches "", "-"
* and "_".
*
* The "*" in a pattern matches everything to the end of the line,
* anything after the "*" is ignored. The rest of the line is pointed
* to by the "partial" variable as a side-effect (else it will be 0).
* This rather ugly feature is to support "-I./dir" type options.
*
* A backslash in a pattern nominates an exact match required, case
* must matche excatly here. This rather ugly feature is to support
* "-I./dir" type options.
*
* For example: "-project" and "-P' both match "-Project", as does
* "-proJ", but "-prj" does not.
*
* For example: "-devDir" and "-d_d' both match "-Development_Directory",
* but "-dvlpmnt_drctry" does not.
*
* For example: to match include path specifications, use a pattern
* such as "-\\I*", and the partial global variable will have the path
* in it on return.
*/
bool arglex_compare(const char *formal, const char *actual);
#endif // INCLUDE_ARGLEX_H
|