Description of Features and Implementation Status of FreeCOM
Author: Steffen Kaiser
Description: Description of features and implementation status of FreeCOM, the COMMAND.COM replacement
Keywords: DOS, FreeDOS, FreeCOM, COMMAND.COM, CLI
Date: 2001-02-06

1. Introduction
2. FreeCOM Command Line Syntax - Useage, Switches and Options
3. Environment Variables
4. Internal Commands
5. User Prompt
   1. Command Line Syntax
   2. Command Line Editing
6. Features of FreeCOM
7. Status of FreeCOM / To-do List
8. Appendix
   1. Compile FreeCOM - sample
   2. Download
   3. CVS Resources
   4. Bug Tracking / Bugzilla
   5. EBNF

# Introduction

FreeCOM is a:

- Command Line Interface,
- (user) shell and/or
- COMMAND.COM replacement

for DOS. It has been spawned as part of FreeDOS, a project that aims to implement a GNU GPL'ed DOS.

The main duty of FreeCOM is to prompt the user to enter commands, which are interpreted, processed directly by FreeCOM or executed as executable files.

Those commands processed by FreeCOM directly are called Internal Commands.

Non-internal commands, which cannot be processed by FreeCOM directly, are called External Commands, because FreeCOM will search for files equally named as typed-in.

Besides to implement certain commands FreeCOM offers some features.

# Command Line Syntax, Useage, Switches and Options

`COMMAND.COM` [ path [ console ] ] [{ option }] [ `'/'` ( `K` | `C` ) «commandline» ]

If present, the first non-option argument specifies the location in which FreeCOM resides. This location is later stored in the environment variable COMSPEC. Since DOS3+ this option is no longer necessary to find the shell invoked during the boot process, but it may be used to let the system boot a primary shell from one location, but use a shell of the same version from a different location later on.
One shallt not point to a RAMdisk at this time, because FreeCOM needs to reload certain information relatively early during execution, before AUTOEXEC.BAT had been executed, in which, normally, FreeCOM is copied into the RAMdisk.
For convinience FreeCOM checks, if at the given location a FreeCOM exists and is accessable, if not, the given location is ignored. Also, the standard requires to specify a path only, but FreeCOM accepts an absolute filename, so accepting that FreeCOM is not necessarily named `COMMAND.COM`.

The second non-option argument, if present, specifies the console FreeCOM shall enable. This setting is system-wide and is not limited to FreeCOM or just this particular process tree. In its result, this argument is identical to the `CTTY` command.

FreeCOM knows the following options:

- `/?`: Issues a help screen, then exists.
- `/!`: Enable/disable debugging support, if compiled to FreeCOM.
- `/Y`: Enables trace/single step mode. This mode is deaktivated when the user prompt has been reached.
- `/D`: Disables to parse AUTOEXEC.BAT, even if the `/P` option is present. This switch is usually set by the kernel, when F5 had been pressed during bootup.
- `/F`: Enables autofail of Critical Errors; then instead of displaying the Abort/Retry/Ignore/Fail dialog, Critical Errors are automatically answered with Fail.
- `/P`: Installs a primary copy of FreeCOM. Such instance:
  1. cannot be terminated with the `EXIT` command.
  2. executes the `AUTOEXEC.BAT` script before any other command.
  The `/P` option may have an argument to specify an alternate name for the AUTOEXEC script, e.g.: `/P:FDAUTO.BAT`.
- `/E`: Sets another size of the environment segment, in which all the environment variables are stored, e.g.: `/E:1024`.
- `/L`: Sets the size of the internal command buffer. Note: This option is ignored currently, the internal buffer always defaults to 512 bytes.
- `/U` Sets the size of the internal user input buffer. Note: This option is ignored currently. The input buffer always defaults to 255 bytes, which is the maximum.
- `/LOW`: Forces to load FreeCOM low. Note: Currently this option has no effect, because no part of FreeCOM is loaded high.
- `/MSG`: Installs the message server. Note: Because the message server is not used nowadays, this option forces to permanently load FreeCOM's messages into memory.
- `/SWAP`: Toggles, if to default to swapping or not; due to different default values of this internal flag, it is recommended to always prefix the option with '`+`' to enable or '`-`' to disable swapping.

The options `/K` and `/C` are special cases and do not behave as normal options does. They are exclusive and all characters at the right side of such option (except an optional argument sign) specify a command to execute, e.g.: `/C `DIR` /s`, `/C=`DIR` /s`, and `/CDIR /s` do behave exactly the same and execuate the command ``DIR` /s`.
If these options are used in conjunction with the `/P` option, the AUTOEXEC.BAT script is executed prior executing the specified command.
In opposite to `/K` the `/C` option does not enter the interactive shell prompt after executing the specified command unless the `/P` options is present, too.

Boolean options, which can only be enabled or disabled, may be prefixed by '`+`' to enable or '`-`' to disable it.

# Environment Variables

Environment variables can be freely assigned using the `SET` command, e.g. executing:
``SET` var1=tecxsgk;jsdgsdflfsjdflkasjf/lasjflas`
assigns this nonsense to the variable `var1`. Later on, the value of the variable can be used by writing: `%var1%`, thus, writing the name of the variable enclosed without whitespace by two percent signs. Warning: Environment variables are expanded fully into plain text before the command line is furtherly parsed. If a variable contains an odd number of quotes, the remaining command line must contain the closing quote in order to operate properly. Also see this:
``SET` var=text del`
``IF` text==%var% `GOTO` label`
The second line looks uninteresting, but once the environment variable has been expanded the line has morphed into:
``IF` text==text del `GOTO` label`
not that funny anymore, because the `IF` command interpretes only the string `text==text` as condition, but `del `GOTO` label` is executed as command.

FreeCOM uses a number of environment variables for its own purpose.

- COMSPEC: FreeCOM loads some information on demand, these data are stored in the FreeCOM executable. The value of this environment variable contains the filename FreeCOM shall use. The contents can be changed with the `SET` command.
- DIRCMD: The user may define default values for the `DIR` command. Any options specified within `DIRCMD` are prefixing any entered ones, so to say FreeCOM behaves as if the user always types:
  ``DIR` %DIRCMD% &laquo;other arguments&raquo;`
  This variable must be changed using the `SET` command.
- COPYCMD: This variable contains default options for the `COPY` command.
- `PROMPT`: FreeCOM prompts the user to enter commands to run, the prompt can be customized by changing the contents of this variable.
  This variable can be changed using the `SET` or the `PROMPT` commands. Latter one includes a detailed description of the format of the prompt string.
- `PATH`: When FreeCOM is to execute an external command and this one does not contain no path, FreeCOM searched for the command in a number of paths. These ones are enumerated by the `PATH` environment variable.
  This variable can be changed using the `SET` or the `PATH` commands. Latter one includes a detailed description of the format of the search path.

There are a number of automatic variables that do not follow the above mentioned syntax and which contents is automatically generated. Unlike the normal variables these automatic variables are constructed of exactly two characters, the first one is a single percent sign and the second one the variable identifier:

- %?: expands to the current errorlevel, which is the exit code of the previously executed external command.
- %0: in batch scripts only: is the name of the script currently executed.
- %1 through %9: in batch scripts only: are the first through nineth argument passed to the currently executed batch script. If less than nine arguments had been passed to the script, they return an empty string. To access the tenth argument please refer to the `SHIFT` command.
- ``FOR` %v IN (...) DO «any command»`: %v may use any letter, the `FOR` command creates a new variable, which is valid in the «any command» following the `DO` keyword.
- %%: Is no real variable, but expands to a single percent sign.

Because automatic variables have one percent sign only, it sometimes lead to confusion within the `FOR` command, e.g. in:
``SET` adam=eva`
``FOR` %a in (*.*) DO echo %adam% %a`
`%adam` is interpreted as [`%a`]dam.

# Internal Commands

Internal commands will be processed by FreeCOM directly, they are available to the user without presence of any external files, in fact they hide External Commands named equally.

The synopsises of the internal commands are described in a style derived from EBNF.

# User Prompt

FreeCOM knows two modes:

1. Interactive, and
2. batch processing.

The second one performs batch scripts, which are more or less a sequence of commands written to a file. Such files may contain any external commands, internal commands and calls to other batch files as well.

In interactive mode FreeCOM prompts the user to enter a command, the line is interpreted, parsed and, finally, either rejected because of an error or executed.

## Command Line Syntax

FreeCOM accepts the following command line:
[ `':'` ] [ `'?'` ] [ `'@'` ] [ `'*'` ] { command [{ argument | redirection }] : `'|'` }
redirection ::= ( `'<'` | `'>'` | `'>>'` ) filename

The first optional `?` must not be mixed up with the command `?`!

### Description:

The colon marks the line as label, which causes to let FreeCOM ignore the line completely as no interpretation is tried on this line, neiter are any redirections created.

The `?` forces FreeCOM to enable the trace mode for this line. In trace mode FreeCOM prompts the user wether to execute the resulting command.

The optional `@` disables the echo status for this line. If the echo status is enabled, the line is displayed right before it is executed; see `ECHO` for more details.

The asterisk `*` is available only, if aliases are compiled into FreeCOM; if present, the alias expansion is skipped.

If commands are chained with the `|` symbols, those commands are to be executed as a pipe. For instance the command line:
`cmd1 | cmd2 | cmd3`
forms a pipe consisting of the three individual commands `cmd1`, `cmd2`, and `cmd3`, where the standard output stream of `cmd1` is connected to the standard input stream of `cmd2` and the output of `cmd2` to the input of `cmd3`. Note: Because DOS is no multitasking environment, pipes are simulated with file and the three-command pipe will look like this:
`cmd1 >%TEMP%\cmd###1.tmp`
`cmd2 <%TEMP%\cmd###1.tmp >%TEMP%\cmd###2.tmp`
`cmd3 <%TEMP%\cmd###2.tmp`
The files are temporary ones and will be removed as soon as they are no longer required, meaning the tempfile #1 is removed after `cmd2` terminates and tempfile #2 upon termination of `cmd3`.

Redirections tie the standard input or output stream to a file or device, for instance:
`cmd arg <infile >>outfile`
redirects the standard input stream of `cmd` to the file `infile` and the standard output stream to `outfile`. The double output redirection specifies to append to an existing file rather than overwriting it.

## Command Line Editing

FreeCOM offers two methods to interactively enter command lines:

1. standard input, and
2. enhanced input.

The first one just calls a DOS function, whereas the second one processes each key for its own. Which method FreeCOM uses is defined at compile time.

If the echo state is enabled, the user is prompted with the `PROMPT` string; otherwise no visible or audible prompt is issued to indicate an user activity request.

In either mode the `ENTER` key terminates the editing and lets FreeCOM start to interprete the entered line.

The standard input mode does neither support command line history, except the last command line in some circumstances, nor file completion. The following keys have a special meaning:

Key | Meaning
--- | ---
F1 | Get next character from last line, if available
F3 | Get last line, if available
F5 | Place current line in last-line buffer and restart editing on a blank line
F6 | Insert the pseudo-character End-of-file
backspace | delete character to the left
cursor left | delete character to the left
cursor right | Get next character from last line, if available

The enhanced input mode does support command line history and file completion. The following keys have a special meaning:

Key | Meaning
--- | ---
F1 | Get next character from last line, if available
F3 | Get last line, if available
F5 | Place current line in last-line buffer and restart editing on a blank line
backspace | delete character to the left
cursor down | Replace the current input line with the previous line from the history
cursor left | move cursor one character one position to the left
cursor right | Move cursor one position to the right; at the end of the line get next character from last line, if available
cursor up | Replace the current input line with the next line from the history
delete | Deletes the character on the cursor
end | Moves the cursor to the end of the line
ESC | Clear current line
home | moves the cursor to the beginning of the line
insert | Switch between insert and overwrite mode
TAB | Take the current word for a file and try to complete it
^C | Clear current line and enable echo state. The echo state is enabled to ensure the user gets to know he is on the command line of FreeCOM rather than stuck in a non-interruptable program.

# Features of FreeCOM

FreeCOM implements the following features:

- `FEATURE_ALIASES` - Command aliases
- `FEATURE_AUTO_REDIRECT_TO_CON` - Autoswitch CON: to monitor
- `FEATURE_BATCH` - Batch script processing
- `FEATURE_BOOT_KEYS` - check for F5/F8 keys on startup if /P is present
- `FEATURE_CALL_LOGGING` - Startup logging
- `FEATURE_DIRSTACK` - Directory stack
- `FEATURE_ENHANCED_INPUT` - Enhanced command line editing
- `FEATURE_FILENAME_COMPLETION` - Filename completion
- `FEATURE_HISTORY` - Command line history
- `FEATURE_INSTALLABLE_COMMANDS` - Installable Commands interface (MUX-AE)
- `FEATURE_LAST_DIR` - Change back to last directory
- `FEATURE_LOAD_MESSAGES` - Load messages permanently
- `FEATURE_NLS` - use DOS NLS

# Status of FreeCOM

FreeCOM's development currently targets the v1.0 version, which is to provide all functionality (features) of commonly known COMMAND.COMs at minimum, but probably at the cost of optimization and performance.

The To-Do list:

Feature | Target
--- | ---
Swapping without any supporting secondary programs (`KSSF.COM` and `VSPAWN.COM`) | v0.90
INT-2E backdoor | v0.90
Wildcards for ``REN``, same filename pattern matching code for ``REN``, ``COPY`` and ``DIR`` | v0.93
``IF` /I` | v0.85
Input/output functions to replace `<stdio.h>` by `<io.h>` (aka replace `FILE*`-based I/O by handle-based one) | v0.95
Strict error recognition, probably `_doserrno` based | v0.97
Support for `DOS=HIGH` | v0.90
Code sharing of modules | v0.91
Redirection in conjunction with Swapping | v0.90
Optimize FreeCOM for size | post v1.0
Other swap storage areas, e.g. XMS and EMS | post v1.0
Long filenames | post v1.0
internal commands | mostly done
Aliases: `ALIAS` | done
Command line history: `HISTORY` | done
Directory stack: `DIRS`, `PUSHD`, and `POPD` | done
MUX-AE interface | done
Enhanced command line editing, file completion | done
Last directory recognition: `CD`, `CDD`, `PUSHD` | done
Control Break handler | done
Critical Error handler | done
``IF` ERRORLEVEL H<letter>` | done (v0.82pl1)
Full support for DOS NLS | done (v0.82pl1)
``DIR` /O` and ``DIR` /A` | done (v0.82pl2)

Footnotes:

- I/O replacement shallt preceed error reporting correction as some failures are impossible to detect without work-arounds with the `<stdio.h>` functions.
- If I get contributions after v0.90, those portion may be added earlier.

# Appendix

## Compile FreeCOM - sample

Due to heavy request, there is a sample description how to compile FreeCOM in ten steps.

## Download

FreeCOM can be downloaded from SourceForge in several ways and packages:

1. source code files from the CVS repository
2. tarball and pre-compiled packages from anonymous FTP
3. tarball and pre-compiled packages via HTTP
4. tarball and one pre-compiled package as file release

### Resources accessable via anonymous FTP

SourceForge closed the FTP - Services.

### Resources accessable via HTTP

http://freedos.sourceforge.net/freecom/packages/ contains several variants of tarballs and pre-compiled packages of FreeCOM. The files immediately located in the directory contain the most current major release of FreeCOM, whereas the subdirectories include Beta releases of the upcoming release.

The packages themselves include:

file name | contents
--- | ---
`COM###.ZIP` or `Com###Beta##.ZIP` | tarball (the source code tree without CVS information)
`BINARY.ZIP` | the most commonly used pre-compiled FreeCOM with almost any feature, but debugging enabled. This release uses standard swapping mechanisms!
`XMSSWAP.ZIP` | the most commonly used pre-compiled FreeCOM with almost any feature, but debugging enabled. This release uses XMS-Only swapping mechanism!
`PLAINEDT.ZIP` | As `BINARY.ZIP` but using the plain command line editor of the kernel instead of the enhanced one
`DEBUG.ZIP` | As `BINARY.ZIP` with debugging support enabled. This variant is a lot larger than the standard release and can generate lots of output.
`LOCALIZE.ZIP` | As `BINARY.ZIP` but targetted at maintainers of a language description file (`*.LNG`).
`SUPPL.ZIP` | the SUPPL library required for linking FreeCOM precompiled for use with Turbo C++ v1.01
`DOCS.ZIP` | a package with these HTML documents

### File Releases on SourceForge

On SourceForge so-called File Releases can be created. The file release section of the FreeCOM module contains a source ZIP and a binary ZIP file, they are equal to the tarball and the `BINARY.ZIP` on the anon FTP space respectively. Unlike the FTP space, old versions are kept, but no Beta versions or side branches.

## CVS Resources

On SourceForge a short description of how to access the CVS repository is located. Following those instructions will download the main trunk of the specified module of the repository, e.g.:

    cvs -z6 co freecom

downloads the `MAIN` trunk, also called `HEAD`, of FreeCOM.

Alternatively the WebCVS -- follow the `Browse CVS` link there and remember to select the `MAIN` branch -- might be helpful in order to download a handful of files.

However, CVS allows to branch the development of a module at some point from the main trunk into side trees. On these branches the module can be developed further, new features can be added etc., without disturbing the main trunk (and therefore the primary release) of the module. When the side development proved its worthiness, the changes are merged into the main trunk and, hence, becomes part of the primary release.

Branches are marked by tags, though, unlike normal tags branch tags automatically evolve with the file, what means that when a file from a specific branch is updated, the branch tag automatically move from the current version of the file to the new one.
To check out a branch, create a new directory, change within it and execute:

    cvs -z6 co -r tag freecom

, where `tag` is the name of the branch you want to download. Note: It is not advisable to use the same directory to manage files for two different branches.

The FreeCOM module has the following active branches:

Tag | Meaning
--- | ---
expExec | Stack-based execution context implementation
expSpawn | Module based FreeCOM, bases on expRes branch

The FreeCOM module has the following obsoleted branches:

Tag | Meaning
--- | ---
expRes | Resource management implementation. Finally merged into trunk as of 2001/03/10

## Bug Tracking / Bugzilla

FreeCOM uses FreeDOS's Bugzilla for tracking bugs and the like.

## EBNF

Documents encode the synopsis of the commands with operators derived from EBNF (Extended Backus-Naur Formula).

### Type setting

Depending on different meanings characters are set into various shapes:

Name | Meaning | Example
--- | --- | ---
`terminal` | characters to be enterred on command line or displayed by the computer; EBNF: "terminal symbols" | ``ECHO``
`'string'` | The quotes remove the metafunction of the enclosed characters in order to specify EBNF operators as terminal symbols. EBNF: "terminal symbols" | `'|'`
bold | operators that constructs portions together; EBNF: "operators" | |
italic | placeholders for arguments, which are explained in the description; EBNF: "non-terminal symbols" | varname

### Operators

The EBNF uses the following operators:

Symbol | Meaning
--- | ---
| | alternative; use either left or right token
() | parenthizes enclose tokens limiting the range of |
[] | brackets enclose optional tokens, thus, they may appear zero or one time; they also limit the range of |
{} | curly brackets enclose repitive tokens, which may appear one or more times; they also limit the range of |
{ : } | as the normal curly brackets, but any repitive tokens are delimited by the token(s) right of the colon; for instance: { file : `'+'` } is the same as: file [{ `'+'` file }] and applies to: file file + file file + file + file file + file + file + file ...
« » | is a placeholder for an arbitary string of terminal symbols, which further syntax is described by the enclosed text in English natural language.
::= | assigns a meaning (right side) to a non-terminal symbol (left side); for instance
    	DIR [ { option | filespec } ]
    	option ::= / ( A | B | C )
Any occurance -- only one here -- of option on the right side of an ::= or where no ::= is present at all is to be replaced by the right side of option::=.

Unless modified by above mentioned operators a sequence of tokens specifies that each token must be present exactly one time in exactly that order.
Note: For the sake of clearness, spaces are inserted between tokens. These spaces do not mean that a space is allowed at this place! Also, the fact that no _ is present does not mean that at this place is none allowed. It is assumed that the reader will find the places where optional spaces are valid either by "doing" or by reading the examples.

Copyright 2000-2001 © Steffen Kaiser - current maintainer of FreeCOM