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
|
#ifndef APPLICATION_H_INCLUDED
#define APPLICATION_H_INCLUDED
#include <string>
// A general application.
// This could solve several problems:
// - the help text could be automatically generated
// - duplicate main code could be removed
// - it would be easy to parse options
// - all applications could be linked to a single file thereby saving disk-space
class Application{
// Nested Option Classes
class Option{
bool hidden;
protected:
static Option *constructionList;
public:
Option();
bool isHidden()const;
void hide(bool b=true);
virtual bool matches(const char *s)=0;
virtual void onOptionsParsed();
virtual std::string documentationMatchString()=0;
virtual std::string documentationDescription()=0;
virtual void parseValue(int t, char **argv, bool *ok, int *numberOfArgumentsParsed)=0;
static Option *getOptionList();
Option *next;
};
protected:
class StringMatchingOption: public Option
{
protected:
const char *matchString;
const char *description;
bool isExactMatch(const char *s);
public:
virtual std::string documentationMatchString();
virtual std::string documentationDescription();
StringMatchingOption(const char *s, const char *description_="");
bool matches(const char *s);
};
class SimpleOption: public StringMatchingOption{
bool value;
public:
SimpleOption(const char *s, const char *description);
void parseValue(int t, char **argv, bool *ok, int *numberOfArgumentsParsed);
bool getValue();
};
class ValueOption: public StringMatchingOption{
public:
virtual std::string documentationMatchString();
virtual void assignValue(const char *s)=0;
ValueOption(const char *s, const char *description);
void parseValue(int t, char **argv, bool *ok, int *numberOfArgumentsParsed);
};
class StringOption: public ValueOption{
const char *value;
public:
StringOption(const char *s, const char *description, const char *initialValue=0);
void assignValue(const char *s);
const char *getValue();
};
class IntegerOption: public ValueOption{
int value;
bool hasRange;
int lower,upper;
public:
IntegerOption(const char *s, const char *description, int initialValue=0);
IntegerOption(const char *s, const char *description, int initialValue, int lower, int upper);
void assignValue(const char *s);
int getValue();
};
class ZeroOneOption: public IntegerOption{
public:
ZeroOneOption(const char *s, const char *description, int initialValue=0);
};
// Application members
private:
static class Application *applicationList;
static class Application *findApplication(char *name);
protected:
static void makeSymbolicLinks(char *name, bool all, const char *path);
static void produceLatexDocumentation(bool all);
class Application::Option* optionList;
public:
Application();
class Application *next;
bool parseOptions(int argc, char **argv, int argumentsToSkip);
virtual bool includeInDefaultInstallation();
void registerOptions();
virtual void printHelp();
virtual int main()=0;
virtual void onExit();
virtual const char *helpText()=0;
friend int main(int argc, char *argv[]);
virtual char *name()=0;
};
#endif
|