03/23/84  exec_com, ec

Syntax:  ec {-control_args} path {ec_args}


Syntax as an active function:  [ec {-control_args} path {ec_args}]


Function: executes programs written in the exec_com language, used to
pass command lines to the Multics command processor and pass input
lines to commands reading input. The syntax described here is known
as Version 2, for which the first line of the exec_com program must
be the line consisting of "&version 2". For a description of Version 1
syntax, type "help v1ec".


Arguments:
path
   is the pathname of an exec_com program, written using the constructs
   described in this info segment. The ec suffix is assumed if not
   specified. The star convention is NOT allowed.
ec_args
   are optional arguments to the exec_com program, and are substituted
   for parameter references such as &1. See "List of parameters".


Control arguments:
   (All control arguments to the exec_com command must precede the
    pathname of the exec_com program.)
-no_trace KEYWORD_LIST
   turns off tracing of specified types of exec_com lines, overriding
   any &trace statements in the exec_com for those types of lines.
   The default is -trace_default. KEYWORD_LIST is composed of any of
   the keywords "command", "comment", "control", and "input", separated
   by commas with no intervening space.
-trace KEYWORD_LIST
   turns on tracing of specified types of exec_com lines, overriding
   any &trace statements in the exec_com for those types of lines.
   The default is -trace_default. KEYWORD_LIST is composed of any of
   the following, separated by commas with no intervening space:
	command, comment, control, input, all_types
	     turns on tracing for the corresponding type of line.
	unexpanded, expanded, all, all_expansions, both
	     affects how the expansion of lines is traced. These are
	     equivalent to &unexpanded, &expanded, &all, and &both in
	     &trace statements inside the exec_com. The keyword
	     "all_expansions" is equivalent to "all".
	prefix=STR
	     specifies a prefix for traced lines, equivalent to
	     &prefix in &trace statements.
	osw=SWITCHNAME
	     specifies an I/O switch on which to write the trace,
	     equivalent to &osw in &trace statements.
-trace_default
   uses &trace statements in the exec_com and the default tracing modes
   to determine what and how to trace. (Default)


List of parameters:
&1 - &9
   expand to the 1st through 9th ec_args, or to defaults defined by a
   &default statement or to null string if there is no corresponding
   ec_arg. The string &0 is invalid.
&(1) - &(9)
   are synonyms for &1 - &9.
&(11), &(12), etc.
   expands to the corresponding ec_arg, or to a default defined by
   &default or to null string if there is no corresponding ec_arg.
   The parentheses are required when there are two or more digits.


&q1 - &q9
&q(1), &q(11), etc.
   expands to the corresponding argument with quotes doubled according
   to the quote depth of the surrounding context. See "Notes on
   quoting". This parameter ensures that quotes in the argument to
   exec_com are handled correctly under the quote-stripping action of
   the command processor.
&r1 - &r9
&r(1), &r(11), etc.
   expands to the corresponding argument enclosed in an added layer of
   quotes, and internal quotes doubled accordingly. See "Notes on
   quoting". This parameter keeps the value of the argument as a
   single unit after one layer of quote-stripping by the command
   processor.


&n
   expands to the number of ec_args specified to exec_com.
&f1 - &f9
&f(1), &f(11), etc.
   expands to a list of the Nth through last ec_args separated by 
   spaces. If N is greater than the value of &n, expands to null string.
&qf1 - &qf9
&qf(1), &qf(11), etc.
   expands to a list of the Nth through last ec_args, with quotes
   doubled, separated by spaces. If N is greater than the value of &n,
   expands to null string. This parameter is equivalent to:
   &qN &qN+1 &qN+2 ....


&rf1 - &rf9
&rf(1), &rf(11), etc.
   expands to a list of the Nth through last ec_args, individually
   requoted, separated by spaces. If N is greater than the value of
   &n, expands to null string. This parameter is equivalent to:
   &rN &rN+1 &rN+2 ....
&f&n, &qf&n, &rf&n
   expands to the last ec_arg specified to exec_com, either as is,
   with quotes doubled, or requoted.


&condition_info_ptr, &cond_info_ptr
   inside an &on unit (see "List of condition handling statements"),
   expands to a virtual pointer (<segment_number>|<offset>) to the
   condition_info structure for the condition that was signalled.
   Programs can be written to interpret the structure for a particular
   condition.
&condition_name, &cond_name
   inside an &on unit (See "List of condition handling statements"),
   expands to the name of the condition that caused the &on unit to
   be invoked. Outside an &on unit, expands to null string.
&ec_dir
   expands to the pathname of the directory containing the exec_com
   currently running. It can be used to call other exec_com's in the
   same directory.


&ec_name
   expands to the entryname of the exec_com currently running, with
   any ec or absin suffix removed (the absin suffix is for an exec_com
   invoked by the absentee facility; type "help ear").
   This parameter can be used to simulate entrypoints in an exec_com
   segment, by adding multiple names to the segment and transferring
   to a different &label depending on the name invoked.
&ec_path
   expands to the expanded, suffixed pathname of the current exec_com.
&ec_switch
   expands to the name of the I/O switch over which the exec_com
   interpreter is reading the exec_com.
&handlers
   expands to a list of condition names for which &on handlers are
   currently in effect. (See "List of condition handling statements").
   Condition names are individually requoted and separated by spaces.
   To test whether a handler is currently in effect for NAME, type:
	&if [or [equal NAME (&handlers)]] &then ...


List of value expressions:
   (All of these constructs can be nested arbitrarily inside each 
   other.)
&(NAME)
   expands to the value assigned to the variable NAME by a previous
   &set statement in the same exec_com. If NAME contains &'s, it is
   first expanded. Therefore, &() constructs can be nested. However,
   &'s in the expansion are not re-expanded. A second level of
   expansion must be specified, therefore, by &(&()).
   If NAME has not been assigned a value by &set, an error occurs.
   Variable names are allowed to contain any characters except &
   and cannot consist solely of digits.


&(N)
   where N is a positive integer, expands to the value of the Nth
   ec_arg to exec_com, or if there is no Nth ec_arg, to the last
   default value assigned to argument N by a &default statement, or if
   no default value was assigned, to null string.
&q(NAME), &q(N)
   expands to the same thing as &(NAME) or &(N), but with quotes
   inside the value doubled according to the quote depoth of the
   surrounding context.
&r(NAME), &r(n)
   expands to the same thing as &(NAME) or &(N), but requoted and
   with internal quotes doubled.


&[ACTIVE STRING], &||[ACTIVE STRING]
   expands to the return value of an active string by calling the
   command processor. This construct ends with the matching right
   bracket. The &||[...] construct is used in &set statements to treat
   the expansion as a single argument to &set. It is important to note
   that &[...] active strings are expanded by exec_com, whereas [...]
   strings are expanded at command line execution time. Therefore,
   ||[...] and not &||[...] must be used in a command line to treat
   the expansion as a single command argument.


List of literals:
   Also see "Notes on white space".
&"..."
   encloses an arbitrary character string to be taken literally.
   Quotes inside the string must be doubled, and the closing undoubled
   quote ends the literal string.
&&
   expands to a single & character, not further expanded.
&AMP, &AMP(N)
   expands to a single ampersand character (ASCII 046), in which case
   it is identical to &&, or to N ampersands where N is a positive
   integer.
&SP, &SP(N)
   expands to a single space character (ASCII 040) or to N spaces.


&BS, &BS(N)
   expands to a single backspace character (ASCII 010) or to N
   backspaces.
&HT, &HT(N)
   expands to a single horizontal tab character (ASCII 011) or to N
   horizontal tabs.
&VT, &VT(N)
   expands to a single vertical tab character (ASCII 013) or to N
   vertical tabs.
&FF, &FF(N), &NP, &NP(N)
   expands to a single form-feed character (ASCII 014) or to N
   form-feeds.


&NL, &NL(N), &LF, &LF(N)
   expands to a single newline character (ASCII 012) or to N newlines.
&CR, &CR(N)
   expands to a single carriage return character (ASCII 015) or to N
   carriage returns.
&QT, &QT(N)
   expands to a single double-quote character (") or to N of them.
&!
   expands to a Multics 15-character unique name, for example
   "!BBBhjBnWQpGbbc". Multiple occurrences of &! within the same
   exec_com expand to the same string.


List of predicates:
&is_defined(NAME)
   expands to "true" if the variable named NAME has been assigned a
   value by an &set statement in the current exec_com, "false"
   otherwise (See "Notes on variables"). This construct expands to
   "true" if &(NAME) can be expanded, "false" if &(NAME) is an error.
&is_defined(N)
   where N is a positive integer, expands to "true" if an Nth ec_arg
   was specified to exec_com or an Nth default was defined via the
   &default statement (see "List of assignment statements"), "false"
   otherwise.
&is_absin
   expands to "true" if the exec_com is being executed by the
   absentee facility, "false" if it is being executed by the exec_com
   command or active function. For example, the segment foo.absin
   submitted as an absentee job expands &is_absin to "true" but an
   exec_com that it invokes via "ec ..." expands &is_absin to "false".


&is_active_function, &is_af
   expands to "true" if the exec_com is being executed by the exec_com
   active function, "false" otherwise.
&is_attached
   expands to "true" if input is currently attached via an &attach
   statement, "false" otherwise. See "Notes on input attachment".
   Input is always attached when running as an absentee.
&is_input_line
   expands to "true" if the line in which it appears is being read as
   an input line by some command, "false" otherwise.
&was_attached
   inside an &on unit (See "List of condition handling statements"),
   expands to "true" if the parent exec_com was attached via &attach
   at the time the condition occurred, "false" otherwise. Outside an
   &on unit, always expands to "false".


List of control statements:
&attach {&trim on/off}
   causes any commands subsequently invoked in command lines to read
   their input from the exec_com rather than from the terminal.
   See "Notes on input attachment". Specifying "&trim off" causes the
   input lines to be read intact, without stripping off the leading and
   trailing white space as is done with most exec_com lines.
   The default is "&trim on".
&detach
   causes any commands subsequently invoked in command lines to read
   their input from the terminal. This is the default. See "Notes on
   input attachment".


&if EXPRESSION
   expands EXPRESSION to get a true or false value. EXPRESSION can
   contain any exec_com-expandable constructs, such as &[...]
   (See "List of value expressions"). If the expanded value of
   EXPRESSION is "true", the following &then statement (if any) is
   executed next. If the value is "false", the following &else
   statement (if any) is executed next. If the value is neither "true"
   nor "false", an error occurs. 
&then LINE
&then &do LINES &end
&else LINE
&else &do LINES &end
   where LINE is any exec_com line, including another &if statement.
   LINE is executed or not depending on the value of the preceding
   &if clause. The &then and &else statements, unlike other exec_com
   statements, are allowed to appear on the same line with one
   another and with &if.  The &do keyword must appear on the same line
   as &then or &else.  The contents of a &do-&end block reference
   the same variables as the containing exec_com. No &goto's are 
   allowed into a &do-&end block from outside it.


&goto LABEL
   causes the next statement to be executed to be the statement
   following the first occurrence of "&label LABEL" in the
   exec_com.
&label LABEL
   specifies a target for "&goto LABEL" and is otherwise ignored.
   The string LABEL can contain any characters.


&quit
   terminates execution of the exec_com. If the program was invoked
   by the exec_com active function, the active function return value
   is null string.
&return LINE
   terminates execution of the exec_com. If the program was invoked
   by the exec_com active function, the active function value is the
   (expanded) value of LINE, the rest of the line. If the program was
   invoked by the exec_com command, the expanded value of LINE is
   printed on the terminal.


List of assignment statements:
&set NAME1 VALUE1 ... NAMEn VALUEn
   assigns values to the variables NAME1 through NAMEn, which are
   created if no assignments for them already exist. All NAMEj and
   VALUEj arguments are fully expanded before any values are set.
   Therefore, the statement:
	&set a &(b) b &(a)
   exchanges the values of the variables a and b. Arguments to &set
   are delimited by white space. White space and literals inside them
   must be enclosed in "...", for example:
	&set answer "&[response Answer?]"
   Alternatively, the &||[...] construct can be used, causing the 
   entire return value to be taken as a single argument:
	&set answer &||[response Answer?]
   There is no restriction on the lengths of NAMEj or VALUEj; NAMEj
   cannot be all digits. If VALUEj is the unquoted keyword &undefined,
   any existing value for NAMEj is deleted, and the &is_defined(NAMEj)
   construct will expand to "false".


&default VALUE1 ... VALUEn
   assigns default values for the exec_com parameters &(1) through 
   &(n).  The default value of &(j) only matters if no jth ec_arg was
   specified to exec_com. The &(j) parameter reference expands to the
   value of the jth ec_arg, or if there is none, to the jth default
   value set by &default, or if there is none, to null string.
   VALUEj arguments are separated by white space, and each is fully
   expanded before default values are set. White space and literal 's
   in them must be enclosed in &"...". If VALUEj is the keyword
   &undefined, no jth default value is set. This keyword is used as
   a place-holder to skip the jth position.


List of printing statements:
&print LINE
   prints the expanded remainder of the line, followed by a newline
   character. If &print appears on a line by itself, a single newline
   character is printed.
&print_nnl LINE
   prints the expanded remainder of the line, without appending a
   newline character.


List of condition handling statements:
&on CONDITION_LIST &begin LINES &end
   establishes a condition handler (&on unit) to be invoked whenever
   any of the conditions named in CONDITION_LIST is signalled.
   Condition names are separated by white space. LINES is any sequence
   of exec_com lines, optionally including &goto statements to transfer
   to labels either inside the &on unit or outside (ie., in the parent
   exec_com). When executed, LINES is treated as a separate exec_com
   in the sense that changes to its &attach, &ready_proc and &trace
   modes (initially off) do not affect the parent exec_com. However,
   &on units share the parent ec's variables and any changes to
   variables affect the parent exec_com. The &begin and &end keywords
   are required for delimiting LINES, even if it consists of a single
   line. No &quit statement is required.
&revert CONDITION_LIST
   reverts any &on units for the conditions named in CONDITION_LIST.
   Condition names are separated by white space.
&signal CONDITION_NAME
   signals the specified condition.


  (The following statements are allowed only inside &on units.)
&exit {&continue}
   causes the &on unit to exit immediately. This statement is useful
   for conditionally exiting part-way through an &on unit.
   If &continue is specified, the condition continues to be propagated
   to other handlers down the stack.
   

List of tracing statements:
&list_variables {match_names} {&control_args}
&lsv {match_names} {&control_args}
   lists the values of all or selected exec_com variables, where
   match_names are starnames and/or qedx regular expressions surrounded
   by /'s. Control args are "&exclude match_name" or "&ex match_name" to
   prevent certain names from being listed, &variable or &var to list
   just the variable names, and &value or &val to list just the values.
&ready on
&ready off
   turns ready messages on or off. Turning them on causes the system
   ready procedure to print a ready message when it is called.
   The default is off. This statement does not affect whether the
   ready procedure is called. The ready procedure is normally called
   after the execution of a command line (type "help ready_on").
   The &ready statement is ignored in the absentee environment.
&ready_proc on
&ready_proc off
   determines whether or not the system ready procedure is called
   after each command line is executed. The default is on for the
   exec_com command, off for the active function. This statement is
   ignored in the absentee environment.


&trace {TYPES} STATE {&prefix PREFIX} {&osw SWITCHNAME}
   sets tracing for one or more kinds of lines specified by TYPES.
   TYPES can be any combination of the following:
     &command	command lines.
     &comment	comments, including those sharing other lines.
     &control	control lines, for example &print....
     &input	lines being read as input to some command.
   The default if TYPE is omitted is all four types.

   STATE can be one of the following--
     off, false	disables tracing entirely.
     on, true	enables tracing, in whichever of the following
		modes was last specified. The default mode is
		"&expanded" for command and input lines, "&both"
		for control lines.
     (continued)


     &unexpanded	prints lines as they appear in the exec_com
		segment. Implies "on".
     &expanded	prints lines after all expansion has been done.
		Implies "on".
     &all		prints at each stage of expansion. Implies "on".
     &both	prints each line as it appears in the exec_com,
		and again after all expansion. Implies "on".

   Defaults for ec's invoked by the exec_com command/active function
   are "&expanded" for command and input lines, "&unexpanded" for
   control lines, and "off" for comments.
   Defaults in the absentee environment are "&expanded" for command and
   control lines, "off" for control lines and comments.


   PREFIX specifies a string to be printed at the start of each line.
   Default prefixes are all null string.

   SWITCHNAME specifies an I/O switch on which to write the trace.
   The default for all types of lines in ec's invoked by the exec_com
   command or active function is user_output. The default in the
   absentee environment is user_io.


Notes on absentee environment:
An exec_com/absin runs in the absentee environment only when it has
been invoked directly by the absentee facility, ie. is running an
absentee process. Exec_com's called within an absentee process are said
to run in the normal exec_com environment.


Input lines in an absentee process come from the absin segment running
the process. These, along with output lines, are directed to an
absout file. Since both input and output lines are written to the same
switch, the default switch is chosen to be user_io for the absentee
environment rather than user_output as for exec_com's. This default
applies to all tracing, and ensures that even if user_output is
redirected somewhere, the input lines driving the process still appear
in the absout.


The &attach and &detach statements have no effect in the absentee
environment, since input to the absentee process always comes from the
absin file. The &is_attached predicate always returns true.

The &ready and &ready_proc statements also have no effect in the
absentee environment. Instead, the ready_on and ready_off commands
should be used.


Notes on version:
The current version of exec_com is known as Version 2. In many ways
similar to the old Version 1, it adds automatic variables, parameter
defaults, literal character escapes, indentation, comments on lines,
line continuation, expansion of active strings in control lines, and
tracing of comments and control lines.

In addition, there are two incompatible changes between the versions.
Whereas V1 leaves unrecognized &strings alone, V2 rejects them as
syntax errors. This change makes V2 an extensible language.
Secondly, V2 parses lines into control keywords and tokens (separated
by whitespace) before expansion, so that expansion can only change the
values of tokens but not the syntax of a line.


A Version 2 exec_com has "&version 2" as its first line. If this first
line is not present, the exec_com is interpreted as Version 1.
Version 1 exec_com's can optionally begin with "&version 1"; at some
future time, Version 2 will be the default and "&version 1" will be
required.

A conversion command is available to translate Version 1 exec_com's to
Version 2. Type "help cvec".


Notes on white space:
White space (SPACE, HORIZONTAL TAB, VERTICAL TAB, and FORM-FEED)
is ignored at the beginning and end of each line, with the exception
of input lines specifically read via "&attach &trim off". As a result,
exec_com lines can be indented freely. Intentional white space at the
beginning or end of a line (for example, an editor input line) must be
specified by literal escapes such as &SP. See "List of literals".


Notes on comments:
Comments are specified by the character sequence &- anywhere in a line.
Where this sequence appears (outside of &"..."), the remainder of the
line is a comment and can contain any characters. White space preceding
the comment, if any, is ignored. Therefore, comments can be aligned
at a particular column without affecting the executable text.
White space before a comment can be specified by the literal escapes
described in "List of literals".


Notes on continuation:
Long command lines and other portions of text that must not be broken
can be continued on successive lines by means of the character sequence
&+ at the beginning of each continuation line. White space preceding
the &+ is ignored and whitespace following the &+ is part of the 
executable line.

Continuation is not affected by intervening comments, whether at the
end of executable text lines or on lines by themselves. This feature
can be used to comment parts of statements.


Notes on quoting:
The exec_com interpreter strips one layer of exec_com quotes (&"...")
from the text. It does not perform command processor-type stripping of
regular quotes ("...").


To defeat one or more levels of command processor quote-stripping, the
values of variable and parameter expansions can be quote-doubled or
requoted using the "q" and "r" prefixes. Quote-doubling doubles
existing quote characters in a string according to the depth of quotes
inside which the string is currently nested, so that one level of
quote-stripping by the command processor will result in the internal
quotes looking the same as they do inside the original string.
Requoting goes a step further by first quote-doubling, then surrounding
string with an additional layer of quotes, thus causing the entire
string to remain a single argument after one level of quote stripping
by the command processor. In the examples below, "Level" refers to the
number of levels deep in quotes that the parameter reference appears in
the exec_com text. Assume that the value of the first ec_arg to
exec_com is the string a"b containing a single quote character:


	&1	&q1	     &r1
Level 0	a"b	a"b	     "a""b"
Level 1	"a"b"	"a""b"	     """a""""b"""
Level 2	"""a"b"""	"""a""""a"""   """""""a""""""""b"""""""

The exact number of quote characters is unimportant; the important
thing is that &q protects internal quotes from one level of quote
stripping by the command processor, and &r ensures that the
value remains a single argument to the comand processor. These prefixes
are very useful since, if the value of the first ec_arg (for example)
contains a space, the value of &1 substituted into a command line will
be parsed into more than one command line argument.


If a value is null, the &q prefix does not affect it, and the &r prefix
results in a pair of quotes, doubled according to the quote depth of
the context.

The "q" and "r" prefixes can be used in the following constructs--
	&q1, &q(1)	&r1, &r(1)
	&qf1, &qf(1)	&rf1, &rf(1)
	&q&n, &qf&n	&r&n, &rf&n
	&q(VAR NAME)	&r(VAR NAME)


Notes on input attachment:
By default, commands invoked by command lines within an exec_com read
their input from the terminal. By preceding a command line with an
&attach statement, the command can be caused to read input lines from
the text of the exec_com instead. Note that "&attach" must precede the
line on which the input-reading command is invoked.  The &detach 
statement causes any later input-reading command to get its
input from the terminal.

While &attach is in effect, the &is_attached predicate expands to
"true"; after &detach, it expands to "false".

