From c3143fbdb7ea46539023e11cb30a7b14434030f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Fri, 23 Oct 2020 02:11:59 +0200 Subject: release 1.2 --- src/tt.options.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/tt.options.c (limited to 'src/tt.options.c') diff --git a/src/tt.options.c b/src/tt.options.c new file mode 100644 index 0000000..f502a7a --- /dev/null +++ b/src/tt.options.c @@ -0,0 +1,90 @@ +// Command-line flags +// ============================================================================ + +// tt can be configured by changing the value of three variables: +// -> declarations + +char *code_prefix; /* string with which code lines should start */ +char *doc_prefix; /* string with which documentation lines should start */ +char *out_prefix; /* string to which the output file name should be appended */ + +// The default values are the following: -> main.options + + code_prefix = " "; /* code lines should begin with four spaces */ + doc_prefix = ""; /* other lines are documentation lines */ + out_prefix = "out/"; /* all output files go in the out/ directory */ + +// Each variable is controlled by a single-letter command-line flag, which +// should then be immediately -- without any space -- followed by the +// desired value. For example, -dfinal. would set out_prefix to "final.". + +// This convention allows for a very simple parsing loop: -> main.options + + for (i = 1; i < argc; i++) + if (argv[i][0] == '-') { + switch(argv[i][1]) { + case 'c': + code_prefix = argv[i] + 2; + break; + case 'd': + doc_prefix = argv[i] + 2; + break; + case 'o': + out_prefix = argv[i] + 2; + break; + case '-': + i++; + goto end; + default: + die(USAGE); + } + } else + break; +end: + +// If the given argument begins with a hyphen, it is interpreted as a flag. +// If the flag is --, then tt ignores the argument and stops looking for flags. +// If the flag is unrecognized, the program dies. If the argument does not +// begin with a hyphen, it and anything following it will not be interpreted +// as a flag. + +// USAGE contains information about how to use tt: -> definitions + +#define USAGE "usage: %s [-cCODE_PREFIX] [-dDOC_PREFIX] [-oOUTPREFIX] destination ...\n", argv[0] + +// Of course, we can't just trust the user to provide reasonable values, so we +// ensure that the code_prefix and out_prefix are not identical and that the +// out_prefix is not empty -- otherwise, tt would overwrite all destination +// files: -> main.options + + if (strcmp(code_prefix, doc_prefix) == 0) + die("code_prefix and doc_prefix cannot be identical\n"); + if (strlen(out_prefix) == 0) + die("out_prefix cannot be empty\n"); + +// Command-line arguments +// ============================================================================ + +// Having finished parsing command-line flags, it is time to collect the +// remaining command-line arguments, which should be one or more destination +// files. Our loop above, when broken out of or finished naturally, has set +// the i variable to the position of the first non-flag argument in argv (or +// simply the position after the last flag in argv). + +// First, we check if there actually are any further argument, or if i is past +// the end of the array: -> main.options + + if (i == argc) die(USAGE); + +// At least one destination file is required. Then, we save the position of the +// first destination file in argv in a special variable for later use: +// -> main.options + +offset = i; + +// -> main.declarations + +int offset; + +// Now, we have successfully finished parsing both flags and arguments, and are +// ready to read the lines on the standard input. \ No newline at end of file -- cgit v1.2.3