Artifact [2e2172220f]

Artifact 2e2172220f240455acd1a0bfae7cfa4113ccb64bdd9bdee3cd84fd4fae39cb07:

Wiki page [TRS-DOS Command Line Options Parser in C] by kc5tja 2017-09-01 02:21:31.
D 2017-09-01T02:21:31.682
L TRS-DOS\sCommand\sLine\sOptions\sParser\sin\sC
N text/x-markdown
U kc5tja
W 3601
# TRS-DOS Command Line Options Parser in C

One thing a ton of early home computers had in common with many mainframes and minicomputers was that real-world operating systems had consistently used libraries for parsing out options and parameters from command-lines.

When you think about it, they *had* to;
with memory capacities as small as 16KB to 48KB,
there wasn't a whole lot of room in the transient program area for parsing parameters.
Operating systems themselves all had common parameters to a multitude of commands,
so it made sense to just re-use the OS' own CLI parsing functionality.

One of the best systems I've encountered so far has been from TRS-DOS, the
disk operating system for the [TRS-80 Model I/III/IV series of computers](https://en.wikipedia.org/wiki/TRS-80).
It's remarkably simple, and involves perhaps the smallest amount of code I've seen for this purpose yet.

## Syntax of a Command

The following example illustrates literally everything about it.

    cmdfile filename1 ...etc... (key1=value1,key2=value2,switch1) filename3 (switch2)

Switches and parameters are provided inside of parentheses.  Whitespace isn't important usually, but it is conventional to pack everything together.  Switches have no values; parameters do, and are provided by the `=` character.

So, for example, if you wanted to compile a program to start at a specific location in memory, you might find yourself typing something like:

    cc file1/c file1/o (incpath=1:+2:,relocs)
    link file1/o file1/cmd (libs=1:libc/o,at=2000H)

(This is purely hypothetical, of course.  I'm not aware of any C compiler that runs on TRS-80 computers under TRS-DOS.  Also note that TRS-DOS uses `/` as the extension separator, not `.` like in Unix, CP/M, or MS-DOS progeny.)

In this case, we're asking `cc` to produce a relocatable object file with `relocs`; we're also specifying the use of disk drives 1: and 2: for places to look for header files with (TRS-DOS doesn't have any idea about sub-directories).  Finally we `link` the object file with `libc/o`, and instruct it to produce a static executable targetted to run at `2000H` in memory.

## How TRS-DOS CLI Option Handling Works

You configure a look-up table in memory for options you are interested in.
An option name cannot exceed 8 characters in length,
and is associated with a callback handler which the parser calls back
upon discovering that option's name.
There are similar callbacks for processing what looks like normal filenames
as well (basically, anything not enclosed in parentheses).

At program start-up, the application receives from TRS-DOS a pointer to its command-line.
When it's ready to parse it, it passes this pointer to the TRS-DOS parse function,
where it is also provided with the aforementioned lookup-table and callbacks.
As parsing continues, TRS-DOS calls back into your program as options and parameters are plucked out of the command line string.

Synonyms to options must occupy separate table elements,
but may refer to the same handler callbacks.
This allows many TRS-DOS commands to support both long and short names for switches and parameters.


## The Code

The code provided in this repository is just a quick sketch;
it's a C clone of some reverse engineering I performed on some TRS-DOS assembly listings.
It's not pretty code, nor is it particularly clean in this implementation.
Still, I want to archive it, and this is a good place to do it.
I'm almost certain to re-use this code for any Kestrel-2DX OS I come up with
(e.g., a port of STS).

Z 204d4b71eeea673ffcd58a8c43ab0410