Listing 2: The CApp class
class CApp {
public:
// These are const values that can be ORed together
typedef long flags;
static flags fl_null;
static flags fl_req; // required
static flags fl_arg; // argument
// These will be supported in future releases
static flags fl_array; // an array of the same type
static flags fl_multiple; // can be used multiple times,
// first time counts
enum {IgnoreUnknownOptions = 1,
IgnoreUnknownArgs = 2};
CApp(int a_flags = 0);
//...............................................................
// An abstract superclass, parent of all the argument classes
class CArg {
public:
CArg(
char* a_name,
char* a_message,
char* a_environment_variable,
flags a_flags
);
void print_usage(ostream& str);
void print_usage_extended(ostream& str);
int is_required() const {return m_flags & fl_req;};
int is_option() const {return !(m_flags & fl_arg);};
int is_argument() const {return m_flags & fl_arg;};
const char* name() const {return m_name;};
// Member functions to be redefined by subclasses
// All but bool (where merely the appearence of the flag
// signifies the existence) return 1;
virtual int has_length() const {return 1;};
// Subclasses must redefine these
virtual void set_value_from_lexeme(char* lexeme) = 0;
virtual const char* type() = 0;
virtual void print(ostream&) = 0;
protected:
int is_used() const {return m_flags & fl_used;};
char* m_name;
char* m_message;
flags m_flags;
char* m_env_variable;
friend class CApp;
};
//.........................................................
class CCharArg : public CArg {
public:
CCharArg(
char* a_name,
char* a_message,
char a_default_value = ' ',
flags a_flags = 0,
char* a_environment_variable = NULL
) : CArg(a_name, a_message, a_environment_variable, a_flags) {
m_value = a_default_value;
}
void set_value_from_lexeme(char* lexeme) {m_value = lexeme[0];};
const char* type() {return "<char>";};
void set(char c) {m_value = c;};
char get_value() {return m_value;};
char operator()() {return m_value;};
void print(ostream& str) {
str << m_value;
}
protected:
char m_value;
};
//.........................................................
class CCstringArg : public CArg {
public:
CCstringArg(
char* a_name, char* a_message,
char* a_default_value = "", flags a_flags = 0,
char* a_environment_variable = NULL
):CArg(a_name, a_message,
a_environment_variable, a_flags) {
m_value = a_default_value;
}
void set_value_from_lexeme(char* lexeme)
{m_value = lexeme;};
const char* type() {return "<string>";};
void set(char* c) {m_value = c;};
char* get_value() {return m_value;};
char* operator()() {return m_value;};
void print(ostream& str) {
if (m_value != NULL) {
str << m_value;
} else {
str << "NULL";
}
}
protected:
char* m_value;
};
//.........................................................
class CIntArg : public CArg {
// ...
// details omitted
// ...
};
//.........................................................
class CToggleArg : public CArg {
// ...
// details omitted
// ...
};
//----------------------------------------------------------------
static void add(CArg* arg);
void parse(int argc, char** argv) {
m_argc = argc;
m_argv = argv;
set_env_values();
parse_internal();
}
void print_usage_and_exit(const char*, int code = -1);
void fatal(char* str, int code = -1) {
cerr << str << endl;
exit(code);
}
protected:
void parse_argument();
void parse_internal();
void parse_flags();
void set_env_values();
// Data members
static int m_argc;
static char** m_argv;
static CArg** m_args;
static int m_args_index;
static int m_args_max_index;
static int m_flags;
static flags fl_used;
friend class CApp::CArg;
};
ostream& operator<<(ostream&, CApp::CArg*);
/* End of File */