The overall topic of the course labs (and all assignments) will be a library for parsing command-line arguments.

Definitions

Short option
Argument starts with a dash, one character follows (e.g. "-v")
Long option
Argument starts with two dashes, one or more characters follow (e.g. "--version")
Option
Short option or Long option
Parameters of an option
Argument that follows the option, if the option accepts parameters (according to the user of your library)
Plain argument
Argument that is neither an option nor a parameter of any other option
Delimiter
The argument --. Any subsequent argument is considered to be a plain argument

In the command

cmd -v --version -s OLD --length=20 -- -my-file your-file

there are short options v and s, long options version and length, the OLD and 20 represent parameters to -s and --length respectively. -my-file and your-file are plain arguments in this example.

Functional requirements

Your library must allow the user the following operations in a convenient way:

  • To specify what options the client program accepts, which of them are optional and which of them are mandatory, verify the actual arguments passed to the client program conform to this specification.
  • To define synonyms (at the very least 1:1 between short and long options, but ideally in a more general way).
  • To specify, whether an option may/may not/must accept parameters, verify that the actual arguments passed to the client program conform to this specification.
  • To specify types of parameters, verify that the actual arguments passed to the client program conform to this specification. At the very least the library has to distinguish between string parameters, integral parameters (with either or both: lower and upper bound), boolean parameters, and string parameters with fixed domain (enumeration).
  • To determine what options were passed to the client program together with their parameters.
  • To extract values of all plain arguments. The delimiter may be omitted unless a plain argument starts with -.
  • To document the options and to present the documentation to the user.

It is not necessary to support all the above functions explicitly. For example, the validation of a type of a parameter may be performed implicitly upon retrieval of the value by the user. An exception may be thrown if the corresponding argument has incorrect type.

The requirements are intentionally not exhaustive. Use your creativity :-).

What To Submit

You will be given access to Git repository in our GitLab instance. You are expected to commit your solution there.

In this task, you are supposed to design the API only. Therefore, you are expected to write source code with empty implementations of individual methods (except for return null and similar as required by the compiler). The API you submit must, however, fulfill the requirements written above.

Apart from the bare API, also submit an example program that is able to parse the following arguments (obviously, its run will fail as the implementation of the library would be empty) that are used by time command.

time [options] command [arguments...]

GNU Options
    -f FORMAT, --format=FORMAT
           Specify output format, possibly overriding the format specified
           in the environment variable TIME.
    -p, --portability
           Use the portable output format.
    -o FILE, --output=FILE
           Do not send the results to stderr, but overwrite the specified file.
    -a, --append
           (Used together with -o.) Do not overwrite but append.
    -v, --verbose
           Give very verbose output about all the program knows about.

GNU Standard Options
    --help Print a usage message on standard output and exit successfully.
    -V, --version
           Print version information on standard output, then exit successfully.
    --     Terminate option list.

Do NOT implement the actual command, only show how your API would be used to set-up option parsing for this command.

The source code may be in any of these programming languages: Java, C#, C or C++.

Feel free to commit also files of your build system. But bear in mind that we might ask you to change it later on to ensure smooth integration with our CI environment (however, cmake, make, Ant and Maven are okay). However, do not commit compiled files (`.class`, `.o` etc.).

Helpful questions

  • What classes will the library contain? What purpose will they have?
  • In what way will the user declare individual options, their parameters and synonyms? What data structures could capture these.
  • In what way will the user react to options? How will the options be accessed? Callbacks? List of all options? On-demand access to particular options?
  • In what way will the library validate the arguments? Explicitly/implicitly? Exceptions/Error codes? Will the library produce warnings displayed to the user directly?

Hints

  • Take a look at existing libraries out there.
  • Try to remove their downsides (what annoys you about the library).
  • Modify some of your previous projects to use your API to parse its options. You might descover imperfections of the design early in the process.