Galaxy Communicator Documentation:

Command Line Argument Parsing and Printing Utilities

License / Documentation home / Help and feedback

As part of establishing a single Communicator library, we have provided copies of MIT functionality for command line argument parsing and printing. This documentation has been largely adapted from the MIT documentation, and we've included their copyright below.


Command line argument parsing

The SLS online argument (oa) facility provides a simple interface to standard online argument parsing. It allows easy specification of program usage and easy extraction of the actual options specified by the user at runtime. It performs some simple usage checking, and also provides documentation of the program by printing out the usage line along describing each program option. This documentation has been broken down into the following areas:

Program Model

The program model is as follows:
        program [options] [variable arguments]
When a program is invoked, first options (if any) are specified, and then variable arguments (if any) are specified. Their is a finite set of options, and each option consists of a key (a string that starts with a `-') followed by a fixed number of arguments for that key. For example, an option might be "-copy from to". Here the key is -copy, and the two arguments are from and to. The variable arguments must appear after all options, and is just an arbitrarily long list of strings (often zero).

When a program is called with no online arguments, or with the -help option, it should print out a help line indicating its usage. If a user of this program gives too few or too many arguments to a given key, the program will do its best to detect this and signal some kind of warning or error.

Overview

The usage of a program is specified with a single char * array, typically called oas and defined at the very top of a program (after the includes):
char *oas[] =
  {"-lex file", "the file containing the lexicon", "default.lex",
   "-subtract file1 file2", "remove the words in file2 from file1", NULL, NULL,
   "-set_weight N", "word weight", "5.0",
   "-disable", "turn off the default checking",
   NULL
  };
The oas string contains one entry for each key (usually one entry per line, but not required), where an entry can have a variable number of strings. The first string in an entry is the key string, which contains the key and the arguments needed by the key, separated by spaces. The library determines how many arguments a key takes from this string. Next is the description of what the key does, to be used when printing out the usage line. This description should be succint and helpful. Following the description is a default string for each of the arguments of the key. These are the defaults that are to be used if the user doesn't specify the key on the command line. Each default can optionally be NULL, meaning that argument does not have a default. There must be as many default strings as there are arguments to the key. The oas string must be terminated with a single NULL in the slot where the next key would otherwise be.

Before calling any other OA functions, the program should first call GalUtil_OACheckUsage(). This function checks first the programmer's usage in writing the oas list, and second the user's usage (i.e., whether the user used a key with too few arguments, or whether an extra argument was inserted between keys, etc). This function will print out the usage line, and return 0 if the usage failed, and return 1 otherwise. If it returns zero, the program should just exit (since GalUtil_OACheckUsage() will print the usage line). The function GalUtil_OaPrintUsage() prints the usage help line.

To actually extract arguments, use the function GalUtil_OAExtract(). This function takes arc, argv, and the oas list, followed by the key you'd like to extract, followed by pairs of a type specification, and a pointer to where the argument should be stored. For each argument of the key, oa_extract will set the variables according to the requested type. For example, using the above oas one could call:

GalUtil_OAExtract(argc, argv, oas, "-set_weight", GAL_OA_INT, &n);

Variable Arguments

Variable arguments must appear after all of the keys when the program is invoked. The function GalUtil_OACheckUsage() can be used to determine the argc where the variable arguments first begin. It will check to be sure that the variable arguments are not intermingled with program options.

To specify a description of variable arguments, use the special key "REST". This is the only legal key without a `-', and the OA library treats is specially.

Help

The program should detect if argc is 1 and print the usage line, if that is appropriate. The OA library will automatically detect when the user specifies -help, and print the usage line accordingly (GalUtil_OACheckUsage() does this). Furthermore, this will automatically be printed in the usage line (the -help key), and need not be specified in the oas list. Also, if there is an error in GalUtil_OACheckUsage(), it will print the usage line and return 0.

int GalUtil_OACheckUsage(int argc, char **argv, char **oas, int *first_real_arg)
This function quickly looks through the oas list and through the actual online arguments specified, and verifies that the usage is correct (to a first approximation). It checks that arguments are not missing nor that there are extra arguments, and also verifies that the oas list is formatted correctly. This function must be called once at the start of the program before GalUtil_OAExtract(). If first_real_arg is non-NULL, this integer will be set to the argc of the first fixed argument. The function returns 0 if there is an error and 1 if usage is correct.

void GalUtil_OAPrintUsage(int argc, char **argv, char **oas)
This function prints the help line of the program. It should be called when the user has not called the program properly.

int GalUtil_OAExtract(int argc, char **argv, char **oas, const char *key, ... )
This function is used to extract the arguments specified by the user. This function is called for a single key, and will return the arguments of that key casted to a specific type. The number of type/p_value pairs must be equal to the number of arguments specified by the key. For example, for the key "-copy from to", there must be two pairs of type/value. The exception to this is a binary key (one with zero arguments, for example "-debug"). In this case, GalUtil_OAExtract() takes one pair of type/value, and it will set the value to be GAL_TRUE or GAL_FALSE depending on whether the key was specified. This is just an alternative to looking at the return value of GalUtil_OAExtract() to determine if the user specified the key. If the user did not specify the key, then the values are set to the defaults specified on the oas list. The allowed types are:

Memory management

GalUtil_OAExtract() does not allocate any memory, so when the type is GAL_OA_STRING the pointer will be exactly the corresponding argv.


void GalUtil_OAExtractAsserting(int argc, char **argv, char **oas, const char *key, ... )
This is the same as the above, but it aborts (exits) if the user did not specify the argument.
 


Printing

These functions provide the developer with control over how messages get displayed or processed, and the user with run time control over the verbosity of messages. This is accomplished by defining levels or classes of messages, each with an associated function. Developers using this facility decide at which level a message is printed by calling the function corresponding to that level (e.g. GalUtil_Error(), GalUtil_Warn(), GalUtil_Debug(), etc).

Whether or not the message passed to that function gets printed is determined at runtime by the user's GAL_VERBOSE environment variable, or by the -verbosity arguments of the Hub or server. This allows the user to have run time control over the number and nature of messages which get printed. Setting GAL_VERBOSE to 0 turns off all printing. Incrementing it by 1 turns on printing of additional message classes, until 6, at which point all printing is turned on. Increasing GAL_VERBOSE beyond 6 has no effect. The default verbosity is 3.

Note that MIT servers use the MIT equivalent of these facilities in places, and you should also set SLS_VERBOSE as well.

For version 4.0, we've attempted to rationalize the information printed out at each verbosity level, as follows:

Note that these verbosity level generalizations apply only to the Galaxy Communicator core. Anyone who uses these functions is encouraged to respect these levels (e.g., nothing but crucial errors until level 3, ordinary status messages at level 3, more detailed status and error messages at levels 4 and above).

int GalUtil_SetVerbose(int verbose_level)
This function sets the verbosity level for the executable. It can be called at any time. It returns the new verbosity level. Input values less than zero will be normalized to the default verbosity of 3.

The following functions are available for increasing degrees of verbosity:

GAL_VERBOSE > 0

void GalUtil_Fatal(const char *format, ... )
void GalUtil_Error(const char *format, ... )
void GalUtil_Assert(int truth, const char *format, ... )

Note that GalUtil_Fatal() and GalUtil_Assert() will quit the program in addition to providing an error message.

GAL_VERBOSE > 1

void GalUtil_Warn(const char *format, ... )

GAL_VERBOSE > 2

void GalUtil_PInfo1(const char *format, ... )
void GalUtil_CPInfo1(int fore, int back, const char *format, ... )

GAL_VERBOSE > 3

void GalUtil_PInfo2(const char *format, ... )
void GalUtil_CPInfo2(int fore, int back, const char *format, ... )

GAL_VERBOSE > 4

void GalUtil_Debug1(const char *format, ... )

GAL_VERBOSE > 5

void GalUtil_Debug2(const char *format, ... )

In addition, there are two functions which allow the user to set a minimum verbose level.

void GalUtil_Print(int level, const char *format, ... )
void GalUtil_CPrint(int level, int fore, int back, const char *format, ... )
Prints in color or b/w if GAL_VERBOSE exceeds level.

void GalUtil_VerboseUseBW(void )
Print for a black and white xterm. Default.

void GalUtil_VerboseUseColor(void )
Print for a color xterm.

Other utilities

void GalUtil_fprintf(FILE *fp, const char *fmt, ... )
Equivalent to fprintf(), unless fp is stdout or stderr, in which case GalUtil_Print(-1, ...) is called.

void GalUtil_WarnWithLocation(const char *fn, const char *fmt, ... )
void GalUtil_WarnLevelWithLocation(int level, const char *fn, const char *fmt, ... )
void GalUtil_PrintWithLocation(int level, const char *fn, const char *fmt, ... )
void GalUtil_PInfo1WithLocation(const char *fn, const char *fmt, ... )
void GalUtil_CPInfo1WithLocation(const char *fn, int fore, int back, const char *fmt, ... )
These functions are mostly for internal use, but may prove useful to others. In all these cases, the fn is the name of the function where the printout is called. This string is printed as a prefix to the printed message, when GAL_VERBOSE is 4 or greater.

Print packages

For 4.0, we've added the capability of managing your own printing. The default system prints to stdout and stderr; you can set up your print package to direct output anywhere you want. You can accomplish this by using the function GalUtil_CreatePrintPkg, and setting the result to the value of the global variable GalUtil_CurrentPrintPkg. You can also use your print package directly, using functions like GalUtil_PkgFatal.

typedef void (*GalVLevelFunc)(int level, const char *fmt, va_list args, void *client_data);
typedef void (*GalVCLevelFunc)(int level, int fore, int back, const char *fmt, va_list args, void *client_data);
typedef void (*GalVPrintfFunc)(const char *fmt, va_list args, void *client_data);
typedef void (*GalVCPrintfFunc)(int fore, int back, const char *fmt, va_list args, void *client_data);

extern GalUtil_PrintPkg *GalUtil_CurrentPrintPkg;

GalUtil_PrintPkg *GalUtil_CreatePrintPkg(GalVPrintfFunc fatal_func, GalVPrintfFunc error_func, GalVPrintfFunc warn_func, GalVLevelFunc level_func, GalVCLevelFunc clevel_func, GalVPrintfFunc pinfo1_func, GalVPrintfFunc pinfo2_func, GalVCPrintfFunc cpinfo1_func, GalVCPrintfFunc cpinfo2_func, GalVPrintfFunc debug1_func, GalVPrintfFunc debug2_func, void *client_data)
Produces a print package which is used when the various print functions are called, as follows:

Finally, the client_data is passed to each of these functions, as arbitrary data each function can use when printing.

void GalUtil_PkgFatal(GalUtil_PrintPkg *pkg, const char *format, ... )
void GalUtil_PkgWarn(GalUtil_PrintPkg *pkg, const char *format, ... )
void GalUtil_PkgError(GalUtil_PrintPkg *pkg, const char *format, ... )
void GalUtil_PkgPrint(GalUtil_PrintPkg *pkg, int level, const char *format, ... )
void GalUtil_PkgCPrint(GalUtil_PrintPkg *pkg, int level, int fore, int back, const char *format, ... )
void GalUtil_PkgPInfo1(GalUtil_PrintPkg *pkg, const char *format, ... )
void GalUtil_PkgPInfo2(GalUtil_PrintPkg *pkg, const char *format, ... )
void GalUtil_PkgCPInfo1(GalUtil_PrintPkg *pkg, int fore, int back, const char *format, ... )
void GalUtil_PkgCPInfo2(GalUtil_PrintPkg *pkg, int fore, int back, const char *format, ... )
void GalUtil_PkgDebug1(GalUtil_PrintPkg *pkg, const char *format, ... )
void GalUtil_PkgDebug2(GalUtil_PrintPkg *pkg, const char *format, ... )
void GalUtil_PkgAssert(GalUtil_PrintPkg *pkg, int truth, const char *format, ... )
Identical to GalUtil_Fatal, etc., except that pkg is a print package to use.


License / Documentation home / Help and feedback
Last updated June 21, 2002