aboutsummaryrefslogtreecommitdiff
path: root/src/tt.options.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tt.options.c')
-rw-r--r--src/tt.options.c90
1 files changed, 90 insertions, 0 deletions
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