Command Tool Guide To Cedar Folk Date December 16, 1983 9:20 pm From Stewart.pa Location PARC Subject Cedar CommandTool Organization CSL XEROX Release as /Indigo/Cedar/Documentation/CommandToolDoc.tioga Came from /Indigo/PreCedar/Documentation/CommandToolDoc.tioga Last edited by Stewart.pa, December 16, 1983 9:19 pm Abstract This document is a user's guide for the CommandTool in Cedar 5. Introduction General The Cedar 5 CommandTool is a stream-oriented "glass teletype" command-line processor. It is much like the Unix (tm) shell, or the Alto executive, or the Tajo Executive, etc. Basically it is a place to invoke Cedar subsystems. Getting started A new Cedar 5 world includes a gray screen with a few icons at the bottom and a few buttons in the upper right corner of the display. One of those buttons is labelled "Cmd". You can create a new top-level CommandTool at any time by clicking the Cmd button with any mouse button. Whenever you boot Cedar 5, a CommandTool is automatically created. The CommandTool viewer appears with the herald "Commander: WD = ///" The string 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, as well as other factors. Someday this will all be consistant. There is a facility for adding more buttons of your own. Other documentation Documentation for individual commands is at present contained in files on the directory /Indigo/Cedar/Documentation/. Each command has its own file; the command Mumble typically has a documentation file named MumbleDoc.tioga. Detailed documentation for the CommandTool itself is /Indigo/Cedar/Documentation/CommandToolStructureDoc.tioga. It includes a lot of information about the implementation of the CommandTool. As such, it will probably not be interesting to users, but instead will be a guide for those interested in implementing their own commands or in customizing the CommandTool itself. Other documentation for the CommandTool may be found in this document, and in the command documentation files /Indigo/Cedar/Documentation/CommandDoc.tioga and SourceDoc.tioga. Facilities overview In general, the CommandTool interprets each line of input as a separate command. The first thing 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. The previous paragraph is not entirely true, as it is possible to type several commands on the same command 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 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. The CommandTool provides for: Initialization of itself The first instance of the CommandTool executes commands from the user profile entry CommandTool.BootCommands before becoming interactive. This will be done only when Cedar is Booted. CommandTool.BootCommands: "Date\n" All instances of the CommandTool which own viewers (including the first one) execute commands from the user profile entry CommandTool.EachCommandToolCommands. This will be done whenever the "Cmd" button is clicked. CommandTool.EachCommandToolCommands: "CreateButton Open Open $FileNameSelection$\nAddSearchRule ///\nStatistics\n" See the individual command documentation to decipher this. @ 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 names 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, see CommandToolDoc.tioga or SourceDoc.tioga. 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 CommandProc (which are the things that implement the commands) must decide for itself to expand *'s and call CommandTool.StarExpansion. 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. Command Environment The CommandTool makes an attempt to set up interesting execution environments for commands. This area is still in flux. One of the most interesting properties the CommandTool can set is the Working Directory. The CommandTool provides a STOP! button, which can halt many commands in their tracks. The effectiveness of this facility should improve. Someday these facilities will be rationalized by the arrival of Activities. Command lookup The CommandTool has a fairly elaborate and formal procedure for finding a CommandProc to execute in response to a user's command line. The procedures can be changed, but the default collection: Uses search rules to find a CommandProc already present in the Commander registry. Automatically sets up programs which are not yet loaded (via .load files). Automatically locates and invokes command files. Command model What is a command? In an informal sense, a Cedar CommandTool command is anything you can get to happen by typing something to the CommandTool, but there is a much stricter definition: a command is represented by the execution of a Cedar procedure of type Commander.CommandProc. There is a directory of commands, called the Commander registry, in Cedar. It 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. It turns out that you can also type the names of things 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. It 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. A command, then, is either a name that matches a CommandProc that Cedar already knows about, a name that matches a CommandProc that exists but is not yet loaded into Cedar, 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 5 file system is called FS. FS provides a hierarchical directory system. 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 accross a FORK without special attention, so be a little cautious.) Other properties are available to a CommandProc when it runs. These are discussed in more detail in CommandToolStructureDoc, but in general, they provide handles through which a CommandProc can gain access to, for example, the CommandTool which invoked it withough much work. CommandProcs can also change properties or add new ones, this allows a command to alter the behavior of the CommandTool and provides a hook for the customization of the CommandTool. Command examples The commands in the following examples may be found in the various documentation files for individual commands. Commands which produce output Date is an example of the simplest type of command. The date command merely prints the date and time on its standard output stream and returns. Commands like PrintWorkingDirectory and List are similar; they obtain information from elsewhere inside Cedar and print it out, generally on the standard output. Commands which alter state Copy is an example of another type of command. Copy accepts instructions (e.g. the names of files) and performs some operation on the state of Cedar. Delete and Statistics are other examples. Commands which do useful work Compile and Bind are commands which do a substantial amount of work before returning. Commands which invoke other systems DFTool and Open are commands which start substantial Cedar subsystems, but which themselves return fairly quickly. One might argue that Open merely opens a viewer, but that viewer brings with it the entire Tioga editor. . . Commands which manipulate other commands Time is an example of a command which takes another command as an argument. How to use the CommandTool Getting Help Help for individual commands is best found in the individual commands on the release documentation directory. Someday this may be automatic. One idea is to create a command file like so: -- GetHelp.cm Open /Indigo/Cedar/Documentation/$1$Doc.tioga This causes the command GetHelp Mumble to open a viewer on /Indigo/Cedar/Documentation/Mumble.tioga. How to initialize your CommandTool As mentioned above, each instance of the CommandTool initializes itself by reading commands from special entries in User.profile (or YourName.profile). The very first CommandTool, that runs when Cedar is booted, reads commands from the CommandTool.BootCommands entry. This facility is equivalent to the UserExec's InitialCommands entry, if you remember that. Proper use for the BootCommands command line is to execute commands that should only be executed when cedar is booted or which really oughtn't be executed several times. One good example is Alias. Alias registers short names for complicated commands (see AliasDoc.tioga). Alias makes entries in the global command registry so there is no need to make them for each CommandTool. Every top-level CommandTool (those that have viewers) reads commands from the CommandTool.EchCommandToolCommands entry. This facility is intended for commands that customize each instance of the CommandTool. A good example is CreateButton, see (CreateButtonDoc.tioga). Since the CommandTool menu buttons are private to a particular instance of the CommandTool, new CommandTools which get created won't have the buttons. However, you can use the user profile entry to create buttons on each CommandTool. 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. Nearly always this will get control back 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. As we find out which commands cannot be stopped, we can fix them. For wizards and 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. How to survive with directories in Cedar 5 FS, the Cedar 5 file system, allows multiple directories on the local disk. The CommandTool has several facilities which allow interesing use of directories. Read Cedar5LocalDirectories.tioga for the religion. 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 aquires 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 workinf 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. See the various documentation files. When looking for a command, the CommandTool first looks in the working directory, then in each directory on the search rules. 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. If you don't like something The CommandTool is an open program. Nearly all of its facilities can be customized. Here are some examples: Command lookup is done by calling CommandProcs which are found on a list. The list can be altered. Command spelling correction could be implemented this way. The CommandTool prompt is a property and can be changed whenever you like. The statistics command works by registering CommandProcs to be called before and after the execution of each command. The same facility could be used to implement numbered prompts, history, redo, etc. Etc. If you are interested in changing something more to your liking, read CommandToolStructureDoc.tioga, talk to the implementor, and look at the code. 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 % The standard output from date has been directed into the file "date.txt." 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 % 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 Saturday, November 26, 1983 3:47 pm Saturday, November 26, 1983 3:47 pm Saturday, November 26, 1983 3:47 pm % 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 Saturday, November 26, 1983 3:59 pm 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 Saturday, November 26, 1983 3:45 pm % 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 " Hello SetProperty $Prompt "%% " % The prompt is normally set to "%% ". 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. 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]] Saturday, November 26, 1983 4:50 pm [[ ///Commands/version]] Cedar 5.0.101 of November 23, 1983 5:20 pm % 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!4 []<>Chat0.log!1 []<>Compiler.log!12 % 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!4 []<>Chat0.log!1 []<>Compiler.log!12 % 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 This means that you might use an @ file to avoid typing a long string. Suppose that Ivy.cm contains the string "/Ivy/Stewart/Temp/". Then: % List @Ivy@a* [[ ///Commands/List /Ivy/Stewart/Temp/a*]] [Ivy]temp>accent.bcd!2 [Ivy]temp>accent.c!1 % @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 possible to tell 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. Suppuse a.cm contains: -- this is the beginning of a.cm b.cm -- this is the end of a.cm Suppuse b.cm contains: -- this is the beginning of b.cm c.cm -- this is the end of b.cm Suppuse 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. 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. 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[SP] will be replaced by the contents of file followed by SP. @file[CR] will be replaced by the contents of file followed by CR. @file@ will be replaced by the contents of file 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*"] At this writing (November 4, 1983), 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 (create) >> file appends the standard output of a command to file < file sets the standard input of a command to read from file These redirection directives must appear as separate tokens, the ">" 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: ;, CR, |, & (These are not activation characters in the ReadEvalPrint sense!) ; 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 CR 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 CR is found. If a Commander.CommandProc returns the atom $Failure, it is deemed to have failed. CR 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. Standards for command authors File names use / syntax. Standard switch characters are - and + Neither of these matters is of especial interest to the command processor, but we should encourage some degree of uniformity among applications.