News
Changes (September 30, 1992)
* Changed the PackageIt.cm script to allow the second argument to contain spaces and special characters, provided it is appropriately quoted.
Example:
% PackageIt Kilroy "echo \"Kilroy was here\" >/tmp/xx; date >>/tmp/xx"
Changes (July 23, 1992)
* The read-eval-print loop has been made more robust concerning IO errors on the commander's streams. This makes it OK, for instance, to destroy a CommanderViewer that is still initializing - previously, this would lead to an uncaught error.
Changes (July 21, 1992)
* New commands IfProcExported and IfProcNotExported.
Bug fix (July 14, 1992)
* Parameter substitution for the alias command had a bug, which has been fixed.
Changes (June 23, 1992)
* The initial commander has had, for a while now, an heretofore-undocumented feature whereby the presence of a non-empty value for the environment variable COMMANDER←INITIAL←PERSIST will prevent the world from exiting when end-of-file is encountered on the standard input. The change is to not print the "Exiting ..." message in this case. The farewell message was also changed to be "Exiting Initial Commander".
Changes (April 15, 1992)
* When the Run command is used with the -a switch (which means run again even if already run), the "Re-export" messages are no longer printed.
* New "Prop" command - allows property values to be fetched with default values and control over quoting.
* Substitution now applies to redirection targets as well as to other parts of the command line. For example, the command "Echo Hello >$outfile" is a useful thing to say.
Changes (April 10, 1992)
* Added PrintFileProperties and SetFileProperties commands; changed PackageIt.cm to use SetFileProperties (instead of chmod).
Changes (March 19, 1992)
* The Version command now prints just the version number without extra text around it; the default is to print major and minor version numbers; an integer argument may be used to specify how many components are desired.
Changes (February 13, 1992)
* Changed the LoadedFiles command to rely on information recorded by the Run command; this should result in faster and more reliable PackageIt behavior.
Changes (January 24, 1992)
* Alias parsing of tokens is now more consistent with other token parsing in the commander.
Changes (September 13, 1991)
* CommanderOnStandardStreamsImpl registers interest in UnixTM SIGINT signal, with the result that CTRL-C typed in the standard streams commander produces an ABORT signal in that process.
Changes (March 15, 1991)
* New Packaging facility; from PackageIt.cm:
Example:
dyload a RawViewers world (e.g. CedarCommander RawViewers)
...
% cd bindir -- The place where you want the package to end up.
% PackageIt RV RawViewers
% sh1 ./RV.ld
( The RawViewers initial command does a few things (like CommandsFromProfile ...) that are not captured by the checkpointing process ).
This will create the UnixTM executable named bindir/RV
* New command (in support of PackageIt, but generally useful):
ReadTo ReadTo <string> - Copy stdin to stdout until a line with just <string> is encountered.
* Fixed this doc string:
PrefixLines PrefixLines <string> - prefix each line of stdin with <string>
* New options to LoadedFiles (again in support of PackageIt):
LoadedFiles Format load state for restart
Usage: LoadedFiles [-pcr | -command | -names | -ccode | -libs] [-first <pattern>] [-after <pattern>] [-before <pattern>] [-last <pattern>] [-except <pattern>]
Changes (November 5, 1990)
* The Files command won't descend into "hidden" directories unless asked.
* New
Dirs command:
Dirs List directories matching given pattern(s)
switches:
-a include files like .* and *~
-f full name always (otherwise strips working directory)
-r recursive - delve into subdirectories
-s slow - don't use heuristics to guess which might be subdirectories
Changes (October 18, 1990)
* The CD and Push commands now check for the existence of the directory.
* The CD and Push commands now allow star patterns (requiring a unique match).
* New CDH and PushH commands; are relative to the home directory.
* New CDF command; does not demand that the directory exists.
* The Type command now does star expansion.
* The Type command also has a synonym, namely Cat. (I've invoked the Catalog command more times than I like to think about).
* New
Files command:
Files List files matching given pattern(s)
switches:
-a include files like .* and *~
-f full name always (otherwise strips working directory)
-r recursive - delve into subdirectories
-s slow - don't use heuristics to guess which might be subdirectories
This is especially useful for dealing with commands that do not do star expansion, e.g.,
Bringover $(files /PCedar/Top/Imager*.df)
The recursive mode does not work quite as I would like it to; the pattern must match the subdirectories as well as the files. For instance "files /PCedar/*" works OK to list all the files in PCedar (it took about six munutes yesterday), but "files /PCedar/*.mesa" would not find all the mesa sources. I plan to fix this someday.
New Commands (April 16, 1990)
BackgroundPriority Execute rest of command line at background priority
ForegroundPriority Execute rest of command line at foreground priority
NormalPriority Execute rest of command line at normal priority
Changes (April 12, 1990)
* The Quit command is decomissioned (it tells you what to do instead).
* The Fail command now returns its argument as the message.
* New command ERROR (raises an unnamed ERROR).
Bug fixes (April 12, 1990)
* Printing of command messages has been reorganized; messages should no longer ever drop into the bit bucket.
Changes (March 27, 1990)
* New commands: IfInstalled, IfNotInstalled, WhenInstalled
* Some minor bugs fixed.
* Rearranged history logic so Redo command can be fixed to do the right thing.
Bug fixes: (March 13, 1990)
* ambiguous commands now fail properly in the PreRegister step
* HistoryLog, Statistics, Terse, and Verbose commands now set the control bits in the proper commander instances (in particular, you can now use these in the initialization entries in your profile, and have them take effect).
Other changes: (March 13, 1990)
* Initial value of keepHistory changed to TRUE.
* Input stream is now Reset on abort.
Changes (February 12, 1990)
* Interface changes to CommanderBackdoor.
* New commands: Statistics, HistoryLog.
* STOP! made more robust.
* New (private) CommanderSys interface to isolate PCedar/DCedar differences.
The UnixTM environment variable COMMANDER←INITIAL𡤌OMMAND is used to pass the initial command to CommanderOnStandardStreamsImpl.
(February 1, 1990)
Command tokens may be quoted with balanced parens, in places where double quotes were allowed (double quotes are OK, too). Shades of JaM!
(February 1, 1990)
$foo substitution now also gets UnixTM environment variables.
(February 1, 1990)
Some new commands:
Command do command-line as a command
Commander Make a nested commander
CommanderViewer Create a new Commander Viewer (rest of command line is the initial command)
CommandsFromProfile Execute commands from a user profile entry
(February 1, 1990)
The Run command knows about the XR←run convention, for the sake of c programs.
(January 30, 1990)
Switched to ".command" and ".require" files (see details below) (January 24, 1990)
The Commander implementation now puts /PCedar/Commands/ in the search rules; it is recommended that DF files in the release SModel the .command and .cm files directly into [PCedar2.0]<Commands>, and that the load files use the From command to indicate installation directories; thus you won't need to Bringover packages to use them. (January 24, 1990)
PseudoCheckpoint now sets execute permission on the rollback script, and also captures prefix map state. (January 24, 1990)
CD with no arguments now gets you into your UnixTM home directory. (This may change, subject to expressed opinions). (January 12, 1990)
Arguments for command files now work, and the $CommandFileDirectory property is set.
(January 12, 1990)
The "From" command no longer requires a terminating slash on the directory argument; also, relative directories are now OK. (January 12, 1990)
Command abbreviation implementation is improved. (January 12, 1990)
MkDir and RmDir commands are now provided. (January 9, 1990)
A new command, LoadedFiles, is provided to reformat load-state infromation in various useful ways. This is used in a command file, PseudoCheckpoint.cm, to provide a means of capturing a version-bound description of a running world. (January 9, 1990)
The section on "Installation" was added to the end of this document. (January 9, 1990)
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 Commander, 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 Commander recognizes that are not in the Commander registry. The Commander 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 Commander encounters a name, say Mumble, that is not in the registry, it first tries to locate a ".load" file named Mumble.load, or a command file named Mumble.cm.. If this finds Mumble.load, then the Commander assumes that you have typed the name of a command that is not yet loaded. The Commander will first load the necessary software into Cedar (by executing Mumble.load as a command file) and then call the CommandProc. During the execution of Mumble.load, the working directory will be initialized to the one where Mumble.load was found. If a .load file cannot be found, then the Commander 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 Commander, 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 Commander 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.)
Command lookup
When a command name is presented to the Commander 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. Commands are registered in a flat name space (unlike the Cedar7.0 and earlier CommandTool).
B. Search for load files (*.load) or command files (*.cm) in search rule order. So if the search rules are (///2.0/Commands/ ///2.0/System/), then ///2.0/Commands/Sample.cm will be found before ///2.0/System/Sample.load, but ///2.0/Commands/Sample.load will be found before ///2.0/Commands/Sample.cm. The current working directory is alway implicitly at the front of the search rules.
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 (per search rule element) in the accumulated names. For this pass, the case of the names is ignored, even if the underlying file system has case-sensitive names.
A. Search the registered commands in search rule order.
B. Search for load files (*.load) or command files (*.cm) in search rule order.
If there is no exact or unambiguous match, then the ambiguity will be indicated. For example:
% a
a ambiguous: Abort AddSearchRules Alias Aliases
PreRegister a failed to register command
%
If there is an unexact, unambiguous match, then the "PreRegister" command provides the full name as its result . For example (with command trace enabled):
% pw
*** PreRegister pw
*** pw
*** PWD
/usr/Build/
% ? pw*
*** ? pw*
PWD Print Working Directory
%
Recommended command line syntax
Most commands take a sequence of swtches and file (or directory) specifications, parsed from left to right. A switch starts with a '- character, and typically is a one character specification of some option. Documentation provided with the command should give a summary of what the switches do. For example, the documentation for the
SModel command is:
SModel dfFile*
Stores files under control of the given DF files.
-c check remote {default}
-n don't store
-t touchy (warnings cause failure)
-u reset switches to default values
To execute the
SModel command on two DF files, using the -n switch for the second, the command might look like:
SModel file1 -n file2
The switches should usually be sticky, in that once a switch is set it remains set that way for the remainder of the files in that execution of the command, although the defaults are used for the next execution of the command.
The '~ character is recommended as a means of inverting the sense of a switch. For example, to execute the
SModel command on two DF files, using the -n switch for the first but not the second, the command might look like:
SModel -n file1 -~n file2
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 Commander, 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
December 18, 1989 12:27:51 pm PST
%
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 Commander has a notion that a command either succeeds or fails. A CommandProc that wishes to notify the Commander 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 its arguments and returns the failure value. Incidently, Fail was implemented mostly to test the Commander! It doesn't have a secret use (but if we told you, it wouldn't be a secret, would it?).
% Date; Fail This Command Always Fails; Date
April 12, 1990 12:54:45 pm PDT
This Command Always Fails
Skipped: Date
Notice that the second Date command was not run. The message "Skipped: Date" was printed by the Commander.
Comments and uninterpreted commands
Some commands don't do anything. "-" and "--" are useful for commenting the Commander 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 Commander is not very smart about picking the command name out from the crowd! To be safe, include a space after the name of a command.
% --hello
[[--hello . . . not found]]
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 Commander. For example, the Commander places special interpretation on the semicolon and on the token ">". There is a way to mark certain commands as uninterpreted. In this case, the Commander 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.
Commands that 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
%
Properties
The Commander maintains a
property list. This list is used by the implementation to store things like the Commander 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 Commander 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 Commander 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 Commander.
% Echo $Junk
Stuff
%
Quoting
A ROPE literal is interpreted according to the standard Cedar rules. For example:
% Echo a b
a b
% Echo "a b"
a b
% Echo "a \"b"
a "b
% Echo "a ""b"
a "b
% Echo "a \nb"
a
b
% Echo "a > b"
a > b
Command files
Simple command files
A command file is a text file containing commands. To run a command file, either:
1. Use the Source command, or
2. If the file's extension is ".cm", use the short name of the file.
Suppose that the command file test.cm contains "Date{CR}Version{CR}". Then:
% Source 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 Commander. When Cmd has no arguments, it creates a new Commander window. When Cmd has an argument, it is interpreted as the name of a command file. A new instance of the Commander is created, but it runs in the same window as the old Commander.
TouchyCmd is like Cmd, except that if any of the commands in the command file fails, the execution of the command file is aborted.
When the Commander 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
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.
Nested command files
Of course, command files will nest. Be cautious of infinite recursion, though; something may break in a nasty way.
Installation
This is based a message I sent out to PCedarUsers; it needs to be updated and reworded to sound less tenative.
Subject: Upcoming Commander changes.
To: PCedarUsers^
cc: Michael Plass
Reply-To: Michael Plass
This message is to give everyone fair warning of some upcoming changes in the PCedar commander that affect the way commands get registered, and the way progams are installed.
Yesterday after the PFUDGE meeting, a group of us gathered to decide a few details. This is what we came up with:
1. New names for .load and .install files:
To prevent confusion about partially-ported packages, and to ease source-sharing, we will change some file extensions:
.load --> .command
.install --> .require
2. New generic top-level name:
What I was calling /release will be called /PCedar
3. The Require command:
It is desireable to use the simplest collection of commands that we can get by with in .command and .require files; we would like to think of these as being written in a little language with well-defined semantics, so we can easily write programs for checking consistency. To this end, these files should ordinarily contain lines in one of these forms (here the <...> brackets are meta-symbols)
Require <world> <component> <resource>
<world> denotes what major collection of software we are talking about, i.e., PCedar, PCedarChest, DATools, etc. Typically, these will be generic names that get translated by the prefix map into the "current" place.
<component> designates the component, e.g., Imager, Tioga, etc.
<resource> names the resource that is needed from the component.
The initial implementation of this will CD to /<world>/<component>/, execute <resource>.require, record <resource> as supplied (provided no failure has occured), and restore the working directory; if <resource> was already supplied, the Require is a NOP.
Run <shortname>
Runs the named executable in the current working directory.
4. Other name changes:
I decided to leave the "Install" and "Installed" command names alone. "Install" does use the ".require" extension. (Under normal conditions, these commands will not be used directly, so names don't matter too much.)
5. From command:
will still be available, as a generally-useful command.
6. PreRegister
The PreLoad command will be renamed to PreRegister.
7. Synonym
This seems like a good time to change the name of the "Rose" command to the harder-to-type-but-easier-to-guess name of "Synonym"
8. Search rules
I would like to change things so that the CWD is not always searched first for the ".command" files; more often than not, I have found this to cause trouble. Opinions? Being able to place a late-bound "." in the search rules seems like a better idea, and is more consistent with Unix.
9. An example (assume Ó on all of these, please):
-- /PCedar2.0/BigCardinals/BigCardinals.require
Run BigCardinalsImpl
-- /PCedar2.0/Commands/Scheme.command
Require PCedar Scheme Scheme
-- /PCedar2.0/Scheme/Scheme.require
Require PCedar BigCardinals BigCardinals
Run SchemeSysPFSImpl
Run SchemePackage
-- Scheme-Source.df
...
Directory [PCedar2.0]<Commands>
Scheme.command
Directory [PCedar2.0]<Scheme>
Scheme.require
...
Michael.
On stable snapshots
Providing a stable snapshot of the world is something that I think is best done by means of a new PFS view (not yet implemented). The idea would be to have a program (akin to the version map builder) that would construct a file snapshoting the version numbers of the world by traversing the DF files, so that
pma /pcedar -stable:/net/palain/plass/PCedar2.0-89-Dec-19/STABLE
would use the contents of the file /net/palain/plass/PCedar2.0-89-Dec-19 to filter the view of the world. (Don't take the example too literally, this is by way of illustration.)
Portions of the world could be unfrozen by using longer paths. For example, if I want to run off the latest RawViewers and Imager, I might say:
pma /pcedar/imager -vux:/pseudo/pcedar2.0/imager
pma /pcedar/imagercolordisplay -vux:/pseudo/pcedar2.0/imagercolordisplay
pma /pcedar/rawviewers -vux:/pseudo/pcedar2.0/rawviewers
In short, prefix maps seem to be a wonderful abstraction for providing that extra level of indirection in just the right place.
More on stable snapshots
The PseudoCheckpoint command is an attempt to provide another way of making a stable world. It writes a .pcr and a .cm to restore the most interesting bits of state, and a "rollback" unixcommand to kick things off. Refer to /PCedar2.0/Commands/PseudoCheckpoint.cm to get an idea of how it happens, and what the limitations are.
Your comments are welcome.
Michael.