//
// 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
// .
//
#ifndef INCLUDE_ARGLEX_H
#define INCLUDE_ARGLEX_H
#include
#include
#include
#include
#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 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 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 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