CommandToolDoc.Tioga
Copyright © 1985 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) May 28, 1985 1:05:55 pm PDT
THE CEDAR COMMANDTOOL
THE CEDAR COMMANDTOOL
CEDAR 6.0 — FOR INTERNAL XEROX USE ONLY
CEDAR 6.0 — FOR INTERNAL XEROX USE ONLY
Cedar CommandTool

© Copyright 1984, 1985 Xerox Corporation. All rights reserved.
Abstract: This document is a user's guide for the CommandTool in Cedar 6.0.
XEROX  Xerox Corporation
   Palo Alto Research Center
   3333 Coyote Hill Road
   Palo Alto, California 94304

For Internal Xerox Use Only
Introduction
General
The CommandTool is a stream-oriented command-line processor. It is much like the Unix (tm) shell, or the Alto executive, or the Tajo Executive, etc. It is a means for invoking registered commands with arguments.
Getting started
The CommandTool viewer appears with the herald "Commander: WD = ..." The characters after the equals sign is the current working directory of that command tool, much more will be said about this later. The CommandTool will have printed a prompt (initially "% ") and will be waiting for input.
The menu of a CommandTool initially has three buttons, STOP!, Find, and Split. Find, and Split work the same way that the other Find, and Split buttons in Cedar work. The STOP! button attemps to stop whatever is the current command running in the CommandTool viewer. It does this by raising the signal ABORTED in the CommandTool process. Usually this will result in the string " -- Aborted" being printed along with a new CommandTool prompt, but the details depend on the particular command.
Command documentation
Documentation for individual commands is in the file
/Cedar/Cedar6.0/Documentation/CommandToolCommands.tioga
Facilities overview
In general, the CommandTool interprets each "line" of input as a separate command. The first token on the command line is taken to be the name of a command previously registered with Cedar. The rest of the command line is taken to be arguments to that command or directives to the CommandTool.
It is possible to type several logical command lines on the same input line and it is possbile for the first thing on the command line to be the name of a command file, rather than itself be a registered command.
The rest of this section contains a brief list of the facilities provided by the CommandTool. Each facility will be described in more detail later.
User profile entries
The CommandTool code executes the following user profile entries as commands in response to certain events, such as booting, rollback, or credentials changes.
CommandTool.BootCommands
is interpreted as commands when the first CommandTool instance is created, which occurs during a full boot sequence. This entry can be used to acquire and run personalized files for a machine prior to taking a checkpoint. This entry can also be executed by the command ///Commands/NoteBootCommands command.
CommandTool.NewUser
is interpreted as commands in one existing command tool whenever there is a new user at (1) credentials change, (2) rollback, or (3) return from idle. If there are no existing CommandTool instances then there is no effect. This entry can also be executed by the command ///Commands/NoteNewUser.
CommandTool.PerLogin
is interpreted in every existing command tool as commands whenever there is a new user at (1) credentials change, (2) rollback, or (3) return from idle. It is recommended that these commands be idempotent, so that multiple executions have the same effect as a single execution. This entry can also be executed by the command ///Commands/NotePerLogin.
CommandTool.PerCommandTool
will be interpreted as commands at the start of every new CommandTool instance that executes from a viewer (with the exception of the very first CommandTool instance created during a full boot). This entry can be used to set up standard buttons, set the default working directory, and so forth. For compatibility, a synonym for this entry is CommandTool.EachCommandToolCommands. This entry can also be executed by the command ///Commands/NotePerCommandTool.
See the release file User.profile for examples.
@ files
A command line may contain "@filename". The CommandTool expands the given file in place as a macro expansion. @ files are different than command files, but often they will be equivalent. @ files cannot have arguments. @ files do not have to include any carriage returns, so they can be used as part of a single command.
Command Files
Command files are executed by creating a new, nested, instance of the CommandTool which reads from the given file rather than from the keyboard. Generally command files are files named Mumble.cm and they may be executed by just typing "Mumble" on the command line or by typing "Source Mumble", or "CommandTool Mumble." Command files can have arguments, as described later.
IO redirection and pipes
Commands are given a standard input stream and a standard output stream for their use. Normally, these streams are attached to the CommandTool viewer, but they may be redirected to read from or write to files. For example, the command line Date > date.txt will put the date and time into the file date.txt.
It is possible to "pipe" the output of one command into the input of another by use of the syntax commandA | commandB. For example, the command line Date | Indent 10 will print the date and time in the CommandTool viewer indented by 10 spaces.
Star expansion
A command line may include file system pattern matches such as *.mesa. The CommandTool provides facilities for expanding these patterns. At present, each command procedure optionally performs star expansion via calls to the CommandTool interface (such as CommandTool.Parse). Not all commands perform star expansion.
Related commands
There can be multiple commands on the same command line, separated by ';. If one of the earlier commands "Fails" (see below), later commands are not executed. An example multiple command is:
Date; Version
which prints out something like:
Monday, April 22, 1985 6:09 pm PST
Cedar 6.0 of April 4, 1985 11:46:16 am PST
Command Environment
The CommandTool makes an attempt to set up interesting execution environments for commands. One of the most interesting properties the CommandTool can set is $WorkingDirectory, which governs the directory in which to lookup short file names.
Command lookup
When a command name is presented to the CommandTool it can denote quite a range of possible actual commands. Searching is affected by the search rules (see the documentation for the AddSearchRules, SetSearchRules and PrintSearchRules commands), the command registration, and the exactness of the match. The intention is to find the "closest" command first, where a more exact match is closer than a less exact match, and a match earlier in the search order is closer than a match later in the search order. A command is searched for according to the following rules:
1. The first exact match found will be used.
A. Search the registered commands in search rule order. So if the search rules are (///Cedar6.0/ ///Commands/), then ///Cedar6.0/Sample will be found before ///Commands/Sample.
B. Search for load files (*.load) in search rule order. So if the search rules are (///Cedar6.0/ ///Commands/), then ///Cedar6.0/Sample.load will be found before ///Commands/Sample.load.
C. Search for command files (*.cm) in search rule order.
2. If there is no exact match, then we search for an match using the given name as a prefix. All prefixes are accumulated before execution, and the command will only be executed if there is a unique short name in the accumulated names.
A. Search the registered commands in search rule order.
B. Search for load files (*.load) in search rule order.
C. Search for command files (*.cm) in search rule order.
As an example, the rule about "unique short name" allows a unique match for "Samp" on "///Commands/Sample" and "///Cedar6.0/Sample.load". The first unique short name match is the one executed. There will not be a unique match if the names found are "///Commands/Sample" and "///Cedar6.0/SampleX.load".
To ensure that the current working directory is "closer" than other directories, if the current working directory is not in the search rules, then it will be added as the first search rule name for the duration of the search. If the current working directory is in the search rules, then no change will be made to the search rules.
If there is no exact or unambiguous match, then the ambiguity will be indicated. For example:
% lookup comp
{Ambiguous:
[]<>Cedar6.0>Compile.load!2
[]<>Cedar6.0>Compiler.load!2
[]<>Cedar6.0>ComplexCompile.load!2
}
What to do if it breaks
Most commands intended for use with the CommandTool catch signals that could reasonably be expected to arise. Those which don't will give rise to event windows. If you are not interested in the event, click the Abort button in the event window, which normally returns control to the CommandTool. If it does not, you can always close the CommandTool and Event viewers and create a new CommandTool with the Cmd button in the Cedar herald.
If a command runs away, try clicking the STOP! button in the CommandTool from which the command was started. This is not completely reliable because it uses Process.Abort to squelch the command. It is possible for a command to ignore this signal, although commands should check for this signal by periodically executing Process.CheckForAbort[]. As we find out which commands cannot be stopped, we can fix them.
For programmers: Process.Abort raises ABORTED in the command's process. This won't work if the command has FORKED, or if it never waits on a condition variable which has aborts enabled. A command can explicitly check for ABORTED by calling ProcessExtras.CheckForAbort and command writers are encouraged to do so frequently.
Command model
What is a command?
Simply speaking, a command is any action implemented by a procedure registered via Commander.Register. The command registry contains the mapping between the names of commands and the CommandProcs which do the work. For example, when you type "Date{CR}" to the CommandTool, the procedure "Date", of type Commander.CommandProc, in the module InitialCommandsImpl.mesa is called. This procedure obtains the current date from the BasicTime interface and prints it using the facilities of the IO package.
There are a few things that the CommandTool recognizes that are not in the Commander registry. The CommandTool provides two facilities that make life a bit easier. One is the ability to type a name which corresponds to some Commander.CommandProc that is not yet loaded into the running copy of Cedar. The other is the ability to type the name of a command file.
When the CommandTool encounters a name, say Mumble, that is not in the registry, it first tries to locate a ".load" file named Mumble.load. If this works, then the CommandTool assumes that you have typed the name of a command that is not yet loaded. The CommandTool will first load the necessary software into Cedar (by executing Mumble.load as a command file) and then call the CommandProc. If a .load file cannot be found, then the CommandTool will try to locate a command file named Mumble or Mumble.cm. Each command in the command file will be run. More exact rules are given later in this document.
Therefore, as recognized by the CommandTool, a command is either a registered procedure, a "load" file that will register a procedure, or the name of a command file which contains other commands.
Command view of the world
When a CommandProc runs (usually as a consequence of a typed command), it receives an environment in which to run. The CommandProc is free to change or ignore this environment, but most do not.
The key elements of this environment are the standard input and output streams, the working directory, and other properties.
The standard input stream is usually connected to the keyboard, but may sometimes read from a file. The standard output stream is usually connected to the display, but may sometimes print to a file. (The CommandTool can even connect the output of one command to the input of another. This is called a pipe.)
The Cedar file system is called FS. FS provides a hierarchical directory system, as well as caching for remote files. As in other systems of this type, the full path name of a file can become quite long. The working directory facility provides a way for users to most of the time use short file names without losing the advantages of the hierarchical directory system. Most programs need not even be aware of the working directory, as it does not need to be explicitly mentioned. (However, the working directory will not propagate across a FORK without special attention, so be a little cautious.)
How to survive with directories in Cedar
FS, the Cedar file system, allows multiple directories on the local disk. The CommandTool has several facilities which allow interesting use of directories.
Working directory
Each CommandTool maintains a working directory, which is shown in the herald of the CommandTool viewer. The working directory is changed by the command ChangeWorkingDirectory, (for which a nickname, CD, is registered). Read the ChangeWorkingDirectoryDoc.tioga file for more information.
Every command run from a CommandTool acquires the working directory. Generally, anytime one of the commands uses FS and passes a shortName (a file name with no directory specification), FS will look for the file in the working directory.
The theology of working directories is in its formative stages, but briefly, they allow you to keep your mental working set smaller, help to avoid name conflicts, and permit you to cleanly switch from one activity to another -- by working on each activity in its own directory.
The CommandTool allows you to set the working directory to a remote directory, and that is useful for browsing, but remember that FS will not create remote files.
CreateButton Open Open $FileNameSelection$ is a very handy command. It puts up an open button that uses the working directory of the CommandTool in whose herald it is.
Search Rules
Each CommandTool maintains a list of directories in which to look for commands whose names you type. Even the in-memory Commander registry of command proceedures is organized into directories. Its structure generally parallels that of the file system.
The search rules can be printed by PrintSearchRules and altered by SetSearchRules and AddSearchRule.
Debugger Search Rules
This is not strictly a CommandTool issue, but this is a logical spot for it. The Cedar runtime machinery, specifically AMFiles, keeps a list of directories in which to search for symbol tables (and in the case of the debugger, for source files.) Most such files will be accessible through the version map machinery, but for development software they will not.
The debugger search rules can be printed by PrintDebugSearchRules and altered by SetDebugSearchRules and AddDebugSearchRule. See the various documentation files. In addition, when a module or configuration is loaded into Cedar by the Run command (really by the procedure CommandTool.Run), the directory in which the .bcd was found is added to the debugger search rules. Therefore, most of the time you don't have to think about it.
Examples
Sit down in front of a Cedar workstation and follow along. Try variations as they occur to you. First click the "Cmd" button in the upper right to get a CommandTool, if there isn't one already.
Simple commands and output redirection
The date command prints the date and time on the standard output. The Open command creates a viewer on a given file. The Version command prints the version number of the running Cedar on the standard output.
Type Date:
% Date
Saturday, November 26, 1983 3:40 pm
Now try redirecting the ouput of the date command:
% Date > date.txt
where blanks are required both before and after ">".
The standard output from date has been directed into the file "date.txt" whose previous contents, if any, are destroyed. Take a look in date.txt:
% Open date.txt
Destroy the date.txt window. Incidently, output from a command can also be appended to a file:
% Version >> date.txt
% Open date.txt
where blanks are required both before and after ">>".
Semicolon: running multiple commands on a line
It is possible to run several commands on the same command line by separating them with semicolons:
% Date;Date;Date
Monday, April 22, 1985 6:48 pm PST
Monday, April 22, 1985 6:48 pm PST
Monday, April 22, 1985 6:48 pm PST
Semicolon has another effect. The CommandTool has a notion that a command either succeeds or fails. A CommandProc that wishes to notify the CommandTool of failure returns a special value. Suppose that several commands are on the same command line separated by semicolons. If one of them "fails," later commands will not be run. There is a special command, called "Fail" that prints the string "This Command Always Fails" and returns the failure value. Incidently, Fail was implemented mostly to test the CommandTool! It doesn't have a secret use.
% Date; Fail; Date
Monday, April 22, 1985 6:48 pm PST
This Command Always Fails
[[Command failed]]
Notice that the second Date command was not run. The message "[[Command failed]]" was printed by the CommandTool.
Comments and uninterpreted commands
Some commands don't do anything. "-" and "--" are useful for commenting the CommandTool typescript and for putting comment lines in command files:
% -- now try the date command
% Date
Monday, April 22, 1985 6:48 pm PST
But remember that the CommandTool is not very smart about picking the command name out from the crowd! Be sure to include a space after the name of a command.
% --hello
[[--hello . . . not found]]
In general, the CommandTool will surround anything it prints with double square brackets.
Normally, commands are interpreted. This means that the syntax of their command lines cannot conflict with the special command line syntax which is interpreted by the CommandTool. For example, the CommandTool places special interpretation on the semicolon and on the token ">". There is a way to mark certain commands as uninterpreted. In this case, the CommandTool does no command line interpretation, but passes everything up to the next carriage return to the command.
- and -- are uninterpreted commands. They are set up so that their command lines can include anything, including special characters like '; and '> without any effect.
% -- date ; date
Notice that the -- command extends to the end of line, not just up to the semicolon.
Let's use the "eval" command to illustrate this point. Normally, eval is uninterpreted:
% eval 3 > 4
FALSE
The special command ShiftInterp takes a command as its argument and executes it as though it were an interpreted command, even though it may not be:
% ShiftInterp eval 3 > 4
The output of "eval 3" has been redirected into the file "4". Look and see!
Commands which take commands as arguments
Some commands take commands as their arguments:
% Time Date
Saturday, November 26, 1983 3:45 pm
Running time: 00:00:00.070624
%
Look at the implementation of Time if you want to do something similar.
Filters, Pipes, and input redirection
A filter is a command which reads from the standard input and writes to the standard output. Indent is a filter. It reads each "line" (determined by carriage return) from the standard input, indents it by a certain number of spaces, and prints it to the standard output.
Remember that normally, the standard input comes from the keyboard. Start Indent and type for a while. Type DEL to stop it (indicated by {DEL} below). User typein is italicized:
% Indent 10
Now is the time
Now is the time
for all good men
for all good men
to come to the aid of
to come to the aid of
their party.
their party.
{DEL}
%
The standard input can be redirected to come from a file:
% Date > temp.txt
% Indent 10 < temp.txt
Saturday, November 26, 1983 4:37 pm
%
The same effect can be achieved without the temporary file by connecting the ouput of Date directly to the input of Indent with a pipe. Pipes are constructed with the character '|:
% Date | Indent 10
Saturday, November 26, 1983 4:39 pm
%
Running commands in the background
Commands can be run in the background by terminating them with the character '&. When the CommandTool sees this character, the CommandProc is FORKed rather than just called, so that the execution of the command proceeds in parallel with further execution of the CommandTool. When this is done, a new viewer whose name is the name of the command is opened to hold the output from the command. In this case, the standard input to the command also comes from the new viewer.
% Date &
%
Destroy the new window when you are finished with it.
Properties
The CommandTool maintains a property list. This list is used by the implementation to store things like the CommandTool prompt string. The commands GetProperties and SetProperty can be used to examine and change properties:
% SetProperty $Prompt "Hello %l%%%l "
Hello %
The prompt is normally set to "%l%%%l ". The percent sign is doubled because the CommandTool uses IO.PutF to print the prompt and % is a special character to PutF and must be doubled to print correctly. The "double-quotes" are necessary so that the trailing space will be included in the value of $Prompt. The %l indicates where the bold (and normal) looks will be applied.
SetProperty only handles properties with ROPE values. The command GetProperties prints properties using PrintTV and will print any kind of property.
% SetProperty $Junk Stuff
% GetProp $Junk
commander properties:
$Junk = "Stuff"
%
The CommandTool provides a facility for command line access to the values of properties, using the special symbol '&. Only those properties with ROPE-valued values work this way. The command Echo is very handy for exploring this turf because all that it does is echo its own command line after processing by the CommandTool.
% Echo &Junk
Stuff
%
Notice that & followed by a token stands for value substitution while an & by itself means run the command in the background.
Star Expansion
The CommandTool will interpret command line arguments containing '* as file system patterns. These patterns are expanded automatically. (There is a way to turn this off for a particular command, which is used by commands that want to deal with patterns explicitly.)
At present, commands must call CommandTool.StarExpansion explicitly. This will change next time the Commander interface is recompiled.
% Echo B*.mesa
[]<>Booting.mesa!1 []<>BootTool.mesa!1
%
Macros: @ files
The CommandTool places special interpretation on the character '@ on command lines. The text immediately after the @, up to white space or to another @, is interpreted as the name of a file. The contents of that file replace the @filename on the command line just as though you had typed them.
Normally, a command line consists of a single line of text ending with a carriage return, but an @file may contain carriage returns. If it does, it is interpreted as a series of commands.
Suppose that the file test.cm contains the two lines "date" and "version".
% @test.cm
[[ ///Commands/date]]
Monday, April 22, 1985 6:52 pm PST
[[ ///Commands/version]]
Cedar 6.0 of April 4, 1985 11:46:16 am PST
The command tool has printed the actual commands that are being executed. It does this whenever @files are expanded.
One use for @files is to contain a list of filenames for use as arguments to a command. Suppose that test.cm contains "*.log" with no carriage return:
% List @test.cm@
[[ ///Commands/List *.log]]
Binder.Log!224 209 22-Apr-85 17:06:51 PST
Compiler.log!902 247 22-Apr-85 17:06:12 PST
If a file with the name after the @ cannot be found, the CommandTool tries again after appending ".cm" to the name.
% List @test
[[ ///Commands/List *.log]]
Binder.Log!224 209 22-Apr-85 17:06:51 PST
Compiler.log!902 247 22-Apr-85 17:06:12 PST
Here are the precise transformations made on the command line. If the contents of X.cm are "XXX" then:
"@X.cm{CR}" becomes "XXX{CR}" -- trailing carriage return is preserved
"@X.cm " becomes "XXX " -- trailing white space is preserved
"@X.cm@" becomes "XXX" -- trailing @ is deleted
@files will be expanded recursively, so that a.cm can contain @b.cm@ and so on. What happens if a.cm contains a line like @a.cm@? There are two cases.
If a.cm contains "Date{CR}@a.cm{CR}", then
% @a.cm
[[ ///Commands/date]]
Saturday, November 26, 1983 5:01 pm
[[ ///Commands/date]]
Saturday, November 26, 1983 5:01 pm
[[ ///Commands/date]]
. . .
until you hit the STOP! button.
If a.cm contains "Date @a.cm@" then:
% @a.cm
Exceeded limit on expansion of @ command files
Roughly speaking, the CommandTool has a test for an infinite @file loop that does not result in any commands being executed. More precisely, if a carriage return is encountered, then the expansion counter is reset. Otherwise the CommandTool gives up after twenty @ file expansions.
Command files
Simple command files
A command file is a text file containing commands. One way to run a command file is to type @commandfilename{CR}. There are three other ways, which behave somewhat differently and which offer some additional functionality.
Suppose that the command file test.cm contains "Date{CR}Version{CR}". Then:
% Cmd test
> Date
Saturday, November 26, 1983 5:13 pm
> Version
Cedar 5.0.101 of November 23, 1983 5:20 pm
The command Cmd creates a new CommandTool. When Cmd has no arguments, it creates a new CommandTool window. When Cmd has an argument, it is interpreted as the name of a command file. A new instance of the CommandTool is created, but it runs in the same window as the old CommandTool.
When the CommandTool encounters a command name, it tries to locate a command file of that name and then acts as though the user had typed "Cmd commandFileName":
% test
> Date
Saturday, November 26, 1983 5:15 pm
> Version
Cedar 5.0.101 of November 23, 1983 5:20 pm
Command file arguments
So far, command files are just like @ files. However, command files can themselves have arguments. First consider the command Echo. Echo merely prints its own arguments and returns:
% Echo a b c
a b c
Inside a command file, the special syntax $n, where n is an integer, refers to the nth argument to the command file. Suppose that the command file Test.cm now contains "Echo $1 $2 $3{CR}":
% test a b c
> Echo $1 $2 $3
a b c
The idea is that it should not be obvious when a command is implemented by a CommandProc and when it is implemented by a command file.
Source
Normally, when a new instance of the CommandTool is created, the property list of the old CommandTool is copied. Therefore changes made to the property list of one CommandTool are not visible from another CommandTool. Since command files are implemented by the creation of a new instance of the CommandTool, commands in a command file cannot affect the property list seem by anyone outisde the command file. Suppose that test.cm contains "SetProperty $Junk Good-bye{CR}GetProperties $Junk{CR}:
% SetProperty $Junk Hello
% GetProperties $Junk
commander properties:
$Junk = "Hello"
% test
> SetProperty $Junk Good-bye
> GetProperties $Junk
commander properties:
$Junk = "Good-bye"
% GetProperties $Junk
commander properties:
$Junk = "Hello"
As you can see, when the command file returns, the old value of $Junk has reappeared.
There is a way to get around this effect. The Source command runs a command file without copying the property list. Changes made to the property list by commands running in a "source" are persistant:
% SetProperty $Junk Hello
% GetProperties $Junk
commander properties:
$Junk = "Hello"
% Source test
> SetProperty $Junk Good-bye
> GetProperties $Junk
commander properties:
$Junk = "Good-bye"
% GetProperties $Junk
commander properties:
$Junk = "Good-bye"
Nested command files
Command files will nest. As you probably noticed, the CommandTool replaces the normal prompt with "> " when a command file is running. When a nested command file is running, the number of '>'s is increased.
Suppose a.cm contains:
-- this is the beginning of a.cm
b.cm
-- this is the end of a.cm
Suppose b.cm contains:
-- this is the beginning of b.cm
c.cm
-- this is the end of b.cm
Suppose c.cm contains:
-- this is the beginning of c.cm
Then:
% a.cm
> -- this is the beginning of a.cm
> b.cm
>> -- this is the beginning of b.cm
>> c.cm
>>> -- this is c.cm
>> -- this is the end of b.cm
> -- this is the end of a.cm
What happens if test.cm contains test.cm?
% test.cm
> test.cm
>> test.cm
>>> test.cm
>>>> test.cm
>>>>> test.cm
>>>>>> test.cm
>>>>>>> test.cm
>>>>>>>> test.cm
Until you click the STOP! button (or something else breaks).
Command line syntax
This section restates the command line syntax in a collected fashion.
The first token on the command line is interpreted as the name of the command. The first token is defined to be anything after the leading spaces and tabs are stripped away up to but not including the first character in the set {SP, TAB, CR, '|, '&, and ';}. The command is looked up in a database and found to be either "interpreted" or "uninterpreted."
The processing of the two types of commands are quite different from then on.
Uninterpreted Commands
The command line for an uninterpreted command extends from the character after the name up to (and includes) the first CR. The command tool makes no assumptions about the command line syntax of uninterpreted commands, except that the name of the command must be isolated by the same mechanism that finds the name of an interpreted command.
As a consequence of this strict view of "uninterpreted," uninterpreted commands cannot participate in many of the facilities provided by the command tool. For example, to be uninterpreted, a command must already be loaded.
Interpreted Commands
The command line of an interpreted command is a string of tokens, some of which are interpreted specially by the command tool. Some of the tokens may participate in substitutions. After substitutions, special tokens are interpreted directly by the command processor. Remaining tokens are passed to the command as arguments.
Quoting: \
\xxx, where xxx is exactly three octal digits IN [000..377], will be replaced by the character with that octal code.
\n, \r, \t will be replaced by CR, CR, and TAB, respectively.
These are the Cedar ROPE quoting conventions. The interpretation is made by Convert.RopeFromLiteral.
A string contained within " marks is considered to be a single token. A '" within a quoted string must be represented as "", so that a"b would be written "a""b".
Characters with special significance for the command processor must be quoted if a command is to receive them as part of its command line. (But see the section on Command parsing below.) There is no specification for how this is to be done yet.
Substitutions: @, &, $, *
@file@ will be replaced by the contents of file
@file (without a trailing @) will be replaced by the contents of file exactly.
If file does not exist, file.cm will be tried.
&name will be replaced by the value of the environment variable name. An environment variable is a name-value mapping maintained by the command processor and kept on a property list. Examples of environment variables are the current user and the working directory. Conversion to the atom which names the environment variable is made by the procedure Atom.MakeAtom[name]. The lookup will be made first on the Commander property list and then on the process properties list. If no value exists or the value found is not a Rope.ROPE, then an empty string is returned.
$n (n an integer), when it occurs in the text of a command file, will be replaced by the nth argument to the command file.
* has its usual meaning in the context of the file system.
*.mesa would expand to a list of all mesa files in the current working directory: a.mesa b.mesa c.mesa . . .
///stuff/a* would expand to a list of all files in the ///stuff/ directory whose names begin with a: ///stuff/acme.mesa ///stuff/azzz.txt . . .
In the context of star expansion, relative paths are interpreted before expansion:
"./a/b/c*" is converted to Concat[$WorkingDirectory, "a/b/c*"]
"../a/b/c*" is converted to Concat[parent-of-$WorkingDirectory, "a/b/c*"]
The default is to not do star expansion. Commands which might reasonably expect to be called with lists of files must call the star expansion facility themselves (See the section on the CommandTool interface.).
I/O Redirection: <, >, >>, |
> file directs the standard output of a command to file
>> file appends the standard output of a command to file
< file sets the standard input of a command to read from file
Note: ">" or ">>" or "<" must appear surrounded by whitespace.
commandA | commandB sets the standard output of commandA to connect to the standard input of commandB (pipe). CommandA will be started "in the background" as though it were started with &.
Spawning of separate activities: &
Command & starts command as a separate activity in its own window. (E. g. the command is FORKed). & must be the last token on the command line before the activating character. A command started with & gets a new viewer to run in. If a command has output redirected and is forked, then no separate window is created and input comes from IO.noInputStream unless otherwise redirected. (See the section below on IO streams)
Terminating characters: ;, \n, |, &
'; serves to separate multiple commands, with the additional semantics that if a command fails, succeeding commands will not be executed (quit-on-failure). When a command fails, the command processor reads until a '\n is encountered or until end of file on the input stream. In the stream sense, '; is not an activating character. Stream based editing may continue until '\n is found.
If a Commander.CommandProc returns the atom $Failure, it is deemed to have failed.
'\n separates commands. Each command is executed in turn without regard to the success or failure of previous commands.
'| and '& start commands in the background. If a command within a pipeline fails, subsequent commands receive EndOfFile on their inputs. (Earlier commands should be flushed, but at present, the CommandTool has no memory and spins off each command as it is encountered.)
Command files
The first token on the command line may be the name of a command file. A new instance of the command processor is started, with input stream connected to the command file, but output and error streams connected to the original viewer.