MS-DOS 6.22 DOSKEY Macro Argument Parsing

In MS-DOS 6.22, the DOSKEY utility intercepts keyboard input to expand user-defined macros before COMMAND.COM interprets them. When a user runs a macro, DOSKEY parses any following command-line text by splitting it into positional tokens, mapping them to predefined replacement symbols such as $1 through $9 or the global $* specifier. Understanding how this substitution occurs clarifies how arguments, delimiters, and special redirection characters are processed and passed to the underlying command interpreter.

Intercepting the Command Buffer

DOSKEY operates as a Terminate-and-Stay-Resident (TSR) program that hooks into interrupt vectors controlling keyboard input (specifically standard buffered input, such as Interrupt 21h, Function 0Ah). When you enter a command line, DOSKEY reads the input buffer before COMMAND.COM receives it.

It isolates the first token—the command or macro name—delimited by whitespace. It then searches its internal memory structures for an identical macro name. If no match is found, the line is forwarded unmodified to the command processor. If a match is found, DOSKEY halts standard line evaluation and initiates macro argument expansion.

Positional Argument Parsing ($1 through $9)

DOSKEY handles individual parameters via dollar-sign notation:

  • Token Separation: DOSKEY scans the text following the macro invocation. It identifies individual arguments by looking for standard DOS command-line delimiters: spaces, horizontal tabs, commas (,), semicolons (;), and equals signs (=). Consecutive delimiters are collapsed into single separators.
  • Token Assignment: The first delimited string is mapped to $1, the second to $2, and so on, up to $9. DOSKEY supports a maximum of nine positional parameters.
  • Null Substitution: If a macro definition references a parameter that was not supplied on the command line (for example, the macro contains $3, but only two parameters were entered), DOSKEY replaces the placeholder with an empty string rather than throwing a syntax error.

Global Argument Parsing ($*)

When a macro definition includes the $* symbol, DOSKEY bypasses token-by-token splitting for that specifier:

  • Unmodified Capture: $* captures the entire tail of the command line immediately following the macro name.
  • Preservation of Whitespace: Unlike the positional $1–$9 parameters, $* preserves leading, trailing, and embedded spaces, as well as literal delimiter characters.
  • Coexistence with Positional Tokens: A macro can include both positional tokens and $*. In such instances, the positional arguments still receive their respective individual values, while $* simultaneously expands to the complete trailing argument string.

Handling Metacharacters and Redirection

Because standard DOS redirection characters (<, >, |) and chaining characters execute immediately if entered during the macro definition phase, DOSKEY relies on dollar-prefixed aliases:

  • $G or $g: Converts into the output redirection symbol (>).
  • $G$G: Converts into the append redirection symbol (>>).
  • $L or $l: Converts into the input redirection symbol (<).
  • $B or $b: Converts into the pipe symbol (|).
  • $T or $t: Functions as a command separator, allowing multiple commands within a single macro.

During macro expansion, DOSKEY translates these dollar tokens into their literal ASCII counterparts (>, <, |). If $T is encountered, DOSKEY breaks the expanded text into distinct sequential command buffers, queueing each command to run in sequence.

Final Execution Hand-off

Once all token replacements ($1–$9, $*) and metacharacter translations are finalized within DOSKEY’s internal expansion buffer, the resulting string is placed back into the system's standard input buffer. COMMAND.COM then reads this translated string as if the user had typed the expanded commands, arguments, and pipe/redirection operators directly into the DOS prompt.