[alt.sources] zsh - a ksh/tcsh-like shell

pfalstad@phoenix.Princeton.EDU (Paul John Falstad) (12/15/90)

---cut here---cut here---cut here---
#! /bin/sh
#
# This is a shar file containing zsh, a ksh/tcsh-like shell.  To extract,
# cat all 8 parts together and pipe the result through sh.  There is
# a "cut here" at the beginning and end of each part--be sure to
# remove everything outside of those.  I put the # man page first so
# you can see what zsh is like.
#
# To unbundle, sh this file
# Fri Dec 14 18:10:16 EST 1990
mkdir readline
echo zsh.1 1>&2
sed 's/^-//' >zsh.1 <<'End of zsh.1'
-.TH ZSH 1
-.SH NAME
-zsh \- the Z shell
-.SH SYNTAX
-\fBzsh\fP
-[
-.B \-aefikmnstuvx0123456789ABCDEFGHIJK
-] [
-.B \-c
-string ]
-[ arg .\|.\|. ]
-.SH DESCRIPTION
-\fBzsh\fP
-is a command interpreter and programming language
-that executes commands read from a terminal
-or a file.
-See
-.B Invocation
-for the meanings of arguments to \fBzsh\fP.
-.SS Definitions
-A metacharacter can one of the following characters:
-.RS
-.PP
-\fB;   &   (   )   {   }   \(bv   <   >   blank   newline\fP
-.RE
-.PP
-A blank is a
-.B tab
-or a
-.BR space .
-An identifier
-is a sequence of letters, digits, or underscores
-starting with a letter or underscore.
-Identifiers are used as names for
-`named parameters'.
-A word is a sequence of
-characters separated by one or more non-quoted
-metacharacters.
-.PP
-A command
-is a sequence of characters in the syntax
-of the shell language.
-\fBzsh\fP reads each command and
-carries out the desired action either directly or by invoking
-separate utilities.
-A builtin is a command that is carried out by the
-parent shell without creating a separate process.
-.SS Commands
-A simple-command is a sequence of blank
-separated words
-which may be preceded by a parameter assignment list.
-See
-.B Environment
-below.
-The first word specifies the name of the command to
-be executed.
-Except as specified below,
-the remaining words are passed as arguments
-to the invoked command.
-The command name is passed as argument 0
-(see
-.BR exec (2)).
-The value of a simple-command is its exit status
-if it terminates normally, or (octal) 200+\fIstatus\^\fP if
-it terminates abnormally (see
-.B signal
-for a list of
-status values).
-.PP
-A pipeline
-is a sequence of one or more
-commands
-separated by
-.B \(bv
-or
-.B \(bv&
-("\fB\(bv&\fP" is actually shorthand for "\fB2>&1\ \|\(bv\fP\|".  See
-.B Input/Output
-below).
-The standard output of each command but the last
-is connected by a
-.B pipe 
-to the standard input of the next command.
-Each command is run as a separate process;
-\fBzsh\fP waits for all the commands to terminate.
-The exit status of a pipeline is the exit
-status of the last command to terminate.  A pipeline may be preceded by
-one of the following keywords:
-.PP
-.PD 0
-.TP
-\fBtime\fP
-The user, system, and real times
-of the commands in the pipeline are printed when the pipeline
-completes.
-.TP
-\fBcoproc\fP
-The processes are
-run asynchronously with the input and output of the pipeline
-connected to a two-way pipe to the parent shell.  The parent
-communicates with the coprocess using the \fB>&p\fP
-and \fB<&p\fP redirection operators.
-.TP
-\fB!\fP
-The exit status of the pipeline is the boolean NOT of the
-exit status of the last command.
-.PD
-.PP
-A sublist is a sequence of one or more pipelines
-separated by
-.BR &&
-or
-.BR || .
-The symbol \fB&&\fP (\fB||\fP) causes the list following it to be
-executed only if the preceding pipeline returns
-a zero (non-zero) value.
-.PP
-A list is a sequence of one or more sublists separated
-by, and optionally terminated by, either
-.BR ;
-or
-.BR & .
-A \fB;\fP causes sequential execution of the preceding
-sublist; a \fB&\fP causes asynchronous execution of the preceding
-sublist (that is, it does not wait for that sublist to finish).
-An arbitrary number of newlines may appear in a
-list, instead of a semicolon,
-to delimit a command.
-.PP
-A command
-is either a simple-command
-or one of the following.
-Unless otherwise stated,
-the value returned by a command is that of the
-last simple-command executed in the command.
-.TP
-\fBfor\fP \fIidentifier\^\fP [ \fBin\fP \fIword\^\fP .\|.\|. ] \fB;do\fP \fIlist\^\fP \fB;done\fP
-Each time a
-.B for
-command is executed, 
-.I identifier 
-is set to the next 
-.I word 
-taken from the
-.B in
-.I word list.
-If
-.B in 
-.I word
-\&.\|.\|.
-is omitted, then the
-.B for
-command executes the \fBdo\fP \fIlist\^\fP once for each positional parameter
-that is set
-(see \fB"Parameter Substitution"\fP).
-Execution ends when there are no more words in the list.
-.TP
-\fBselect\fP \fIidentifier\^\fP [ \fBin\fP \fIword\^\fP .\|.\|. ] \fB;do\fP \fIlist\^\fP \fB;done\fP
-A
-.B select
-command prints on standard error (file descriptor 2), the set of
-.IR word s,
-each preceded by a number.
-If
-.BI in " word"
-\&.\|.\|.
-is omitted, then the positional parameters are used instead
-(see
-.B "Parameter Substitution"
-below).
-The
-.B PROMPT3
-prompt is printed
-and a line is read from the standard input.
-If this line consists of the number
-of one of the listed
-.IR word s,
-then the value of the parameter
-.I identifier
-is set to the
-.I word
-corresponding to this number.
-If this line is empty the selection list is
-printed again.
-Otherwise the value of the parameter
-.I identifier
-is set to null.  The contents of the line read from standard input is
-saved in the parameter \fBREPLY\fP.  The
-.I list
-is executed for each selection until a
-break or end-of-file is encountered.
-.TP
-\fBcase\fP \fIword\^\fP \fBin\fP [ \fIpattern\^\fP \fB)\fP \fIlist\^\fP \fB;;\fP ] .\|.\|. \fBesac\fP
-A
-.B case
-command executes the
-.I list
-associated with the first
-.I pattern
-that matches
-.IR word .
-The form of the patterns is
-the same as that used for
-filename generation (see
-.B "Filename Generation"
-below).
-.TP
-\fBif\fP \fIlist\^\fP \fB;then\fP \fIlist\^\fP [ \
-\fBelif\fP \fIlist\^\fP \fB;then\fP \fIlist\^\fP ] .\|.\|. \
-[ \fB;else\fP \fIlist\^\fP ] \fB;f\&i\fP
-The
-.I list
-following \fBif\fP is executed and,
-if it
-returns a zero exit status, the
-.I list
-following the first
-.B then
-is executed.  Otherwise, the
-.I list
-following \fBelif\fP
-is executed and, if its value is zero, the
-.I list
-following the next
-.B then
-is executed.  Failing that, the
-.B else
-.I list
-is executed.  If no
-.B else
-.I list
-or
-.B then
-.I list
-is executed, then the
-.B if
-command returns a zero exit status.
-.TP
-.PD 0
-\fBwhile\fP \fIlist\^\fP \fB;do\fP \fIlist\^\fP \fB;done\fP
-.TP
-\fBuntil\fP \fIlist\^\fP \fB;do\fP \fIlist\^\fP \fB;done\fP
-.PD
-A
-.B while
-command repeatedly executes the
-.B while
-.I list
-and, if the exit status of the last command in the list is zero, executes
-the
-.B do
-.IR list ;
-otherwise the loop terminates.
-If no commands in the
-.B do
-.I list
-are executed, then the
-.B while
-command returns a zero exit status;
-.B until
-may be used in place of
-.B while
-to negate
-the loop termination test.
-.TP
-\fBrepeat\fP \fInum\fP\fB ;do\fP \fIlist\^\fP \fB;done\fP
-A
-.B repeat
-command executes the
-.I list
-a certain number of times, as specified by
-.IR num .
-If the exit status of
-.I list
-is nonzero, the loop terminates.
-.TP
-\fB(\fP\fIlist\^\fP\fB)\fP
-Execute
-.I list
-in a separate environment.
-Note, that if two adjacent open parentheses are
-needed for nesting, a space must be inserted to avoid
-arithmetic evaluation as described below.
-.TP
-\fB{\fP\fIlist\^\fP\fB}\fP
-The 
-.I list
-is simply executed.
-.TP
-.PD 0
-\fBfunction\fP \fIidentifier\^\fP \fB{\fP\fIlist\fB}\fP
-.TP
-\fIidentifier\^\fP \fB() {\fP\fIlist\fB}\fP
-.PD
-Define a function which is referenced by
-.IR identifier .
-The body of the function is the
-.I list
-of commands between
-.B {
-and
-.BR } .
-(See
-.B Functions
-below).
-.TP
-\fBexec \fP\fIcommand\^\fP
-.br
-The
-.I command
-is executed in place of the parent shell, without forking.
-.TP
-\fBcommand \fP\fIcommand\^\fP
-.br
-The
-.I command
-is run, ignoring shell functions.
-.PP
-The following reserved words
-are only recognized as the first word of a command
-and when not quoted:
-.RS
-.PP
-.B
-if then else elif fi case esac for while until do done repeat function select time coproc ! exec command
-.RE
-.SS History Substitution
-.LP
-History substitution allows you to use words from previous command
-lines in the command line you are typing.  This simplifies spelling
-corrections and the repetition of complicated commands or arguments.
-Command lines are saved in the history list, the size of which
-is controlled by the
-.B HISTSIZE
-variable.  The most recent command is retained in any case.
-A history substitution begins with a
-.B !
-and may occur anywhere on the command line; history
-substitutions do not nest.  The
-.B !
-can be escaped with
-.B \e
-to suppress its special meaning.
-.LP
-Input lines containing history substitutions are echoed on the
-terminal after being expanded, but before any other
-substitutions take place or the command gets executed.
-.SS \fIEvent Designators\fP
-.LP
-An event designator is a reference to a command-line entry in
-the history list.
-.RS
-.PD 0
-.TP
-.B !
-Start a history substitution, except when followed by a blank, newline,
-.BR = ,
-or
-.BR ( .
-.TP
-.B !!
-Refer to the previous command. 
-By itself, this substitution
-repeats the previous command.
-.TP
-.BI ! n
-Refer to command-line
-.IR n .
-.TP
-.BI ! \-n
-Refer to the current command-line minus
-.IR n .
-.TP
-.BI  ! str
-Refer to the most recent command starting with
-.IR str .
-.TP
-.BI  !? str\fR[\fP ? \fR]\fP
-Refer to the most recent command containing
-.IR str .
-.TP
-.B !#
-Refer to the current command line typed in so far.
-.TP
-.BR !{ .\|.\|. }
-Insulate a history reference from adjacent characters (if necessary).
-.PD
-.RE
-.SS \fIWord Designators\fR
-.LP
-A
-.RB ` : '
-separates the event specification from the word designator. 
-It can be omitted if the word designator begins with a
-.BR \*^ ,
-.BR $ ,
-.BR * ,
-.B \-
-or
-.BR % .
-If the word is to be selected from the previous command, the second
-.B !
-character can be omitted from the event specification.  For instance,
-.B !!:1
-and
-.B !:1
-both refer to the first word of the previous command, while
-.B !!$
-and
-.B !$
-both refer to the last word in the previous command. 
-Word designators include:
-.RS
-.PD 0
-.TP
-.B 0
-The first input word (command).
-.TP
-.I n
-The
-.IR n 'th
-argument.
-.TP
-.B ^
-The first argument, that is,
-.BR 1 .
-.TP
-.B $
-The last argument.
-.TP
-.B %
-The word matched by (the most recent)
-.BI ? s
-search.
-.TP
-.IB x \- y
-A range of words;
-.BI \- y
-abbreviates
-.BI 0\- y\fR.
-.TP
-.B *
-All the arguments, or a null value if there is just
-one word in the event.
-.TP
-.IB x *
-Abbreviates
-.IB x \-$ .
-.TP
-.IB x \-
-Like
-.I x*
-but omitting word
-.BR $ .
-.PD
-.RE
-.SS \fIModifiers\fR
-.IX "history substitution modifiers"
-.IX ": modifiers" "" "\fL:\fR modifiers \(em history substitution \(em \fLcsh\fR"
-.LP
-After the optional word designator, you can add
-a sequence of one or more of the following modifiers,
-each preceded by a
-.BR : .
-.RS
-.TP
-.B h
-Remove a trailing pathname component, leaving the head.
-.PD 0
-.TP
-.B r
-Remove a trailing suffix of the form
-.RB ` "\&.\fIxxx" ',
-leaving the basename.
-.TP
-.B e
-Remove all but the suffix.
-.TP
-.BI s/ l / r\fR[\fP / \fR]\fP
-Substitute
-.I r
-for
-.IR l .
-.TP
-.B t
-Remove all leading pathname components, leaving the tail.
-.TP
-.B &
-Repeat the previous substitution.
-.TP
-.B g
-Apply the change to the first occurrence of a match in each word,
-by prefixing the above (for example,
-.BR g& ).
-.TP
-.B p
-Print the new command but do not execute it.
-.TP
-.B q
-Quote the substituted words, escaping further substitutions.
-.TP
-.B x
-Like
-.BR q ,
-but break into words at each blank.
-.PD
-.RE
-.LP
-Unless preceded by a
-.BR g ,
-the modification is applied only to the
-first string that matches
-.IR l ;
-an error results if no string matches.
-.LP
-The left-hand side of substitutions are not regular expressions,
-but character strings.
-Any character can be used as the delimiter in place of
-.BR / .
-A backslash quotes the delimiter character.
-The character
-.BR & ,
-in the right hand side, is replaced by the text
-from the left-hand-side. 
-The
-.B &
-can be quoted with a backslash. 
-A null
-.I l
-uses the previous string either from a
-.I l
-or from a contextual scan string
-.I s
-from
-.BI !? s\fR.
-You can omit the rightmost delimiter if a newline
-immediately follows
-.IR r ;
-the rightmost
-.B ?
-in a context scan can similarly be omitted.
-.LP
-Without an event specification, a history reference refers either to the
-previous command, or to a previous history reference on the command line
-(if any).
-.PP
-.LP
-.PP
-The character sequence
-.BI ^ foo ^ bar
-repeats the last command, replacing the string "foo" with the
-string "bar".
-.PP
-If \fBzsh\fP encounters the character sequence
-\fB!"\fP
-in the input, the history mechanism is temporarily disabled until
-the current list is fully parsed.  The
-\fB!"\fP
-is removed from the input, and any subsequent
-.B !
-characters have no special significance.
-.PP
-A less convenient but more comprehensible
-form of command history support
-is provided by the
-.B fc
-builtin (see below).
-.SS Comments
-In noninteractive shells,
-a word beginning with
-.B #
-causes that word and all the following characters up to a newline
-to be ignored.
-.SS Aliasing
-The first word of each command is replaced by the text of an
-alias if an alias for this word has been defined.  
-The replacement string can contain any
-valid input
-including the metacharacters listed above.
-If the last character of the alias value is a blank
-then the word following the alias will also be checked for alias
-substitution.
-Aliases can be nested.
-If an alias is defined with using the \-a flag (see the
-.B alias
-builtin below), it will be replaced no matter where it
-appears in the command line.
-Aliases can be used to redefine 
-builtin commands or the
-`reserved words' listed above.
-Aliases can be created and listed with the
-alias
-command and can be removed with the
-unalias
-command.
-.PP
-The following aliases
-are compiled into \fBzsh\fP
-but can be unset or redefined:
-.RS 5
-.PD 0
-.TP
-.B "false=\(fmlet 0\(fm"
-.TP
-.B "history=\(fmfc \-l\(fm"
-.TP
-.B "nohup=\(fmnohup\ \(fm"
-.TP
-.B "r=\(fmfc \-e \-\(fm"
-.TP
-.B "true=\(fm:\(fm"
-.TP
-.B "pwd=\(fmecho $PWD\(fm"
-.PD
-.RE
-.SS Process Substitution
-Each command argument of the form
-\fB<(\fP\fIlist\^\fP\fB)\fP
-or
-\fB>(\fP\fIlist\^\fP\fB)\fP
-or
-\fB=(\fP\fIlist\^\fP\fB)\fP
-is subject to process substitution.
-In the case of the
-.B <
-or
-.B >
-forms, \fBzsh\fP
-will run process
-.I list
-asynchronously connected to a named pipe (FIFO).
-The name of this pipe will become the argument to the command.
-If the form with
-.B >
-is selected then writing on this file will provide input for
-.IR list .
-If
-.B <
-is used,
-then the file passed as an argument will
-be a named pipe connected to the output of the
-.I list
-process.
-For example,
-.RS
-.PP
-\fBpaste <(cut \-f1\fP \fIfile1\fP\fB) <(cut \-f3\fP \fIfile2\fB) | tee >(\fP\fIprocess1\fP\fB) >(\fP\fIprocess2\fP\fB)\fP >/dev/null
-.RE
-.PP
-.BR cut s
-fields 1 and 3 from
-the files
-.I file1
-and
-.I file2
-respectively,
-.BR paste s
-the results together, and sends it to the processes
-.I process1
-and
-.IR process2 .
-Note that the file, which is passed as an argument to the command,
-is a system
-pipe 
-so programs that expect to
-.BR lseek (2)
-on the file will not work.
-Also note that the previous example can be more compactly and
-efficiently written as:
-.RS
-.PP
-\fBpaste <(cut \-f1\fP \fIfile1\fP\fB) <(cut \-f3\fP \fIfile2\fB) > >(\fP\fIprocess1\fP\fB) > >(\fP\fIprocess2\fP\fB)\fP
-.RE
-.PP
-\fBzsh\fP uses socketpairs (pipes) instead of a FIFOs to implement the latter
-two process substitutions in the above example.
-.PP
-If
-.B =
-is used,
-then the file passed as an argument will be the name
-of a temporary file containing
-the output of the
-.I list
-process.  This may be used instead of the
-.B <
-form for a program that expects to lseek on the input file.
-.SS Parameter Substitution
-A parameter is an identifier,
-one or more digits,
-or any of the characters
-.BR \(** ,
-.BR # ,
-.BR ? ,
-.BR \- ,
-.BR $ ,
-and
-.BR !\\^ .
-The value of a named
-parameter may also be assigned by writing:
-.RS
-.PP
-.IB name = value\^\|
-[
-.IB name = value
-] .\|.\|.
-.RE
-.PP
-If
-.I name
-was declared integer with the
-.B integer
-builtin, the
-.I value
-is subject to arithmetic evaluation as described below.
-.PP
-Positional parameters,
-parameters denoted by a number,
-may be assigned values with the
-\fBset\fP
-builtin.  Parameter
-.B $0
-is set from argument zero when \fBzsh\fP
-is invoked.
-.PP
-The character
-.B $
-is used to introduce parameter substitution.
-Note that the results of such
-substitution are quoted from all
-further substitution.
-.PP
-.PD 0
-.RS
-.TP
-\fB${\fP\fIparameter\^\fP\fB}\fP
-The value, if any, of the parameter is substituted.
-The braces are required when
-.I parameter
-is followed by a letter, digit, or underscore
-that is not to be interpreted as part of its name
-or when a named parameter is subscripted.
-If
-.I parameter
-is one or more digits then it is a positional parameter.
-.I parameter
-may be followed by zero or more of any of the modifiers allowed in the
-history mechanism except \fBq\fP and \fBx\fP.
-.TP
-\fB$*\fP
-All the positional
-parameters, starting with
-.BR $1 ,
-are substituted.
-.TP
-\fB${\fP\fIparameter\^\fP\fB:\-\fP\fIword\^\fP\fB}\fP
-If
-.I parameter
-is set and is non-null then substitute its value;
-otherwise substitute
-.IR word .
-.TP
-\fB${\fP\fIparameter\^\fP\fB:=\fP\fIword\^\fP\fB}\fP
-If
-.I parameter
-is not set or is null then set it to
-.IR word ;
-the value of the parameter is then substituted.
-Positional parameters may be assigned to
-in this way.
-.TP
-\fB${\fP\fIparameter\^\fP\fB:?\fP\fIword\^\fP\fB}\fP
-If
-.I parameter
-is set and is non-null then substitute its value;
-otherwise, print
-.I word
-and exit.
-If
-.I word
-is omitted then a standard message is printed.
-.TP
-\fB${\fP\fIparameter\^\fP\fB:+\fP\fIword\^\fP\fB}\fP
-If
-.I parameter
-is set and is non-null then substitute
-.IR word ;
-otherwise substitute nothing.
-.TP
-\fB${\fP\fIparameter\^\fP\fB#\fP\fIpattern\^\fP\fB}\fP
-.TP
-\fB${\fP\fIparameter\^\fP\fB##\fP\fIpattern\^\fP\fB}\fP
-If the shell
-.I pattern
-matches the beginning of the value of
-.IR parameter ,
-then the value of
-this substitution is the value of the
-.I parameter
-with the matched portion deleted;
-otherwise the value of this
-.I parameter
-is substituted.
-In the first form the smallest matching pattern is deleted and in the
-second form the largest matching pattern is deleted.
-.TP
-\fB${\fP\fIparameter\^\fP\fB%\fP\fIpattern\^\fP\fB}\fP
-.TP
-\fB${\fP\fIparameter\^\fP\fB%%\fP\fIpattern\^\fP\fB}\fP
-If
-the shell
-.I pattern
-matches the end of the value of
-.IR parameter ,
-then the value of
-this substitution is the value of the
-.I parameter
-with the matched part deleted;
-otherwise substitute the value of
-.IR parameter .
-In the first form the smallest matching pattern is deleted and in the
-second form the largest matching pattern is deleted.
-.PD
-.RE
-.PP
-In the above,
-.I word
-is not evaluated unless it is
-to be used as the substituted string,
-so that, in the following example,
-pwd
-is executed only if
-.B d
-is not set or is null:
-.RS
-.PP
-.B "echo \|${d:\-\^$(\^pwd\^)\^}"
-.RE
-.PP
-If the
-.B :
-is omitted from the above expressions,
-then \fBzsh\fP only checks whether
-.I parameter
-is set or not.
-.PP
-The following parameters are automatically set by \fBzsh\fP:
-.RS
-.PD 0
-.TP 10
-.B #
-The number of positional parameters in decimal.
-.TP
-.B \-
-Flags supplied to \fBzsh\fP on invocation or by
-the
-.B setopt
-command.
-.TP
-.B ?
-The decimal value returned by the last executed command.
-.TP
-.B $
-The process number of this shell.
-.TP
-.B !
-The process number of the last background command invoked.
-.TP
-.B EUID
-The effective user id of the shell process.
-.TP
-.B HOSTTYPE
-A string corresponding to the architecture \fBzsh\fP is running on.
-.TP
-.B PPID
-The process number of the parent of this shell.
-.TP
-.B PWD
-The present working directory set by the
-cd
-command.
-.TP
-.B RANDOM
-Each time this parameter is referenced, a random integer,
-uniformly distributed between 0 and 32767, is generated.
-The sequence of random numbers can be initialized by assigning
-a numeric value to
-RANDOM.
-.TP
-.B LINENO
-In a script, the current line number.
-.TP
-.B REPLY
-This parameter is set by the
-.B select
-statement and by
-the
-.B read
-builtin when no arguments are supplied.
-.TP
-.B SECONDS
-Each time this parameter is referenced, the number of
-seconds since shell invocation is returned.
-If this parameter is
-assigned a value, then the value returned upon reference will
-be the value that was assigned plus the number of seconds since the assignment.
-.TP
-.B TCxx
-The string or value corresponding to the termcap entry \fBxx\fP.
-.TP
-.B UID
-The user id of the shell process.
-.TP
-.B USERNAME
-The name corresponding to the real user id of this shell process.
-.TP
-.B VERSION
-The version number of this \fBzsh\fP.
-.PD
-.RE
-.PP
-The following parameters are used by \fBzsh\fP:
-.RS
-.PD 0
-.TP
-.B ARGV0
-If placed in the environment for a command, \fBzsh\fP
-will use its value as argv[0] for the \fBexec\fP(2) call
-rather than the specified command name.
-.TP
-.B CDPATH
-The search path for the
-cd
-command.
-.TP
-.B FCEDIT
-The default editor name for the
-.B fc
-command.
-.TP
-.B IFS
-Internal field separators,
-normally
-.BR space ,
-.BR tab ,
-and
-.B newline
-that is used to separate command words which result from
-command or parameter substitution
-and for separating words with the 
-.B read
-builtin.
-.TP
-.B HISTSIZE
-If this parameter is set when \fBzsh\fP is invoked, then
-the number of previously entered commands that
-are accessible by this shell
-will be greater than or equal to this number.
-The default is 128.
-.TP
-.B HOME
-The default argument (home directory) for the
-.B cd
-command.
-.TP
-.B MAIL
-If this parameter is set to the name of a mail file
-then \fBzsh\fP informs the user of arrival of mail
-in the specified file.
-.TP
-.B MAILCHECK
-This variable specifies how often (in seconds) \fBzsh\fP
-will check for changes in the modification time
-of any of the files specified by the
-.B MAIL
-parameter.
-The default value is 60 seconds.
-When the time has elapsed
-\fBzsh\fP will check before issuing the next prompt.
-.TP
-.B PROMPT
-The value of this parameter is expanded
-much like printf(3S),
-using "%<char>" to signal an expansion.
-The available sequences are:
-.RS
-.PP
-.TP
-.B %d \fPor\fB %/
-The current working directory.
-.TP
-.B %\(ap
-The current working directory; if it starts with $HOME, that part is 
-replaced by a \(ap.
-.TP
-.B %c \fPor\fB %.
-The trailing component of the current working directory.
-.TP
-.B %h \fPor\fB %!
-The current history event number.
-.TP
-.B %M
-The full machine hostname.
-.TP
-.B %m
-The hostname up to the first ".".
-.TP
-.BR %S\  ( %s )
-Start (stop) standout mode.
-.TP
-.BR %B\  ( %b )
-Start (stop) boldfacing mode.
-.TP
-.BR %U\  ( %u )
-Start (stop) underline mode.
-.TP
-.B %t \fPor\fB %@
-Current time of day, in 12-hour, am/pm format.
-.TP
-.B %T
-Current time of day, in 24-hour format. 
-.TP
-.B %n
-The user name (contents of \fB$USERNAME\fP).
-.TP
-.B %w
-The date in <Mon> dd format.
-.TP
-.B %W
-The date in mm/dd/yy format.
-.TP
-.B %D
-The date in yy-mm-dd format.
-.TP
-.B %l
-The line (tty) the user is logged on.
-.TP
-.B %#
-A `#' if \fBzsh\fP is run as a root shell, a `%' if not.
-.TP
-.B %%
-A single %.
-.RE
-.PD
-.PP
-.PD 0
-.B PROMPT2
-Secondary prompt string,
-expanded in the
-same manner as
-.BR PROMPT .
-.TP
-.B PROMPT3
-Selection prompt string
-used within a
-.B select
-loop, by default
-.RB `` "#? \|" ''.
-.TP
-.B SHELL
-The pathname of the user's shell.
-.TP
-.B WATCH
-A colon-separated list of users to be checked for login and logout
-activity.  If set to `all', the login and logout activity
-of all users will be monitored.
-.TP
-.B WATCHFMT
-The format of the login/logout reports.
-The following
-sequences are available for the format specification:
-.RS
-.PP
-.TP
-.B %n
-The name of the user that logged in/out.
-.TP
-.B %a
-The observed action, i.e. "logged on" or "logged off".
-.TP
-.B %l
-The line (tty) the user is logged on.
-.TP
-.BR %S\  ( %s )
-Start (stop) standout mode.
-.TP
-.BR %B\  ( %b )
-Start (stop) boldfacing mode.
-.TP
-.BR %U\  ( %u )
-Start (stop) underline mode.
-.TP
-.B %M
-The full hostname of the remote host.
-.TP
-.B %m
-The hostname up to the first ".". If only 
-the ip address is available or the utmp 
-field contains the name of an X-windows 
-display, the whole name is printed.
-.TP
-.B %t or %@
-The time, in 12-hour, am/pm format (logout 
-time is approximated if unavailable).
-.TP
-.B %T
-The time, in 24-hour format.
-.TP
-.B %w
-The date in <Mon> dd format.
-.TP
-.B %W
-The date in mm/dd/yy format.
-.TP
-.B %D
-The date in yy-mm-dd format.
-.RE
-.PD
-.PP
-If
-.B WATCHFMT
-is not set, the format defaults to
-"%n has %a %l from %m."
-.RE
-.PP
-\fBzsh\fP gives default values to
-\fBPATH\fP, \fBPROMPT\fP, \fBPROMPT2\fP, \fBPROMPT3\fP,
-and \fBIFS\fP,
-while
-.B SHELL
-and
-.B MAIL
-are
-not set at all by \fBzsh\fP (although
-.B HOME
-.I is
-set by
-.IR login (1)).
-On some systems
-.B MAIL
-and
-.B SHELL
-are also
-set by
-.IR login (1)).
-.B \fBzsh\fP
-expands the value of
-.B HOME
-so that it does not contain any symbolic links.
-.SS Arithmetic Substitution
-An arithmetic expression of the form
-.B $[...]
-is replaced by the value of the arithmetic expression
-within the brackets.  See
-.B
-Arithmetic Evaluation
-below.
-.SS Command Substitution
-The standard output from a command of the form
-.B $(...)
-or
-.B `...`
-may be used as part or all
-of a word;
-trailing newlines are removed.
-In the second (archaic) form, the string between the quotes is processed
-for special quoting characters before the command is executed. (See
-.BR Quoting ).
-The command substitution
-\^\fB$(\^cat\ file\^)\fP\^
-can be replaced by the equivalent but faster
-\^\fB$(\^<file\^)\fP\^.
-.SS Brace Expansion
-A string of the form
-.B {str,str,...}
-is expanded to each string in the comma-separated list in the
-specified order.  This construct may be nested.
-.PP
-A five-character string of the form
-.B {x\-y}
-is expanded to each character in the range from x to y, inclusive.
-.SS Filename Substitution
-After alias substitution is performed, each word
-is checked to see if it begins with an unquoted
-.B \(ap 
-or
-.BI = .
-If it begins with a
-.BI \(ap ,
-then the word up to a
-.B /
-is checked to see if it matches a user name on the system.
-If a match is found, the
-.B \(ap
-and the matched login name is replaced by the
-login directory of the matched user.
-A
-.B \(ap
-by itself, or in front of a
-.BR / ,
-is replaced by \fB$HOME\fP.
-A
-.B \(ap
-followed by a
-.B +
-or
-.B \-
-is replaced by \fB$PWD\fP and \fB$OLDPWD\fP respectively.
-.PP
-If the word begins with a
-.B =
-followed by a letter, the word
-is replaced by the full pathname of the command name
-following the
-.BI = .
-Thus
-.BI = foo
-is a shorthand for
-\^\fB$(\^which\ \fIfoo\fB\^)\fR\^.
-If the word is of the form
-.B =number
-or
-.BR =number/... ,
-then the first part of the word is replaced
-by the appopriate element of the directory stack,
-corresponding to the specified number.
-The stack is viewed as zero-based, i.e.,
-.B =0
-is the same as
-.BR $PWD .
-As a special
-case,
-.B =\-
-is recognized as indicating the last directory in the stack.
-.PP
-All of the above forms of filename substitution
-may be followed by any of the modifiers allowed in the
-history mechanism except \fBq\fP and \fBx\fP.
-.SS Filename Generation
-Following substitution, each command
-.I word
-is scanned for
-the characters
-.BR \(** ,
-.BR ? ,
-.BR [ ,
-.BR ^ ,
-.BR # ,
-.BR < ,
-and
-.BR | .
-If one of these characters appears
-then the word is regarded as a
-.IR pattern .
-The word is replaced with alphabetically sorted filenames that match the pattern.
-If no filename is found that matches the pattern, then
-the word is left unchanged.
-When a
-.I pattern
-is used for filename generation,
-the character
-.B .
-at the start of a filename
-or immediately following a
-.BR /
-must be matched explicitly, unless the 
-.B globdots
-option is set.
-Also, the
-.B /
-character itself must be matched explicitly.
-In filename generation, no pattern matches "." or "..".
-In other instances of pattern matching the
-.B /
-and
-.B .
-are not treated specially.
-.PP
-.PD 0
-.RS
-.TP
-.B \(**
-Matches any string, including the null string.
-.TP
-.B ?
-Matches any single character.
-.TP
-.BR [ \^.\|.\|.\^ ]
-Matches any one of the enclosed characters.
-A pair of characters separated by
-.B \-
-matches any
-character lexically between the pair, inclusive.
-If the first character following the opening "["
-is a "^" then any character not enclosed is matched.
-A
-.B \-
-can be included in the character set by putting it as the
-first or last character.
-.TP
-.B <...>
-Matches a numeric field.  A pattern of the form
-.BR <x\-y> ,
-where x and y are decimal integers, matches any number between
-x and y inclusive.  Patterns of the form
-.B <x\->
-and
-.B <\-y>
-match any number greater than or equal to x, and less than or
-equal to y, respectively.  The degenerate
-.B <\->
-or simply
-.B <>
-matches any number.  Note that a
-.B <...>
-pattern eats up
-any numbers it encounters; thus
-.B foo<1\-5>7
-does not match
-"foo27", even though 2 is between 1 and 5.
-.TP
-.B x#
-Matches zero or more occurrences of the pattern x.
-.TP
-.B x##
-Matches one or more occurrences of the pattern x.
-.TP
-.B ^pattern
-Matches anything but the specified pattern.
-.TP
-.B foo|bar
-Matches either foo or bar.
-.PD
-.RE
-.PP
-Parentheses may be used for grouping.  Note that the \fB|\fP character
-must be within parentheses, so that the lexical analyzer does
-not think it is a pipe character.  Also note that "/" has a
-higher precedence than "^"; that is:
-.RS
-.PP
-ls
-.BI ^ foo / bar
-.RE
-.PP
-will search directories in "." except "./foo" for a file named bar.
-.PP
-A pathname component of the form
-.BI ( foo /)#
-matches a path consisting of zero or more directories
-matching the pattern foo.
-As a shorthand,
-.B ..../
-is equivalent to
-.BR (*/)# .
-Thus:
-.RS
-.PP
-ls
-.BI (*/)# bar
-.RE
-.PP
-or
-.RS
-.PP
-ls
-.BI ..../ bar
-.RE
-.PP
-does a recursive directory search for files named bar.
-.PP
-If used for filename generation, a pattern may end in a qualifier
-of the form \fB(X)\fP or \fB(^X)\fP, where \fBX\fP is a character that
-specifies which filenames that otherwise match the given pattern
-will be inserted in the argument list.  \fBX\fP may be any one of the
-following:
-.PD 0
-.RS
-.TP
-.B /
-directories
-.TP
-.B .
-plain files
-.TP
-.B @
-symbolic links
-.TP
-.B =
-sockets
-.TP
-.B <
-named pipes (FIFOs)
-.TP
-.B *
-executable files (0100)
-.TP
-.B %
-device files (character or block special)
-.TP
-.B r
-readable files (0400)
-.TP
-.B w
-writeable files (0200)
-.TP
-.B x
-executable files (0100, same as *)
-.TP
-.B R
-world-readable files (0004)
-.TP
-.B W
-world-writeable files (0002)
-.TP
-.B X
-world-executable files (0001)
-.PD
-.RE
-.PP
-Thus:
-.RS
-.PP
-ls
-.B
-*(%)
-.RE
-.PP
-lists all device files in the current directory,
-and
-.RS
-.PP
-ls
-.B /tmp/foo*(^@)
-.RE
-.PP
-lists all files beginning with the string
-"foo" in /tmp, ignoring symlinks.  A "/" at the end of a pattern
-is equivalent to "(/)".
-.SS Quoting
-Each of the
-.I metacharacters
-listed above (See
-.I Definitions
-above)
-has a special meaning to \fBzsh\fP
-and causes termination of a word unless quoted.
-A character may be
-.I quoted
-(that is, made to stand for itself)
-by preceding
-it with a
-.BR \e .
-The pair
-.B \enewline
-is ignored.
-All characters enclosed between a pair of single quote marks (\^\fB\(fm\^\(fm\fP\^),
-are quoted.
-A single quote cannot appear within single quotes.
-Inside double quote marks
-(\fB"\^"\fP),
-parameter and command substitution occurs and
-.B \e
-quotes the characters
-.BR \e ,
-.BR \f(CW`\fP ,
-\fB"\fP,
-and
-.BR $ .
-Inside grave quote marks
-.Pn ( `` )
-.B \e
-quotes the characters
-.BR \e ,
-` ,
-and
-.PP $ .
-If the grave quotes occur within double quotes then
-.BR \e
-also quotes the character
-\fB"\fP.
-.PP
-The special meaning of reserved words or aliases can be removed by quoting any
-character of the reserved word.
-The recognition of function names or builtin names listed below
-cannot be altered by quoting them.
-.SS Arithmetic Evaluation
-An ability to perform integer arithmetic
-is provided with the builtin
-.BR let .
-Evaluations are performed using
-.I long
-arithmetic.
-Constants are of the form
-[\fIbase\fB#\^\fR]\fIn\^\fP
-where
-.I base
-is a decimal number between two and thirty-six
-representing the arithmetic base
-and
-.I n
-is a number in that base.
-If
-.I base
-is omitted
-then base 10 is used.
-.PP
-An arithmetic expression uses nearly the same syntax, precedence, and
-associativity of
-expressions in C.
-The following operators are supported (listed in decreasing order
-of precedence):
-.PP
-.PD 0
-.RS
-.TP
-.B + \- ! \(ap ++ \-\-
-unary plus/minus, logical NOT, complement, {pre,post}{in,de}crement
-.TP
-.B &
-logical AND
-.TP
-.B ^
-logical XOR
-.TP
-.B |
-logical OR
-.TP
-.B * / %
-multiplication, division, remainder
-.TP
-.B + \-
-addition, subtraction
-.TP
-.B << >>
-logical shift left, shift right
-.TP
-.B < > <= >=
-comparison
-.TP
-.B == !=
-equality and inequality
-.TP
-.B &&
-boolean AND
-.TP
-.B || ^^
-boolean OR, XOR
-.TP
-.B ? :
-ternary operator
-.TP
-.B
-= += \-= *= /= %= &= ^= |= <<= >>= &&= ||= ^^=
-assignment
-.TP
-.B ,
-comma operator
-.PD
-.RE
-.PP
-The operators &&, ||, &&=, and ||= are short-circuiting,
-and only one of the latter two expressions in a ternary operator
-is evaluated.  Note the precedence of the logical AND, OR,
-and XOR operators.
-.PP
-Named parameters can be referenced by name within an arithmetic expression
-without using the parameter substitution syntax.
-.PP
-An internal integer representation of a named parameter
-can be specified with the
-.B integer
-builtin.
-Arithmetic evaluation is performed on the value of each
-assignment to a named parameter declared integer
-in this manner.
-.PP
-Since many of the arithmetic operators require
-quoting, an alternative form of the
-.B let
-command is provided.
-For any command which begins with a
-.BR (( ,
-all the characters until a matching
-.B ))
-are treated as a quoted expression.
-More precisely,
-.BR (( .\|.\|. ))
-is equivalent to
-.B let
-\fB"\fP\|.\|.\|.\fB"\fP.
-.SS Prompting
-When used interactively,
-\fBzsh\fP prompts with the value of
-.B PROMPT
-before reading a command.
-If at any time a newline is typed and further input is needed
-to complete a command, then the secondary prompt
-(that is, the value of
-.BR PROMPT2 )
-is issued.
-.SS Input/Output
-Before a command is executed, its input and output
-may be redirected using a special notation interpreted by \fBzsh\fP.
-The following may appear anywhere in a simple-command
-or may precede or follow a
-.I command
-and are
-.I not
-passed on to the invoked command.
-Substitution occurs before
-.I word
-is used except as noted below.
-If the result of substitution on
-.I word
-produces more than one filename,
-redirection occurs for each
-separate filename in turn.
-.TP 14
-.BI < word
-Use file
-.I word
-as standard input (file descriptor 0).
-.TP
-.BI > word
-Use file
-.I word
-as standard output (file descriptor 1).
-If the file does not exist then it is created.
-If the file exists, and the
-.B clobber
-option is not set,
-this causes an error;
-otherwise, it is truncated to zero length.
-.TP
-.BI >! " word"
-Same as
-.BR > ,
-except that the file is truncated to zero length
-if it exists, even if
-.B clobber
-is not set.
-.TP
-.BI >> word
-Use file
-.I word
-as standard output.
-If the file exists then output is appended to it.
-If the file does not exist, and the
-.B clobber
-option is not set,
-this causes an error;
-otherwise, the file is created.
-.TP
-.BI >>! " word"
-Same as
-.BR >> ,
-except that the file is created if it does not
-exist, even if
-.B clobber
-is not set.
-.TP
-.BI << word
-The shell input is read up to a line that is the same as
-.IR word ,
-or to an end-of-file.
-No parameter substitution, command substitution or
-filename generation is performed on
-.IR word .
-The resulting document,
-called a
-.IR here-document ,
-becomes
-the standard input.
-No interpretation
-is placed upon the characters of the document.
-.TP
-.BI <& digit
-The standard input is duplicated from file descriptor
-.I digit
-(see
-.IR dup (2)).
-Similarly for the standard output using
-.BR >&
-.IR digit .
-.TP
-.BI >& word
-Same as
-.BI > word
-.B 2>&1 .
-.TP
-.BI >>& word
-Same as
-.BI >> word
-.B 2>&1 .
-.TP
-.B <&\-
-The standard input is closed.
-Similarly for the standard output using
-.BR >&\- .
-.TP
-.BI <&! " digit"
-Same as
-.B <&\-
-.BI <& digit .
-.TP
-.BI >&! " digit"
-Same as
-.B >&\-
-.BI >& digit .
-.TP
-.B <&p
-The input from the coprocess is moved to standard input.
-.TP
-.B >&p
-The output to the coprocess is moved to standard output.
-.PP
-If one of the above is preceded by a digit,
-then the
-file descriptor number referred to is that specified
-by the digit
-(instead of the default 0 or 1).
-For example:
-.RS
-.PP
-\&.\|.\|. \|2>&1
-.RE
-.PP
-means file descriptor 2 is to be opened
-for writing as a duplicate
-of file descriptor 1.
-.PP
-The order in which redirections are specified is significant.
-\fBzsh\fP evaluates each redirection in terms of the
-.RI ( "file descriptor" ", " file )
-association at the time of evaluation.
-For example:
-.RS
-.PP
-\&.\|.\|. \|1>\fIfname\^\fP 2>&1
-.RE
-.PP
-first associates file descriptor 1 with file
-.IR fname .
-It then associates file descriptor 2 with the file associated with file
-descriptor 1 (that is,
-.IR fname ).
-If the order of redirections were reversed, file descriptor 2 would be associated
-with the terminal (assuming file descriptor 1 had been) and then file descriptor
-1 would be associated with file
-.IR fname .
-.PP
-If the user tries to open a file descriptor for writing more than once,
-\fBzsh\fP opens the file descriptor as a pipe to a process that copies
-its input to all the specified outputs, similar to tee(1).  Thus:
-.RS
-.PP
-.B date >foo >bar
-.RE
-.PP
-writes the date to two files, named "foo" and "bar".
-Note that a pipe is an implicit indirection; thus
-.RS
-.PP
-.B date >foo | cat
-.RE
-.PP
-writes the date to the file "foo", and also pipes it to cat.
-.PP
-If the user tries to open a file descritor for reading more than once,
-\fBzsh\fP opens the file descriptor as a pipe to a process that copies
-all the specified inputs to its output in the order
-specified, similar to cat(1).  Thus
-.RS
-.PP
-.B sort <foo <fubar
-.RE
-.PP
-or even
-.RS
-.PP
-.B sort <f{oo,ubar}
-.RE
-.PP
-is equivalent to "cat foo bar | sort".  Note that
-a pipe is in implicit indirection; thus
-.RS
-.PP
-.B cat bar | sort <foo
-.RE
-.PP
-is equivalent to "cat bar foo | sort" (note the order of the inputs).
-.PP
-If a simple command consists of one or more redirection operators
-and zero or more parameter assignments, but no command name,
-the command \fBcat\fP is assumed.  Thus
-.RS
-.PP
-.B < file
-.RE
-.PP
-prints the contents of \fBfile\fP.
-.PP
-If a command is followed by
-.B &
-and job control is not active,
-then the default standard input
-for the command
-is the empty file
-.BR /dev/null .
-Otherwise, the environment for the execution of a command contains the
-file descriptors of the invoking shell as modified by
-input/output specifications.
-.SS Environment
-The
-.I environment
-(see
-.IR environ (7))
-is a list of name-value pairs that is passed to
-an executed program in the same way as a normal argument list.
-The names must be
-.I identifiers
-and the values are character strings.
-\fBzsh\fP interacts with the environment in several ways.
-On invocation, \fBzsh\fP scans the environment
-and creates a
-parameter
-for each name found,
-giving it the corresponding value and marking it exported.
-Executed commands inherit the environment.
-If the user modifies the values of these
-parameters
-or creates new ones,
-using the
-.B export
-command they become part of the
-environment.
-The environment seen by any executed command is thus composed
-of any name-value pairs originally inherited by \fBzsh\fP,
-whose values may be modified by the current shell,
-plus any additions
-which must be noted in
-.B export
-commands.
-.PP
-The environment for any
-.I simple-command
-or function
-may be augmented by prefixing it with one or more parameter assignments.
-A parameter assignment argument is a word of the form
-.IR identifier=value .
-Thus:
-.RS
-.PP
-TERM=450 \|cmd \|args				and
-.br
-(export \|TERM; \|TERM=450; \|cmd \|args)
-.RE
-.PP
-are equivalent (as far as the above execution of
-.I cmd
-is concerned).
-.PP
-If the
-.B keyword
-flag is set,
-.I all
-parameter assignment arguments are placed in the environment,
-even if they occur after the command name.
-.SS Function
-.PP
-The
-.B function
-reserved word, described in the
-.I Commands
-section above,
-is used to define shell functions.
-Shell functions are read in and stored internally.
-Alias names are resolved when the function is read.
-Functions are executed like commands with the arguments
-passed as positional parameters.
-(See
-.I Execution
-below).
-.PP
-Functions execute in the same process as the caller and
-share all files
-and present working directory with the
-caller.
-A trap on
-.B EXIT
-set inside a function
-is executed after the function completes in the environment
-of the caller.
-.PP
-The builtin
-.B return
-is used to return
-from function calls.
-Errors within functions return control to the caller.
-.PP
-Function identifiers
-can be listed with the
-.B function
-builtin.
-Functions can be undefined with the
-.B unfunction
-builtin.
-.PP
-The following functions, if defined, have special meaning to \fBzsh\fP:
-.PP
-.PD 0
-.RS
-.TP
-\fBchpwd\fP
-Executed whenever the current working directory is changed.
-.TP
-\fBprecmd\fP
-Executed before each prompt.
-.TP
-\fBperiodic\fP
-If the parameter
-.B PERIOD
-is set, this function is executed every
-.B PERIOD
-minutes, just before a prompt.
-.TP
-\fBTRAPxxx\fP
-If defined and non-null,
-this function will be executed whenever \fBzsh\fP 
-catches a signal \fBSIGxxx\fP, where \fBxxx\fP is a signal
-name as specified for the \fBkill\fP builtin (see below).
-In addition, \fBTRAPERR\fP is executed whenever a command has a non-zero
-exit status, \fBTRAPDEBUG\fP is executed after each command, and
-\fBTRAPEXIT\fP
-is executed when \fBzsh\fP exits,
-or when the current function exits if defined
-inside a function.
-If a function of this form is defined and null,
-\fBzsh\fP and processes spawned by it will ignore \fBSIGxxx\fP.
-.PD
-.RE
-.SS Jobs
-.PP
-If the
-.B monitor
-option of the
-.B set
-command is turned on,
-an interactive shell associates a \fIjob\fR with each pipeline.
-It keeps
-a table of current jobs, printed by the
-.B jobs
-command, and assigns them small integer numbers.
-When a job is started asynchronously with
-.BR & ,
-\fBzsh\fP prints a line which looks
-like:
-.PP
-.DT
-	[1] 1234
-.PP
-indicating that the job which was started asynchronously was job number
-1 and had one (top-level) process, whose process id was 1234.
-.PP
-If you are running a job and wish to do something else you may hit the key
-\fB^Z\fR (control-Z) which sends a STOP signal to the current job.
-\fBzsh\fP will then normally indicate that the job has been `suspended',
-and print another prompt.
-You can then manipulate the state of this job,
-putting it in the background with the
-.B bg
-command, or run some other
-commands and then eventually bring the job back into the foreground with
-the foreground command
-.BR fg .
-A \fB^Z\fR takes effect immediately and
-is like an interrupt in that pending output and unread input are discarded
-when it is typed.
-.PP
-A job being run in the background will suspend if it tries to read
-from the terminal.
-Background jobs are normally allowed to produce output,
-but this can be disabled by giving the command ``stty tostop''.
-If you set this
-tty option, then background jobs will suspend when they try to produce
-output like they do when they try to read input.
-.PP
-There are several ways to refer to jobs in \fBzsh\fP.
-A job can be referred to by the process id of any process of the job
-or by one of the following:
-.PD 0
-.TP
-.BI % number
-The job with the given number.
-.TP
-.BI % string
-Any job whose command line begins with
-.IR string .
-.TP
-.BI %? string
-Any job whose command line contains
-.IR string .
-.TP
-.BI %%
-Current job.
-.TP
-.BI %+
-Equivalent to
-.BR %% .
-.TP
-.BI %\-
-Previous job.
-.PD
-.PP
-\fBzsh\fP learns immediately whenever a process changes state.
-It normally informs you whenever a job becomes blocked so that
-no further progress is possible.  If
-.B notify
-is not set, it waits until
-just before it prints
-a prompt before it informs you.
-.PP
-When the monitor mode is on, each background job that completes
-triggers any trap set for
-.BR CHLD .
-.PP
-When you try to leave \fBzsh\fP while jobs are running or suspended, you will
-be warned that `You have suspended (running) jobs.'
-You may use the
-.B jobs
-command to see what they are.
-If you do this or immediately try to
-exit again, \fBzsh\fP will not warn you a second time; the suspended
-jobs will be terminated, and the running jobs will be sent
-a \fBSIGHUP\fP signal.
-To avoid having \fBzsh\fP terminate the running jobs, either
-use the \fBnohup\fP(1) command or the \fBdisown\fP builtin (see below).
-.SS Signals
-The INT and QUIT signals for an invoked
-command are ignored if the command is followed by
-.B &
-and job
-.B monitor
-option is not active.
-Otherwise, signals have the values
-inherited by \fBzsh\fP from its parent
-(but see the \fBTRAPxxx\fP special function above).
-.SS Execution
-Each time a command is executed, the above substitutions
-are carried out.
-If the command name matches one
-of the
-.I builtins
-listed below,
-it is executed within the
-current shell process.
-Next, the command name is checked to see if
-it matches one of the user defined functions.
-If it does,
-the positional parameters are saved
-and then reset to the arguments of the
-.I function
-call.
-When the
-.I function
-completes or issues a
-.BR return ,
-the positional parameter list is restored
-and any trap set on
-.B EXIT
-within the function is executed.
-The value of a
-.I function
-is the value of the last command executed.
-A function is also executed in the
-current shell process.
-If a command name is not a
-.I builtin
-or a user defined
-.IR function ,
-a process is created and
-an attempt is made to execute the command via
-.IR exec (2).
-.PP
-The shell parameter
-.B PATH
-defines the search path for
-the directory containing the command.
-Alternative directory names are separated by
-a colon.
-The default path is
-.B /bin:/usr/bin:
-(specifying
-.BR /bin ,
-.BR /usr/bin ,
-and the current directory
-in that order).
-The current directory can be specified by
-two or more adjacent colons, or by a colon
-at the beginning or end of the path list.
-If the command name contains a \fB/\fP then the search path
-is not used.
-Otherwise, each directory in the path is
-searched for an executable file.
-.PP
-Whenever \fBzsh\fP executes an external command, it gives
-control of the tty to the command.  If the command
-completes with a zero return code, \fBzsh\fP does not reset
-the tty; otherwise, the tty modes are reset to what they were
-before the command was executed.  If a process is suspended,
-\fBzsh\fP saves the state of the tty and resets the tty modes;
-if the process is later restarted, the tty modes are restored
-to what they were when the process was suspended.
-.SS Command Re-entry.
-The text of the last
-.B HISTSIZE
-(default 128)
-commands entered from a terminal device
-is saved in memory.
-The builtin
-.B fc
-is used to list or
-edit a portion of this file.
-The portion of the file to be edited or listed can be selected by
-number or by giving the first character or
-characters of the command.
-A single command or range of commands can be specified.
-If you do not specify an editor program as
-an argument to
-.B fc
-then the value of the parameter
-.B FCEDIT
-is used.
-If
-.B FCEDIT
-is not defined then
-.B /usr/ucb/vi
-is used.
-The edited command(s) is printed and re-executed upon
-leaving the editor.
-The editor name
-.B \-
-is used to skip the editing phase and
-to re-execute the command.
-In this case a substitution parameter of the form
-\fIold\fP\fB=\fP\fInew\fP
-can be used to modify the command before execution.
-For example, if
-.B r
-is aliased to
-.B \(fmfc \-e \-\(fm
-then typing
-`\fBr bad=good c\fP'
-will re-execute the most recent command which starts with the letter
-.BR c ,
-replacing the first occurrence of the string
-.B bad
-with the string
-.BR good .
-.SS Readline
-This is the library that handles reading input when using an interactive
-shell.
-By default, the line editing commands
-are similar to those of Emacs.
-A vi-style line editing interface is also available.
-.PP
-In this section, the Emacs\-style notation is used to denote
-keystrokes.  Control keys are denoted by C\-\fIkey\fR, e.g. C\-n
-means Control\-N.  Similarly, 
-.I meta
-keys are denoted by M\-\fIkey\fR, so M\-x means Meta\-X.  (On keyboards
-without a 
-.I meta
-key, M\-\fIx\fP means ESC \fIx\fP, i.e. press the Escape key
-then the
-.I x
-key.
-The combination M\-C\-\fIx\fP means ESC\-Control\-\fIx\fP,
-or press the Escape key
-then hold the Control key while pressing the
-.I x
-key.)
-.PP
-You may change the default key\-bindings with an
-.B \(ap/.inputrc 
-file.  Other 
-programs that use this library may add their own commands and bindings.
-.PP
-For example, if you wanted to make M\-C\-u execute the command
-.IR universal\-argument ,
-then 
-in your
-.B \(ap/.inputrc
-file you would put:
-.RS
-.PP
-M\-Control\-u: universal\-argument
-.RE
-or
-.RS
-C\-Meta\-u: universal\-argument
-.RE
-.PP
-You can use the following names for characters: RUBOUT, DEL, ESC,
-NEWLINE, SPACE, RETURN, LFD, TAB.
-.PP
-You can start with a vi-like editing mode by placing
-.RS
-.PP
-set editing-mode vi
-.RE
-.PP
-in your 
-.B \(ap/.inputrc
-file.
-.PP
-You can have readline use a single line for display, scrolling the input
-between the two borders by placing
-.RS
-.PP
-set horizontal\-scroll\-mode On
-.RE
-.PP
-in your 
-.B \(ap/.inputrc
-file.
-.PP
-The following is a list of the names of the commands and the default
-key-strokes to get them.
-.SS Commands for Moving
-.PP
-.PD 0
-.TP
-.B beginning\-of\-line (C\-a)
-Move to the start of the current line.
-.TP
-.B end\-of\-line (C\-e)
-Move to the end of the line.
-.TP
-.B forward\-char (C\-f)
-Move forward a character.
-.TP
-.B backward\-char (C\-b)
-Move back a character.
-.TP
-.B forward\-word (M\-f)
-Move forward to the end of the next word.
-.TP
-.B backward\-word (M\-b)
-Move back to the start of this, or the previous, word.
-.TP
-.B clear\-screen (C\-l)
-Clear the screen leaving the current line at the top of the screen.
-.PD
-.SS Commands for Manipulating the History
-.PP
-.PD 0
-.TP
-.B accept\-line (Newline, Return)
-Accept the line regardless of where the cursor is.
-.TP
-.B previous\-history (C\-p)
-Fetch the previous command from the history list, moving back in
-the list.
-.TP
-.B next\-history (C\-n)
-Fetch the next command from the history list, moving forward in the
-list.
-.TP
-.B beginning\-of\-history (M\-<)
-Move to the first line in the history, the first line entered.
-.TP
-.B end\-of\-history (M\->)
-Move to the end of the input history, i.e., the line you are entering.
-.PD
-.SS Commands for Changing Text
-.PP
-.PD 0
-.TP
-.B delete\-char (C\-d)
-Delete the character under the cursor.  If the cursor is at the
-beginning of the line, and there are no characters in the line, and
-the last character typed was not C\-d, then return EOF.
-.TP
-.B backward\-delete\-char (Rubout)
-Delete the character behind the cursor.  A numeric arg says to kill
-the characters instead of deleting them.
-.TP
-.B quoted\-insert (C\-q, C\-v)
-Add the next character that you type to the line verbatim.  This is
-how to insert characters like C\-q, for example.
-.TP
-.B self\-insert (a,\ b,\ A,\ 1,\ !,\ ...)
-Insert the character typed.
-.TP
-.B transpose\-chars (C\-t)
-Drag the character before point forward over the character at point.
-Point moves forward as well.  If point is at the end of the line, then
-transpose the two characters before point.  Negative arguments don't work.
-.TP
-.B transpose\-words (M\-t)
-Drag the word behind the cursor past the word in front of the cursor
-moving the cursor over that word as well.
-.TP
-.B upcase\-word (M\-u)
-Uppercase the current (or following) word.  With a negative argument,
-do the previous word, but do not move point.
-.TP
-.B downcase\-word (M\-l)
-Lowercase the current (or following) word.  With a negative argument,
-do the previous word, but do not move point.
-.TP
-.B capitalize\-word (M\-c)
-Capitalize the current (or following) word.  With a negative argument,
-do the previous word, but do not move point.
-.PD
-.SS Killing and Yanking
-.PP
-.PD 0
-.TP
-.B kill\-line (C\-k)
-Kill the text from the current cursor position to the end of the line.
-This saves the killed text on the kill\-ring.  (see below)
-.TP
-.B backward\-kill\-line
-Kill backward to the beginning of the line.  This is normally unbound,
-in favor of \fBunix-line-discard\fP, which emulates the behavior of
-the standard Unix terminal driver.
-.TP
-.B kill\-word  (M\-d)
-Kill from the cursor to the end of the current word, or if between
-words, to the end of the next word.
-.TP
-.B backward\-kill\-word (M\-Rubout)
-Kill the word behind the cursor.
-.TP
-.B unix\-line\-discard (C\-u)
-Do what C\-u used to do in Unix line input.  We save the killed text on
-the kill\-ring, though.
-.TP
-.B unix\-word\-rubout (C\-w)
-Do what C\-w used to do in Unix line input.  The killed text is saved
-on the kill\-ring.  This is different than backward\-kill\-word because
-the word boundaries differ.
-.TP
-.B yank (C\-y)
-Yank the top of the kill ring into the buffer at point.
-.TP
-.B yank\-pop (M\-y)
-Rotate the kill\-ring, and yank the new top.  Only works following
-`yank' or `yank\-pop'.
-.PD
-.SS Arguments
-.PP
-.PD 0
-.TP
-.B digit\-argument (M\-0, M\-1, ..., M\-\-)
-Add this digit to the argument already accumulating, or start a new
-argument.  M\-\- starts a negative argument.
-.TP
-.B universal\-argument
-Do what C\-u does in 
-.I Emacs.
-By default, this is not bound to a key.
-.PD
-.SS Completing
-.PP
-.PD 0
-.TP
-.B complete (TAB)
-Perform substitution on the text before point.
-If no substitutions can be performed, attempt
-filename completion.
-If the text before point is a tilde followed by
-a word which is a prefix of one of the usernames
-in
-.BR \(ap/.zfriends ,
-substitute the text with the
-home directory of that user.
-.TP
-.B possible\-completions (M-?)
-List the possible completions of the text before point.
-.PD
-.SS Miscellaneous
-.PP
-.PD 0
-.TP
-.B abort (C\-g)
-Abort the current editing command and
-ring the terminal's bell.
-.TP
-.B do\-uppercase\-version (M\-a, M\-b, ...)
-Run the command that is bound to the uppercased key.
-.TP
-.B prefix\-meta (ESC)
-Metafy the next character typed.  This is for
-people without a meta key.  ESC f is equivalent to Meta\-f.
-.TP
-.B undo (C\-_)
-Incremental undo, separately remembered for each line.
-.TP
-.B revert\-line (M\-r)
-Undo all changes made to this line.  This is like typing the `undo'
-command enough times to get back to the beginning.
-.TP
-.B history\-expand (M\-Space)
-Perform history expansion on this line.
-.TP
-.B check\-spelling (M\-$)
-Check the spelling of the word before the point.
-.PD
-.SS Builtins
-The following simple-commands are executed in the shell process.
-Input/Output redirection is permitted.
-Unless otherwise indicated, the output is written on file descriptor 1
-and the exit status, when there is no syntax error, is zero.
-.PD
-.TP
-\fB:\fP [ \fIarg\^\fP .\|.\|. ]
-The command only expands parameters.
-.br
-.ne 2
-.TP
-\fB\|. \fIfile\fP
-Read commands from
-.IR file .
-The commands are executed in the current shell environment.
-The exit status is the exit status of the last command executed.
-.TP
-\fBalias\fP [ \fB\-a\fP ]  [ \fIname\fP [ \fIstr\^\fP .\|.\|. ] ]
-.B alias
-with no arguments prints the list of aliases
-on standard output.
-If
-.I name
-is supplied with no
-.IR str ,
-the alias associated with
-.I name
-is printed.
-Otherwise
-.I name
-is defined as an alias having the specified value.
-A trailing space in the value
-causes the next word to be checked for
-alias substitution.
-Unless the
-.B \-a
-flag is used, the alias will only be substituted with its value
-if it appears as a command word.
-.TP
-.PD 0
-\fBbg\fP [ \fIjob\fP ]
-.TP
-\fIjob\fP \fB&\fP
-.PD
-Puts the specified
-.I job
-into the background.
-The current job is put in the background
-if
-.I job
-is not specified.
-See
-.I Jobs
-for a description of the format of
-.IR job .
-.TP
-\fBbreak\fP [ \fIn\^\fP ]
-Exit from the enclosing
-.BR for
-.BR while
-.BR until
-or
-.B select
-loop, if any.
-If
-.I n
-is specified then break
-.I n
-levels.
-.TP
-\fBcontinue\fP [ \fIn\^\fP ]
-Resume the next iteration of the enclosing
-.BR for
-.BR while
-.BR until
-or
-.B select
-loop.
-If
-.I n
-is specified then resume at the
-.IR n -th
-enclosing loop.
-.TP
-.PD 0
-\fBcd\fP [ \fIarg\^\fP ]
-.TP
-\fBcd\fP \fIold\^\fP \fInew\^\fP
-.PD
-This command can be in either of two forms.
-In the first form it
-changes the current directory to
-.IR arg .
-If
-.I arg
-is
-.B \-
-the directory is changed to the previous
-directory.
-The shell
-parameter
-.B HOME
-is the default
-.IR arg .
-The parameter
-.B PWD
-is set to the current directory.
-The shell parameter
-.B CDPATH
-defines the search path for
-the directory containing
-.IR arg .
-Alternative directory names are separated by
-a colon.
-The default path is
-the current directory.
-If
-.I arg
-begins with a \fB/\fP then the search path
-is not used.
-Otherwise, each directory in the path is
-searched for
-.IR arg .
-.IP
-The second form of
-.B cd
-substitutes the string
-.I new
-for the string
-.I old
-in the current directory name,
-.B PWD
-and tries to change to this new directory.
-.TP
-\fBdirs\fP [ \fIdirs\fP .\|.\|. ]
-If no \fIdirs\fP are specified, prints the directory stack.
-Otherwise loads the directory stack with the arguments,
-which must be directory names, and puts \fB$PWD\fP at the top
-of the stack.
-.TP
-\fBdisown\fP [ \fIjob\fP .\|.\|. ]
-The specified jobs are removed from the job table.
-This means that the status of these jobs will no longer
-be monitored, and the user can exit safely from an interactive
-shell without sending a \fBSIGHUP\fP to these jobs.
-.TP
-\fBecho\fP [ \fB\-n\fP ] [ \fIarg\^\fP .\|.\|. ]
-Echos the arguments to the standard output.  Prints
-a final newline if the \fB\-n\fP flag is not specified.
-.TP
-\fBeval\fP [ \fIarg\^\fP .\|.\|. ]
-The arguments are read as input
-to the shell
-and the resulting command(s) executed.
-.TP
-\fBexit\fP [ \fIn\^\fP ]
-Causes the shell to exit
-with the exit status specified by
-.IR n .
-If
-.I n
-is omitted then the exit status is that of the last command executed.
-An end-of-file will also cause the shell to exit
-except for a
-shell which has the
-.I ignoreeof
-option (See
-.B setopt
-below) turned on.
-.TP
-\fBexport\fP [ \fIname\fP[\fB=\fP\fIvalue\^\fP] ] .\|.\|.
-The given
-.IR name s
-are marked for automatic
-export to the
-.I environment
-of subsequently-executed commands.
-.TP
-.PD 0
-\fBfc\fP [ \fB\-e\fP \fIename\^\fP \ ] [ \fB\-nlr\^\fP ] [ \fIold=new\fP .\|.\|. ] [ \fIfirst\^\fP [ \fIlast\^\fP ] ]
-.PD
-A range of commands from
-.I first
-to
-.I last
-is selected from the last
-.B HISTSIZE
-commands that were typed at the terminal.
-The arguments
-.I first
-and
-.I last
-may be specified as a number or as a string.
-A string is used to locate the most recent command starting with
-the given string.
-A negative number is used as an offset to the current command number.
-Any number of substitutions
-.I old=new
-are performed.
-If the flag
-.BR \-l ,
-is selected,
-the commands are listed on standard output.
-Otherwise, the editor program
-.I ename
-is invoked on a file containing these
-keyboard commands.
-If
-.I ename
-is not supplied, then the value of the parameter
-.B FCEDIT
-(default /usr/ucb/vi)
-is used as the editor.
-If
-.I ename
-is `\-', no editor is invoked.
-When editing is complete, the edited command(s)
-are executed.
-If
-.I last
-is not specified
-then it will be set to
-.IR first .
-If
-.I first
-is not specified
-the default is the previous command
-for editing and \-16 for listing.
-The flag
-.B \-r
-reverses the order of the commands and
-the flag
-.B \-n
-suppresses command numbers when listing.
-.TP
-.PD 0
-\fBfg\fP [ \fIjob\fP ]
-.TP
-\fIjob\fP
-.PD
-The
-specified
-.I job
-is brought to the foreground.
-Otherwise, the current job is
-brought into the foreground.
-See
-.I Jobs
-for a description of the format of
-.IR job .
-.TP
-\fBglob\fP \fIname\fP .\|.\|.
-Marks \fIname\fP, which must be a command name,
-for normal filename generation.
-See \fBnoglob\fP below.
-.TP
-\fBhash\fP \fIname\fP \fIfile\fP
-Adds an entry to the command hash table corresponding
-to \fIname\fP.  \fIfile\fP is an executable file to be run
-whenever \fIname\fP is specified in a simple command.
-.TP
-\fBinteger\fP \fIname\fP .\|.\|.
-The specified named parameters are marked for an internal
-integer representation.
-.TP
-\fBjobs\fP [ \fB\-lp\^\fP ] [ \fIjob\^\fP .\|.\|. ]
-Lists information about each given job; or all active jobs if
-.I job
-is omitted.
-The
-.B \-l
-flag lists process ids in addition to the normal information.
-The
-.B \-p
-flag causes only the process group to be listed.
-See
-.I Jobs
-for a description of the format of
-.IR job .
-.TP
-.PD 0
-\fBkill\fP [ \fB\-\fP\fIsig\^\fP ] \fIjob\^\fP .\|.\|.
-.TP
-\fBkill\fP \fB\-l\fP
-.PD
-Sends either the TERM (terminate) signal or the
-specified signal to the specified jobs or processes.
-Signals are either given by number or by names (as given in
-.BR /usr/include/signal.h ,
-stripped of the prefix ``SIG'').
-If the job is suspended, it will be send a CONT (continue) signal
-after the specified signal is delivered.
-The argument
-.I job
-can the process id of a process that is not a member of one of the
-active jobs.
-See
-.I Jobs
-for a description of the format of
-.IR job .
-In the second form,
-.BR "kill \-l" ,
-the signal numbers and names are listed.
-.TP
-\fBlet\fP \fIarg\^\fP .\|.\|.
-Each
-.I arg
-is a separate
-.IR "arithmetic expression"
-to be evaluated.
-See
-.I "Arithmetic Evaluation"
-above, for a description of arithmetic expression evaluation.
-The exit status is
-0 if the value of the last expression
-is non-zero, and 1 otherwise.
-.TP
-\fBlimit\fP [ \fB\-h\fP ] [ \fIresource\fP [ \fImax-use\fP ] ]
-.PD 0
-.TP
-.B "limit \-s"
-.PD
-.br
-Limit the consumption by any process the shell spawns,
-each not to exceed
-.I max-use
-on the specified
-.IR resource .
-If
-.I max-use
-is omitted, print the current limit; if
-.I resource
-is omitted, display all limits.
-.RS
-.TP
-.B \-h
-Use hard limits instead of the current limits.  Hard limits impose a
-ceiling on the values of the current limits.  Only the super-user may
-raise the hard limits.
-.LP
-.I resource
-is one of:
-.RS
-.TP 15
-.B cputime
-Maximum
-.B CPU
-seconds per process.
-.PD 0
-.TP
-.B filesize
-Largest single file allowed.
-.TP
-.B datasize
-Maximum data size (including stack) for the process.
-.TP
-.B stacksize
-Maximum stack size for the process.
-.TP
-.B coredumpsize
-Maximum size of a core dump (file).
-.TP
-.B descriptors
-Maximum value for a file descriptor.
-.PD
-.RE
-.LP
-.I max-use
-is a number, with an optional scaling factor, as follows:
-.RS
-.TP 15
-.IB n h
-Hours (for
-.BR cputime ).
-.PD 0
-.TP
-.IB n k
-.I n
-kilobytes. 
-This is the default for all but
-.BR cputime .
-.TP
-.IB n m
-.I n
-megabytes or minutes (for
-.BR cputime ).
-.TP
-.IB mm : ss
-Minutes and seconds (for
-.BR cputime ).
-.PD
-.RE
-.RE
-.IP
-If
-.B limit
-is invoked solely with the
-.B s
-option, the current limits are taken to apply
-to the parent shell as well as to all processes
-spawned by it.
-.TP
-.B log
-Inform the user of all users
-affected by
-.B WATCH
-whether they have been announced before or not.
-.TP
-\fBmostglob\fP \fIname\fP .\|.\|.
-Marks \fIname\fP, which must be a command name,
-for modified filename generation.  Whenever \fIname\fP
-is used as a command name in a simple command,
-filename generation is not performed on the first argument
-following the command name.
-If there are one or more initial arguments beginning with a
-dash (corresponding to option arguments), they and the
-first argument following them
-are not subject to filename generation.
-.TP
-\fBnoglob\fP \fIname\fP .\|.\|.
-Marks \fIname\fP, which must be a command name,
-for no filename generation.  Whenever \fIname\fP
-is used as a command name in a simple command,
-filename generation is not performed on its arguments.
-.TP
-.B popd [ \fB+\fIn\fP ]
-Pop the directory stack, and
-.BR cd s
-to the new top directory.
-The elements of the directory stack are numbered from 0 starting at the top.
-.RS
-.TP 8
-.BI + n
-Discard the
-.IR n 'th
-entry in the stack.
-.RE
-.HP
-.B pushd
-.RB [ +\c
-.IR n " |"
-.IR dir ]
-.br
-Push a directory onto the directory stack.
-With no arguments, exchange the top two elements,
-unless the option
-.B pushdtohome
-is set, in which case push the current directory
-onto the stack and change to \fB$HOME\fP.
-.RS
-.TP
-.BI + n
-Rotate the
-.IR n 'th
-entry to the top of the stack and
-.B cd
-to it.  If the option
-.B dextract
-is set, extract the
-.IR n 'th
-entry from the directory stack
-and
-.B cd
-to it.
-.PD 0
-.TP
-.I dir
-Push the current working directory onto the stack and change to
-.IR dir .
-.PD
-.RE
-.TP
-\fBpwd\fP
-Equivalent to
-\fBecho $PWD\fP.
-.TP
-\fBread\fP [ \fIname\fB?\fIprompt\^\fR ] [ \fIname\^\fP .\|.\|. ]
-The shell input mechanism.
-One line is read and
-is broken up into fields using the characters in
-.B IFS
-as separators.
-If
-.IR name
-is omitted then
-.B REPLY
-is used as the default
-.IR name.
-The exit status is 0 unless an end-of-file is encountered.
-If the first argument contains a
-.BR ? ,
-the remainder of this word is used as a
-.I prompt
-on standard error
-when the shell is interactive.
-The exit status is 0 unless an end-of-file is encountered.
-.TP
-\fBrehash\fP
-Rebuilds the command hash table.  This command is executed
-automatically whenever the value of \fB$PATH\fP is changed.
-.TP
-\fBreturn\fP [ \fIn\^\fP ]
-Causes a shell
-.I function
-to return
-to the invoking script
-with the return status specified by
-.IR n .
-If
-.I n
-is omitted then the return status is that of the last command executed.
-If
-.B return
-is invoked while not in a
-.I function
-or a
-\fB\|.\fP
-script,
-then it is the same as an
-.BR exit .
-.TP
-\fBsched\fP [+]hh:mm \fIcommand\fP
-Schedule a command for execution at a later time.
-.TP
-\fBset\fP [ \fIarg\fP .\|.\|. ]
-Assign the arguments to the positional parameters, in order.
-If no arguments are given, then the names and values of
-all named parameters are printed on the standard output.
-.TP
-\fBsetopt\fP [ \fB\(+-aefikmnsuvxABCDEFGHIJK1234567890\fP ] \
-[ \fIopt\fP .\|.\|. ]
-Sets the options by letter or by name.  If no options
-are specified, the current option settings are printed.
-Valid options are as follows:
-.RS
-.PD 0
-.TP 8
-.B allexport (\-a)
-All subsequent parameters that are defined are automatically exported.
-.TP 8
-.B errexit (\-e)
-If a command has a non-zero exit status,
-execute the
-.B ERR
-trap, if set,
-and exit.
-.TP 8
-.B norcs (\-f)
-\fBzsh\fP will not read the .zshrc, .zlogin, or .zlogout files.
-.TP 8
-.B keyword (\-k)
-All parameter assigment arguments are placed in the environment
-for a command, not just those that precede the command name.
-.TP 8
-.B interactive (\-i)
-This is an interactive shell.
-.TP 8
-.B monitor (\-m)
-Background jobs will run in a separate process group
-and a line will print upon completion.
-The exit status of background jobs is reported in a completion message.
-This flag is turned on automatically for
-interactive shells.
-.TP 8
-.B noexec (\-n)
-Read commands and check them for syntax errors, but do not execute them.
-.TP 8
-.B \-t
-Exit after reading and executing one command.
-.TP 8
-.B shinstdin (\-s)
-Read commands from the standard input rather than from a file.
-.TP 8
-.B nounset (\-u)
-Treat unset parameters as an error when substituting.
-.TP 8
-.B verbose (\-v)
-Print shell input lines as they are read.
-.TP 8
-.B xtrace (\-x)
-Print commands and their arguments as they are executed.
-.TP 8
-.B clobber (\-1)
-Permits \fB>\fP redirection to truncate existing files.
-Also allows \fB>>\fP redirection to create files.
-.TP 8
-.B nobadpattern (\-2)
-In filename generation, do not report an error
-when given a malformed pattern.
-Instead, pass the pattern unchanged
-as an argument.
-.TP 8
-.B nonomatch (\-3)
-In filename generation,
-do not report an error when pattern matches no filenames.
-Instead, pass the pattern unchanged
-as an argument.
-.TP 8
-.B globdots (\-4)
-In filename generation, do not require that an initial \fB.\fP
-be matched explicitly.
-.TP 8
-.B notify (\-5)
-Notify the user immediately when jobs are completed, rather
-than wait until just before issuing a prompt.  This is
-the default mode.
-.TP 8
-.B bgnice (\-6)
-All background jobs are run at a lower priority.  This is the
-default mode.
-.TP 8
-.B ignoreeof (\-7)
-The shell will not exit on end-of-file.  Either
-\fBexit\fP or \fBlogout\fP must be used.
-.TP 8
-.B markdirs (\-8)
-All directory names resulting from filename generation
-have a trailing / appended.
-.TP 8
-.B autolist (\-9)
-List possilities on an ambiguous completion.
-.TP 8
-.B correct (\-0)
-Automatically try to correct the spelling of commands.
-.TP 8
-.B dextract (\-A)
-See \fBpushd\fP above.
-.TP 8
-.B nobeep (\-B)
-Prevent the shell from beeping.
-.TP 8
-.B printexitvalue (\-C)
-If an interactive program exits non-zero, print the
-exit value.
-.TP 8
-.B pushdtohome (\-D)
-Make pushd with no arguments do the equivalent
-of \fBpushd \(ap\fP, like \fBcd\fP.
-.TP 8
-.B pushdsilent (\-E)
-Prevent \fBpushd\fP and \fBpopd\fP from printing
-the directory stack.
-.TP 8
-.B nullglob (\-G)
-If a pattern for filename generation does not match any
-filenames, delete it from the argument list rather than
-report an error.
-.TP 8
-.B rmstarsilent (\-H)
-Do not prompt the user before execution of `rm *'.
-.TP 8
-.B ignorebraces (\-I)
-Do not perform brace expansion.
-.TP 8
-.B cdablevars (\-J)
-If a named parameter (without the \fB$\fP) is specified
-to the \fBcd\fP, \fBpushd\fP, or \fBpopd\fP commands,
-and the value of the named parameter begins with a `/',
-\fBzsh\fP will act as if the \fB$\fP had been supplied.
-.TP 8
-.B nobanghist (\-K)
-Do not perform `\fB!\fP' history substitution;
-do not treat the `\fB!\fP' character
-specially.
-.RE
-.PD
-.TP
-\fBshift\fP [ \fIn\^\fP ]
-.br
-The positional parameters from
-\fB$\fP\fIn\fP\fB+1\fP
-\&.\|.\|.
-are renamed
-.B $1
-\&.\|.\|.\^
-, default
-.I n
-is 1.
-.PD
-.PP
-.PD 0
-\fBtest\fP \fIexpr\fP
-.TP
-\fB[\fP \fIexpr\fP \fB]\fP
-Return a status of 0 (true) or 1 (false) depending on
-the evaluation of
-the conditional expression
-.IR expr .
-Expressions may be unary or binary.  Unary
-expressions are often used to examine the status of a file.  There
-are string operators
-and numeric comparison operators as well.
-.RS
-.PD 0
-.TP
-.B \-b \fIfile\fP
-True if \fIfile\fP exists and is block special.
-.TP
-.B \-c \fIfile\fP
-True if \fIfile\fP exists and is character special.
-.TP
-.B \-d \fIfile\fP
-True if \fIfile\fP exists and is a directory.
-.TP
-.B \-f \fIfile\fP
-True if \fIfile\fP exists and is a regular file.
-.TP
-.B \-g \fIfile\fP
-True if \fIfile\fP exists and is set-group-id.
-.TP
-.B \-k \fIfile\fP
-True if \fIfile\fP has its ``sticky'' bit set.
-.TP
-.B \-L \fIfile\fP
-True if \fIfile\fP exists and is a symbolic link.
-.TP
-.B \-p \fIfile\fP
-True if \fIfile\fP exists and is a named pipe.
-.TP
-.B \-r \fIfile\fP
-True if file exists and is readable.
-.TP
-.B \-s \fIfile\fP
-True if \fIfile\fP exists and has a non-zero size.
-.TP
-.B \-S \fIfile\fP
-True if \fIfile\fP exists and is a socket.
-.TP
-.B \-t [\fIfd\fP]
-True if
-.I fd
-is opened on a terminal.  If
-.I fd
-is omitted, it defaults to 1 (standard output).
-.TP
-.B \-u \fIfile\fP
-True if the \fIfile\fP exists and its set-user-id bit is set.
-.TP
-.B \-w \fIfile\fP
-True if the \fIfile\fP exists and is writable.
-.TP
-.B \-x \fIfile\fP
-True if the \fIfile\fP exists and is executable.
-.TP
-.B \-O \fIfile\fP
-True if the \fIfile\fP exists and is owned by the effective user id.
-.TP
-.B \-G \fIfile\fP
-True if the \fIfile\fP exists and is owned by the effective group id.
-.TP
-\fIfile1\fP \-\fBnt\fP \fIfile2\fP
-True if \fIfile1\fP is newer (according to
-modification date) than \fIfile2\fP.
-.TP
-\fIfile1\fP \-\fBot\fP \fIfile2\fP
-True if \fIfile1\fP is older than file2.
-.TP
-\fIfile1\fP \fB\-ef\fP \fIfile\fP
-True if \fIfile1\fP and \fIfile2\fP have the same device and
-inode numbers.
-.TP
-.B \-z \fIstring\fP
-True if the length of \fIstring\fP is zero.
-.TP
-.B \-n \fIstring\fP
-.TP
-\fIstring\fP
-True if the length of
-.I string
-is non-zero.
-.TP
-\fIstring1\fP \fB=\fP \fIstring2\fP
-True if the strings are equal.
-.TP
-\fIstring1\fP \fB!=\fP \fIstring2\fP
-True if the strings are not equal.
-.TP
-.B ! \fIexpr\fP
-True if
-.I expr
-is false.
-.TP
-\fIexpr1\fP \-\fBa\fP \fIexpr2\fP
-True if both
-.I expr1
-AND
-.I expr2
-are true.
-.TP
-\fIexpr1\fP \-\fBo\fP \fIexpr2\fP
-True if either
-.I expr1
-OR
-.I expr2
-is true.
-.TP
-.I arg1 \fBOP\fP arg2
-OP is one of
-.BR \-eq ,
-.BR \-ne ,
-.BR \-lt ,
-.BR \-le ,
-.BR \-gt ,
-or
-.BR \-ge .
-These arithmetic binary operators return true if \fIarg1\fP
-is equal, not-equal, less-than, less-than-or-equal,
-greater-than, or greater-than-or-equal than \fIarg2\fP,
-respectively.
-.I Arg1
-and
-.I arg2
-may be positive integers, negative integers, or the special
-expression \fB\-l\fP \fIstring\fP, which evaluates to the
-length of 
-.IR string .
-.PD
-.RE
-.TP
-\fBumask\fP [ \fImask\^\fP ]
-The user file-creation mask is set to
-.I mask
-(see
-.IR umask (2)).
-.I mask
-must be an octal number.
-If
-.I mask
-is omitted, the current value of the mask is printed.
-.TP
-\fBunalias\fP \fIname\^\fP .\|.\|.
-The
-.IR
-parameters
-given by the list of
-.IR name s
-are removed from the
-.I alias
-list.
-.TP
-\fBunfunction\fP \fIname\fP .\|.\|.
-The
-.IR
-functions
-given by the list of
-.IR name s
-are removed from the
-.I function
-list.
-.TP
-\fBunhash\fP \fIname\fP .\|.\|.
-Removes \fIname\fP from the command hash table.
-Shell builtins may be undefined in this way.
-.TP
-\fBunlimit [ \fB\-h\fP ] [ \fIresource\fP .\|.\|. ]\fP
-Remove a limitation on
-.IR resource .
-If no
-.I resource
-is specified, then all
-.I resource
-limitations are removed.
-See the description of the
-.B limit
-command for the list of
-.I resource
-names.
-.RS
-.TP 8
-.B \-h
-Remove corresponding hard limits.  Only the super-user may do this.
-.RE
-.TP
-\fBunset\fP \fIname\^\fP .\|.\|.
-The parameters given by the list of
-.IR name s
-are unset.
-.TP
-\fBunsetopt\fP [ \fIopt\fP .\|.\|.\| ]
-The named options are unset.  See \fBsetopt\fP above.
-.SS Invocation
-The shell first executes the the file
-\fB/etc/zshrc\fP
-and then
-\fB\(ap/.zshrc\fP,
-if it exists.
-If the shell is invoked by
-.IR exec (2),
-and the first character of argument zero
-.RB ( $0 )
-is
-.BR \- ,
-then the shell is assumed to be a
-.I login
-shell and
-commands are read from
-.B /etc/zlogin
-and
-.BR \(ap/.zshrc ,
-if it exists.
-If the
-.B \-s
-flag is not present and
-.I arg
-is, then the first
-.I arg
-is taken as the name of the script to execute.
-The script
-.I arg
-must have read permission and any
-.I setuid
-and
-.I getgid
-settings will be ignored.
-Commands are then read as described below;
-the following flags are interpreted by the shell
-when it is invoked:
-.PP
-.PD 0
-.TP 10
-.BI \-c "\| string"
-If the
-.B \-c
-flag is present then
-commands are read from
-.IR string .
-.TP
-.B \-s
-If the
-.B \-s
-flag is present or if no
-arguments remain
-then commands are read from the standard input.
-Shell output,
-except for the output of the
-.I builtins
-listed above,
-is written to
-file descriptor 2.
-.TP
-.B \-i
-If the
-.B \-i
-flag is present or
-if the shell input and output are attached to a terminal (as told by
-.IR ioctl (2))
-then this shell is
-.IR interactive .
-In this case TERM is ignored (so that \fBkill 0\fP
-does not kill an interactive shell) and INTR is caught and ignored.
-In all cases, QUIT is ignored by the shell.
-.PD
-.PP
-The remaining flags and arguments are described under the
-.B setopt
-command above.
-.SH EXIT STATUS
-Errors detected by the shell, such as syntax errors,
-cause the shell
-to return a non-zero exit status.
-Otherwise, the shell returns the exit status of
-the last command executed (see also the
-.B exit
-command above).
-If the shell is being used non-interactively
-then execution of the shell file is abandoned.
-.SH FILES
-\(ap/.zshrc
-.br
-\(ap/.zlogin
-.br
-\(ap/.zlogout
-.br
-\(ap/.zfriends
-.br
-\(ap/.inputrc
-.br
-/etc/zshrc
-.br
-/etc/zlogin
-.br
-/tmp/zsh\(**
-.SH SEE ALSO
-sh(1),
-csh(1),
-tcsh(1),
-itcsh(1),
---cut here---cut here---cut here---

pfalstad@phoenix.Princeton.EDU (Paul John Falstad) (12/15/90)

---cut here---cut here---cut here---
-				close(pipes[1]);
-				entersubsh(1);
-				exiting = 1;
-				execpline2(pline->right,ASYNC,pipes[0],output,1);
-				_exit(lastval);
-				}
-			else if (pid == -1)
-				{
-				zerr("fork failed: %e",errno);
-				errflag = 1;
-				}
-			else
-				{
-				char *s,*text;
-
-				close(pipes[0]);
-				text = s = getptext(pline->right);
-				for (;*s;s++)
-				if (*s == '\n')
-					*s = ';';
-				untokenize(text);
-				addproc(pid,text)->lastfg = 1;
-				freepline(pline->right);
-				pline->right = NULL;
-				}
-			}
-
-		/* otherwise just do the pipeline normally. */
-
-		execcomm(pline->left,input,pipes[1],how==ASYNC,0);
-		pline->left = NULL;
-		close(pipes[1]);
-		if (pline->right)
-			{
-			execpline2(pline->right,how,pipes[0],output,last1);
-			close(pipes[0]);
-			}
-		}
-}
-
-/* make the argv array */
-
-char **makecline(char *nam,struct xlist *list)
-{
-int ct = 0;
-Node node;
-char **argv,**ptr;
-
-	if (isset(XTRACE))
-		{
-		for (node = list->first; node; node = node->next,ct++);
-		ptr = argv = (char **) zalloc((ct+2)*sizeof(char *));
-		*ptr++ = nam;
-		fprintf(stderr,"+ %s",nam);
-		if (list->first)
-			fputc(' ',stderr);
-		for (node = list->first; node; node = node->next)
-			if (*(char *) node->dat)
-				{
-				*ptr++ = node->dat;
-				untokenize(node->dat);
-				fputs(node->dat,stderr);
-				if (node->next)
-					fputc(' ',stderr);
-				}
-		*ptr = NULL;
-		fputc('\n',stderr);
-		return(argv);
-		}
-	else
-		{
-		for (node = list->first; node; node = node->next,ct++);
-		ptr = argv = (char **) zalloc((ct+2)*sizeof(char *));
-		*ptr++ = nam;
-		for (node = list->first; node; node = node->next)
-			if (*(char *) node->dat)
-				{
-				*ptr++ = node->dat;
-				untokenize(node->dat);
-				}
-		*ptr = NULL;
-		return(argv);
-		}
-}
-
-/* untokenize the command line and remove null arguments */
-
-void fixcline(table l)
-{
-Node node,next;
-
-	for (node = l->first; node; node = next)
-		{
-		next = node->next;
-		if (*(char *) node->dat)
-			untokenize(node->dat);
-		else
-			remnode(l,node);
-		}
-}
-
-void untokenize(char *s)
-{
-	for (; *s; s++)
-		if (istok(*s))
-			if (*s == HQUOT || *s == Nularg)
-				chuck(s--);
-			else
-				*s = tokens[*s-Pound];
-}
-
-/* add vars to the environment */
-
-void addenv(table list)
-{
-char *s,*t;
-
-	while (s = getnode(list))
-		{
-		dovarsubs(&s);
-		if (errflag)
-			break;
-		untokenize(s);
-		t = getnode(list);
-		dovarsubs(&t);
-		if (errflag)
-			break;
-		untokenize(t);
-		setparm(s,t,1,0);
-		}
-}
-
-/* nonzero if we shouldn't clobber a file */
-
-int dontclob(struct fnode *f)
-{
-struct stat buf;
-
-	if (isset(CLOBBER) || f->type & 1)
-		return 0;
-	if (stat(f->u.name,&buf) == -1)
-		return 1;
-	return S_ISREG(buf.st_mode);
-}
-
-/* close an mnode (success) */
-
-void closemn(struct mnode *mfds[10],int fd)
-{
-	if (mfds[fd])
-		{
-		if (mfds[fd]->ct > 1)
-			if (mfds[fd]->rflag == 0)
-				catproc(mfds[fd]);
-			else
-				teeproc(mfds[fd]);
-		free(mfds[fd]);
-		mfds[fd] = NULL;
-		}
-}
-
-/* close all the mnodes (failure) */
-
-void closemnodes(struct mnode *mfds[10])
-{
-int t0,t1;
-
-	for (t0 = 0; t0 != 10; t0++)
-		if (mfds[t0])
-			{
-			for (t1 = 0; t1 != mfds[t0]->ct; t1++)
-				close(mfds[t0]->fds[t1]);
-			free(mfds[t0]);
-			mfds[t0] = NULL;
-			}
-}
-
-/* add a fd to an mnode */
-/* an mnode is a list of fds associated with a certain fd.
-	thus if you do "foo >bar >ble", the mnode for fd 1 will have
-	two fds, the result of open("bar",...), and the result of
-	open("ble",....). */
-
-void addfd(int forked,int save[10],struct mnode *mfds[10],int fd1,int fd2,int rflag)
-{
-int pipes[2];
-
-	if (!mfds[fd1])	/* starting a new mnode */
-		{
-		mfds[fd1] = alloc(sizeof(struct mnode));
-		if (!forked && fd1 != fd2 && fd1 < 10)
-			save[fd1] = movefd(fd1);
-		redup(fd2,fd1);
-		mfds[fd1]->ct = 1;
-		mfds[fd1]->fds[0] = fd1;
-		mfds[fd1]->rflag = rflag;
-		}
-	else
-		{
-		if (mfds[fd1]->rflag != rflag)
-			{
-			zerr("file mode mismatch on fd %d",fd1);
-			errflag = 1;
-			return;
-			}
-		if (mfds[fd1]->ct == 1)		/* split the stream */
-			{
-			mfds[fd1]->fds[0] = movefd(fd1);
-			mfds[fd1]->fds[1] = movefd(fd2);
-			mpipe(pipes);
-			mfds[fd1]->pipe = pipes[1-rflag];
-			redup(pipes[rflag],fd1);
-			mfds[fd1]->ct = 2;
-			}
-		else		/* add another fd to an already split stream */
-			mfds[fd1]->fds[mfds[fd1]->ct++] = movefd(fd2);
-		}
-}
-
-void execcomm(comm comm,int input,int output,int bkg,int last1)
-{
-int type;
-long pid = 0;
-table args = comm->args;
-int save[10] = {0,0,0,0,0,0,0,0,0,0},gstat;
-struct fnode *fn;
-struct mnode *mfds[10] = {0,0,0,0,0,0,0,0,0,0};
-int fil,forked = 0,iscursh = 0,t0;
-struct chnode *chn = NULL;
-char *text;
-list l;
-
-	if ((type = comm->type) == SIMPLE && !*comm->cmd)
-		{
-		if (comm->vars)
-			addvars(comm->vars);
-		return;
-		}
-	if (comm->cmd)
-		{
-		if (*comm->cmd == '%')
-			{
-			if (full(args))
-				{
-				zerrnam(comm->cmd,"too many arguments");
-				return;
-				}
-			addnode(args,comm->cmd);
-			comm->cmd = strdup((bkg) ? "bg" : "fg");
-			bkg = 0;
-			}
-		docmdsubs(&comm->cmd);
-		if (errflag)
-			{
-			freecmd(comm);
-			lastval = 1;
-			return;
-			}
-		untokenize(comm->cmd);
-		}
-	if (jobbing)	/* get the text associated with this command */
-		{
-		char *s;
-		s = text = gettext(comm);
-		for (;*s;s++)
-			if (*s == '\n')
-				*s = ';';
-		untokenize(text);
-		}
-	else
-		text = NULL;
-	prefork(comm->args);	/* do prefork substitutions */
-	if (comm->cmd && !(comm->flags & CFLAG_COMMAND))
-		{
-		if (isset(CORRECT) && jobbing)
-			spckcmd(&comm->cmd);
-		if ((l = gethnode(comm->cmd,shfunchtab)) &&
-				!(comm->flags & CFLAG_COMMAND))
-			{
-			insnode(comm->args,(Node) comm->args,comm->cmd);
-			comm->cmd = NULL;
-			comm->left = duplist(l);
-			type = comm->type = SHFUNC;
-			}
-		else
-			chn = gethnode(comm->cmd,chtab);
-		}
-	if (unset(RMSTARSILENT) && jobbing && chn && chn->type != BUILTIN &&
-			!strcmp(comm->cmd,"rm") && full(comm->args) &&
-			((char *) comm->args->first->dat)[0] == Star &&
-			((char *) comm->args->first->dat)[1] == '\0')
-		checkrmall();
-	if (errflag)
-		{
-		freecmd(comm);
-		lastval = 1;
-		return;
-		}
-	
-	/* this is nonzero if comm is a current shell procedure */
-
-	iscursh = (type >= CURSH) || (type == SIMPLE && chn &&
-		chn->type == BUILTIN);
-
-	gstat = (chn) ? chn->globstat : GLOB;
-
-	/* if this command is backgrounded or (this is an external
-		command and we are not exec'ing it) or this is a builtin
-		with output piped somewhere, then fork.  If this is the
-		last stage in a subshell pipeline, don't fork, but make
-		the rest of the function think we forked. */
-
-	if (bkg || !(iscursh || (comm->flags & CFLAG_EXEC)) ||
-			(chn && chn->type == BUILTIN && output))
-		{
-		pid = (last1 && execok()) ? 0 : phork();
-		if (pid == -1)
-			return;
-		if (pid)
-			{
-			if (pid == -1)
-				zerr("%e",errno);
-			else
-				(void) addproc(pid,text);
-			return;
-			}
-		entersubsh(bkg);
-		forked = 1;
-		}
-	if (bkg && isset(BGNICE))	/* stupid */
-		nice(5);
-	if (input)		/* add pipeline input/output to mnodes */
-		addfd(forked,save,mfds,0,input,0);
-	if (output)
-		addfd(forked,save,mfds,1,output,1);
-	spawnpipes(comm->redir);		/* do process substitutions */
-	while (full(comm->redir))
-		if ((fn = getnode(comm->redir))->type == INPIPE)
-			{
-			if (fn->u.fd2 == -1)
-				execerr();
-			addfd(forked,save,mfds,fn->fd1,fn->u.fd2,0);
-			free(fn);
-			}
-		else if (fn->type == OUTPIPE)
-			{
-			if (fn->u.fd2 == -1)
-				execerr();
-			addfd(forked,save,mfds,fn->fd1,fn->u.fd2,1);
-			free(fn);
-			}
-		else
-			{
-			if (!(fn->type == HEREDOC || fn->type == CLOSE || fn->type ==
-					MERGE || fn->type == MERGEOUT))
-				if (xpandredir(fn,comm->redir))
-					continue;
-			if (fn->type == READ || fn->type == HEREDOC)
-				{
-				fil = (fn->type == READ) ? open(fn->u.name,O_RDONLY) : fn->u.fd2;
-				if (fil == -1)
-					{
-					if (errno != EINTR)
-						zerr("%e: %s",errno,fn->u.name);
-					execerr();
-					}
-				addfd(forked,save,mfds,fn->fd1,fil,0);
-				if (fn->type == READ)
-					free(fn->u.name);
-				}
-			else if (fn->type == CLOSE)
-				{
-				if (!forked && fn->fd1 < 3)
-					{
-					zerr("can't close fd %d without forking",fn->fd1);
-					execerr();
-					}
-				closemn(mfds,fn->fd1);
-				close(fn->fd1);
-				}
-			else if (fn->type == MERGE || fn->type == MERGEOUT)
-				{
-				fil = dup(fn->u.fd2);
-				if (mfds[fn->fd1])
-					redup(fil,fn->fd1);
-				else
-					addfd(forked,save,mfds,fn->fd1,fil,fn->type == MERGEOUT);
-				}
-			else
-				{
-				if (fn->type >= APP)
-					fil = open(fn->u.name,dontclob(fn) ?
-						O_WRONLY|O_APPEND : O_WRONLY|O_APPEND|O_CREAT,0666);
-				else
-					fil = open(fn->u.name,dontclob(fn) ? 
-						O_WRONLY|O_CREAT|O_EXCL : O_WRONLY|O_CREAT|O_TRUNC,0666);
-				if (fil == -1)
-					{
-					if (errno != EINTR)
-						zerr("%e: %s",errno,fn->u.name);
-					execerr();
-					}
-				addfd(forked,save,mfds,fn->fd1,fil,1);
-				free(fn->u.name);
-				}
-			free(fn);
-			}
-	postfork(comm->args,gstat);	/* perform postfork substitutions */
-	if (errflag)
-		{
-		lastval = 1;
-		goto err;
-		}
-	
-	/* we are done with redirection.  close the mnodes, spawning
-		tee/cat processes as necessary. */
-	for (t0 = 0; t0 != 10; t0++)
-		closemn(mfds,t0);
-
-	if (unset(NOEXEC))
-		if (type >= CURSH)	/* current shell proc */
-			{
-			void (*func[])(struct cnode *) = {execcursh,execshfunc,
-				execfor,execwhile,execrepeat,execif,execcase,execselect};
-	
-			fixcline(comm->args);
-			(func[type-CURSH])(comm);
-			fflush(stdout);
-			if (ferror(stdout))
-				{
-				zerr("write error: %e",errno);
-				clearerr(stdout);
-				}
-			}
-		else if (iscursh)		/* builtin */
-			{
-			int (*func)() = chn->u.func;
-
-			if (comm->vars)
-				{
-				addvars(comm->vars);
-				comm->vars = NULL;
-				}
-			fixcline(comm->args);
-			if (func == test)		/* let test know if it is test or [ */
-				insnode(comm->args,(Node) comm->args,strdup(comm->cmd));
-			lastval = func(comm);
-			if (isset(PRINTEXITVALUE) && lastval)
-				zerr("exit %d",lastval);
-			}
-		else
-			{
-			if (comm->vars)
-				addenv(comm->vars);
-			if (type == SIMPLE)
-				{
-				closem();
-				execute(comm->cmd,args);
-				}
-			else	/* ( ... ) */
-				execlist(comm->left);
-			}
-err:
-	if (forked)
-		_exit(lastval);
-	fixfds(save);
-	freecmd(comm);
-}
-
-/* restore fds after redirecting a builtin */
-
-void fixfds(int save[10])
-{
-int t0;
-
-	for (t0 = 0; t0 != 10; t0++)
-		if (save[t0])
-			redup(save[t0],t0);
-}
-
-void entersubsh(int bkg)
-{
-	if (!jobbing)
-		{
-		if (bkg && isatty(0))
-			{
-			close(0);
-			if (open("/dev/null",O_RDWR))
-				{
-				zerr("can't open /dev/null: %e",errno);
-				_exit(1);
-				}
-			}
-		}
-	else if (!jobtab[curjob].gleader)
-		{
-		setpgrp(0L,jobtab[curjob].gleader = getpid());
-		if (!bkg)
-			attachtty(jobtab[curjob].gleader);
-		}
-	else
-		setpgrp(0L,jobtab[curjob].gleader);
-	subsh = 1;
-	if (SHTTY != -1)
-		{
-		close(SHTTY);
-		SHTTY = -1;
-		}
-	if (jobbing)
-		{
-		signal(SIGTTOU,SIG_DFL);
-		signal(SIGTTIN,SIG_DFL);
-		signal(SIGTSTP,SIG_DFL);
-		signal(SIGPIPE,SIG_DFL);
-		}
-	if (interact)
-		{
-		signal(SIGTERM,SIG_DFL);
-		if (sigtrapped[SIGINT])
-			signal(SIGINT,SIG_IGN);
-		}
-	if (!sigtrapped[SIGQUIT])
-		signal(SIGQUIT,SIG_DFL);
-	opts[MONITOR] = OPT_UNSET;
-	clearjobtab();
-}
-
-/* close all shell files */
-
-void closem(void)
-{
-int t0;
-
-	for (t0 = 10; t0 != NOFILE; t0++)
-		close(t0);
-}
-
-/* get here document */
-
-int gethere(char *str)
-{
-char pbuf[256],*nam = gettemp();
-int tfil = creat(nam,0666);
-FILE *in = fdopen(SHIN,"r");
-
-	FOREVER
-		{
-		fgetline(pbuf,256,in);
-		if (strcmp(str,pbuf))
-			{
-			pbuf[strlen(pbuf)] = '\n';
-			write(tfil,pbuf,strlen(pbuf));
-			}
-		else
-			break;
-		}
-	close(tfil);
-	tfil = open(nam,O_RDONLY);
-	unlink(nam);
-	free(nam);
-	return(tfil);
-}
-
-void catproc(struct mnode *mn)
-{
-int len,t0;
-char *buf;
-
-	if (phork())
-		{
-		for (t0 = 0; t0 != mn->ct; t0++)
-			close(mn->fds[t0]);
-		close(mn->pipe);
-		return;
-		}
-	closeallelse(mn);
-	buf = zalloc(4096);
-	for (t0 = 0; t0 != mn->ct; t0++)
-		while (len = read(mn->fds[t0],buf,4096))
-			write(mn->pipe,buf,len);
-	_exit(0);
-}
- 
-void teeproc(struct mnode *mn)
-{
-int len,t0;
-char *buf;
-
-	if (phork())
-		{
-		for (t0 = 0; t0 != mn->ct; t0++)
-			close(mn->fds[t0]);
-		close(mn->pipe);
-		return;
-		}
-	buf = zalloc(4096);
-	closeallelse(mn);
-	while ((len = read(mn->pipe,buf,4096)) > 0)
-		for (t0 = 0; t0 != mn->ct; t0++)
-			write(mn->fds[t0],buf,len);
-	_exit(0);
-}
-
-void closeallelse(struct mnode *mn)
-{
-int t0,t1;
-
-	for (t0 = 0; t0 != NOFILE; t0++)
-		if (mn->pipe != t0)
-			{
-			for (t1 = 0; t1 != mn->ct; t1++)
-				if (mn->fds[t1] == t0)
-					break;
-			if (t1 == mn->ct)
-				close(t0);
-			}
-}
-
-/* strtol() doesn't work right on my system */
-
-long int zstrtol(const char *s,char **t,int base)
-{
-int ret = 0;
- 
-	for (; *s >= '0' && *s < ('0'+base); s++)
-		ret = ret*base+*s-'0';
-	if (t)
-		*t = (char *) s;
-	return ret;
-}
-
-/* $(...) */
-
-table getoutput(char *cmd,int qt)
-{
-list list;
-int pipes[2];
-
-	if (*cmd == '<')
-		{
-		int stream;
-		char *fi;
-
-		fi = strdup(cmd+1);
-		if (*fi == '~')
-			*fi = Tilde;
-		else if (*fi == '=')
-			*fi = Equals;
-		filesub((void **) &fi);
-		if (errflag)
-			return NULL;
-		stream = open(fi,O_RDONLY);
-		if (stream == -1)
-			{
-			magicerr();
-			zerr("%e: %s",errno,cmd+1);
-			return NULL;
-			}
-		return readoutput(stream,qt);
-		}
-	hungets(strdup(cmd));
-	strinbeg();
-	if (!(list = parlist(1)))
-		{
-		strinend();
-		hflush();
-		return NULL;
-		}
-	if (peek != EOF && peek != EMPTY)
-		{
-		strinend();
-		hflush();
-		return NULL;
-		}
-	strinend();
-	mpipe(pipes);
-	if (phork())
-		{
-		close(pipes[1]);
-		return readoutput(pipes[0],qt);
-		}
-	subsh = 1;
-	close(pipes[0]);
-	redup(pipes[1],1);
-	entersubsh(0);
-	signal(SIGTSTP,SIG_IGN);
-	exiting = 1;
-	execlist(list);
-	close(1);
-	exit(0);  return NULL;
-}
-
-/* read output of command substitution */
-
-table readoutput(int in,int qt)
-{
-table ret;
-char *buf,*ptr;
-int bsiz,c,cnt = 0;
-FILE *fin;
-
-	fin = fdopen(in,"r");
-	ret = newtable();
-	ptr = buf = zalloc(bsiz = 256);
-	while ((c = fgetc(fin)) != EOF)
-		if (!qt && znspace(c))
-			{
-			if (cnt)
-				{
-				*ptr = '\0';
-				addnode(ret,strdup(buf));
-				cnt = 0;
-				ptr = buf;
-				}
-			}
-		else
-			{
-			*ptr++ = c;
-			if (++cnt == bsiz)
-				{
-				char *pp = zalloc(bsiz *= 2);
-				
-				memcpy(pp,buf,cnt);
-				free(buf);
-				ptr = (buf = pp)+cnt;
-				}
-			}
-	if (qt && ptr != buf && ptr[-1] == '\n')
-		ptr[-1] = '\0';
-	if (cnt)
-		addnode(ret,strdup(buf));
-	free(buf);
-	fclose(fin);
-	return ret;
-}
-
-/* =(...) */
-
-char *getoutputfile(char *cmd)
-{
-#ifdef WAITPID
-int pid;
-#endif
-char *nam = gettemp(),*str;
-int tfil;
-list list;
-
-	for (str = cmd; *str && *str != Outpar; str++);
-	if (!*str)
-		zerr("oops.");
-	*str = '\0';
-	hungets(strdup(cmd));
-	strinbeg();
-	if (!(list = parlist(1)))
-		{
-		hflush();
-		strinend();
-		return NULL;
-		}
-	if (peek != EOF && peek != EMPTY)
-		{
-		strinend();
-		hflush();
-		return NULL;
-		}
-	strinend();
-	if (!jobtab[curjob].filelist)
-		jobtab[curjob].filelist = newtable();
-	addnode(jobtab[curjob].filelist,strdup(nam));
-#ifdef WAITPID
-	if (pid = phork())
-		{
-		waitpid(pid,NULL,WUNTRACED);
-		return nam;
-		}
-#else
-	if (waitfork())
-		return nam;
-#endif
-	subsh = 1;
-	close(1);
-	entersubsh(0);
-	tfil = creat(nam,0666);
-	exiting = 1;
-	execlist(list);
-	close(1);
-	exit(0); return NULL;
-}
-
-/* get a temporary named pipe */
-
-char *namedpipe(void)
-{
-char *tnam = gettemp();
-
-	mknod(tnam,0010666,0);
-	return tnam;
-}
-
-/* <(...) */
-
-char *getoutproc(char *cmd)
-{
-list list;
-int fd;
-char *pnam,*str;
-
-	for (str = cmd; *str && *str != Outpar; str++);
-	if (!*str)
-		zerr("oops.");
-	*str = '\0';
-	hungets(strdup(cmd));
-	strinbeg();
-	if (!(list = parlist(1)))
-		{
-		strinend();
-		hflush();
-		return NULL;
-		}
-	if (peek != EOF && peek != EMPTY)
-		{
-		strinend();
-		hflush();
-		return NULL;
-		}
-	strinend();
-	pnam = namedpipe();
-	if (!jobtab[curjob].filelist)
-		jobtab[curjob].filelist = newtable();
-	addnode(jobtab[curjob].filelist,strdup(pnam));
-	if (phork())
-		return pnam;
-	entersubsh(1);
-	fd = open(pnam,O_WRONLY);
-	if (fd == -1)
-		{
-		zerr("can't open %s: %e",pnam,errno);
-		_exit(0);
-		}
-	redup(fd,1);
-	fd = open("/dev/null",O_RDONLY);
-	redup(fd,0);
-	exiting = 1;
-	execlist(list);
-	close(1);
-	_exit(0);  return NULL;
-}
-
-/* >(...) */
-
-char *getinproc(char *cmd)
-{
-list list;
-int pid,fd;
-char *pnam,*str;
-
-	for (str = cmd; *str && *str != Outpar; str++);
-	if (!*str)
-		zerr("oops.");
-	*str = '\0';
-	hungets(strdup(cmd));
-	strinbeg();
-	if (!(list = parlist(1)))
-		{
-		strinend();
-		hflush();
-		return NULL;
-		}
-	if (peek != EOF && peek != EMPTY)
-		{
-		strinend();
-		hflush();
-		return NULL;
-		}
-	strinend();
-	pnam = namedpipe();
-	if (!jobtab[curjob].filelist)
-		jobtab[curjob].filelist = newtable();
-	addnode(jobtab[curjob].filelist,strdup(pnam));
-	if (pid = phork())
-		return pnam;
-	entersubsh(1);
-	fd = open(pnam,O_RDONLY);
-	redup(fd,0);
-	exiting = 1;
-	execlist(list);
-	_exit(0);  return NULL;
-}
-
-/* > >(...) (does not use named pipes) */
-
-int getinpipe(char *cmd)
-{
-list list;
-int pipes[2];
-char *str = cmd;
-
-	for (str = cmd; *str && *str != Outpar; str++);
-	if (!*str)
-		zerr("oops.");
-	*str = '\0';
-	hungets(strdup(cmd+2));
-	strinbeg();
-	if (!(list = parlist(1)))
-		{
-		strinend();
-		hflush();
-		return -1;
-		}
-	if (peek != EOF && peek != EMPTY)
-		{
-		strinend();
-		hflush();
-		return NULL;
-		}
-	strinend();
-	mpipe(pipes);
-	if (phork())
-		{
-		close(pipes[1]);
-		return pipes[0];
-		}
-	close(pipes[0]);
-	entersubsh(1);
-	redup(pipes[1],1);
-	exiting = 1;
-	execlist(list);
-	_exit(0);  return 0;
-}
-
-/* < <(...) */
-
-int getoutpipe(char *cmd)
-{
-list list;
-int pipes[2];
-char *str;
-
-	for (str = cmd; *str && *str != Outpar; str++);
-	if (!*str)
-		zerr("oops.");
-	*str = '\0';
-	hungets(strdup(cmd+2));
-	strinbeg();
-	if (!(list = parlist(1)))
-		{
-		strinend();
-		hflush();
-		return -1;
-		}
-	if (peek != EOF && peek != EMPTY)
-		{
-		strinend();
-		hflush();
-		return NULL;
-		}
-	strinend();
-	mpipe(pipes);
-	if (phork())
-		{
-		close(pipes[0]);
-		return pipes[1];
-		}
-	close(pipes[1]);
-	entersubsh(1);
-	redup(pipes[0],0);
-	exiting = 1;
-	execlist(list);
-	_exit(0);  return 0;
-}
-
-/* run a list, saving the current job num */
-
-void runlist(list l)
-{
-int cj = curjob;
-
-	execlist(l);
-	curjob = cj;
-}
-
-char *gettemp(void)
-{
-	return mktemp(strdup("/tmp/zshXXXXXX"));
-}
-
-/* my getwd; all the other ones I tried confused the SIGCHLD handler */
-
-char *zgetwd(void)
-{
-static char buf0[MAXPATHLEN];
-char buf3[MAXPATHLEN],*buf2 = buf0+1;
-struct stat sbuf;
-struct direct *de;
-DIR *dir;
-ino_t ino = -1;
-dev_t dev = -1;
-
-	holdintr();
-	buf2[0] = '\0';
-	buf0[0] = '/';
-	for(;;)
-		{
-		if (stat(".",&sbuf) < 0)
-			{
-			chdir(buf0);
-			noholdintr();
-			return strdup(".");
-			}
-		ino = sbuf.st_ino;
-		dev = sbuf.st_dev;
-		if (stat("..",&sbuf) < 0)
-			{
-			chdir(buf0);
-			noholdintr();
-			return strdup(".");
-			}
-		if (sbuf.st_ino == ino && sbuf.st_dev == dev)
-			{
-			chdir(buf0);
-			noholdintr();
-			return strdup(buf0);
-			}
-		dir = opendir("..");
-		if (!dir)
-			{
-			chdir(buf0);
-			noholdintr();
-			return strdup(".");
-			}
-		chdir("..");
-		readdir(dir); readdir(dir);
-		while (de = readdir(dir))
-			if (de->d_fileno == ino)
-				{
-				lstat(de->d_name,&sbuf);
-				if (sbuf.st_dev == dev)
-					goto match;
-				}
-		rewinddir(dir);
-		readdir(dir); readdir(dir);
-		while (de = readdir(dir))
-			{
-			lstat(de->d_name,&sbuf);
-			if (sbuf.st_dev == dev)
-				goto match;
-			}
-		noholdintr();
-		closedir(dir);
-		return strdup(".");
-match:
-		strcpy(buf3,de->d_name);
-		if (*buf2)
-			strcat(buf3,"/");
-		strcat(buf3,buf2);
-		strcpy(buf2,buf3);
-		closedir(dir);
-		}
-}
-
-/* open pipes with fds >= 10 */
-
-void mpipe(int pp[2])
-{
-	pipe(pp);
-	pp[0] = movefd(pp[0]);
-	pp[1] = movefd(pp[1]);
-}
-
-/* do process substitution with redirection */
-
-void spawnpipes(table l)
-{
-Node n = l->first;
-struct fnode *f;
-
-	for (; n; n = n->next)
-		{
-		f = n->dat;
-		if (f->type == OUTPIPE)
-			{
-			char *str = f->u.name;
-			f->u.fd2 = getoutpipe(str);
-			free(str);
-			}
-		if (f->type == INPIPE)
-			{
-			char *str = f->u.name;
-			f->u.fd2 = getinpipe(str);
-			free(str);
-			}
-		}
-}
-
End of exec.c
echo exec.pro 1>&2
sed 's/^-//' >exec.pro <<'End of exec.pro'
-void execstring(char *s);
-void newrunlist(list l);
-int phork(void);
-void execcursh(comm comm);
-void execute(char *arg0,table args);
-char *findcmd(char *arg0);
-void execlist(list list);
-void execlist1(list list);
-void execlist2(list2 list,int type,int last1);
-int execpline(list2 l,int how,int last1);
-void execpline2(pline pline,int how,int input,int output,int last1);
-char **makecline(char *nam,struct xlist *list);
-void fixcline(table l);
-void untokenize(char *s);
-void addenv(table list);
-int dontclob(struct fnode *f);
-void closemn(struct mnode *mfds[10],int fd);
-void closemnodes(struct mnode *mfds[10]);
-void addfd(int forked,int save[10],struct mnode *mfds[10],int fd1,int fd2,int rflag);
-void execcomm(comm comm,int input,int output,int bkg,int last1);
-void fixfds(int save[10]);
-void entersubsh(int bkg);
-void closem(void);
-int gethere(char *str);
-void catproc(struct mnode *mn);
-void teeproc(struct mnode *mn);
-void closeallelse(struct mnode *mn);
-long int zstrtol(const char *s,char **t,int base);
-table getoutput(char *cmd,int qt);
-table readoutput(int in,int qt);
-char *getoutputfile(char *cmd);
-char *namedpipe(void);
-char *getoutproc(char *cmd);
-char *getinproc(char *cmd);
-int getinpipe(char *cmd);
-int getoutpipe(char *cmd);
-void runlist(list l);
-char *gettemp(void);
-char *zgetwd(void);
-void mpipe(int pp[2]);
-void spawnpipes(table l);
End of exec.pro
echo funcs.h 1>&2
sed 's/^-//' >funcs.h <<'End of funcs.h'
-/*
-
-	funcs.h - includes for all prototype files
-
-	This file is part of zsh, the Z shell.
-
-   zsh is free software; no one can prevent you from reading the source
-   code, or giving it to someone else.
-   This file is copyrighted under the GNU General Public License, which
-   can be found in the file called COPYING.
-
-   Copyright (C) 1990 Paul Falstad
-
-   zsh is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY.  No author or distributor accepts
-   responsibility to anyone for the consequences of using it or for
-   whether it serves any particular purpose or works at all, unless he
-   says so in writing.  Refer to the GNU General Public License
-   for full details.
-
-   Everyone is granted permission to copy, modify and redistribute
-   zsh, but only under the conditions described in the GNU General Public
-   License.   A copy of this license is supposed to have been given to you
-   along with zsh so you can know your rights and responsibilities.
-   It should be in a file named COPYING.
-
-   Among other things, the copyright notice and this notice must be
-   preserved on all copies.
-
-*/
-
-#include "glob.pro"
-#include "hist.pro"
-#include "table.pro"
-#include "subst.pro"
-#include "builtin.pro"
-#include "loop.pro"
-#include "jobs.pro"
-#include "exec.pro"
-#include "init.pro"
-#include "lex.pro"
-#include "parse.pro"
-#include "utils.pro"
-#include "test.pro"
-char *readline(char *);
-char *mktemp(char *);
End of funcs.h
echo glob.c 1>&2
sed 's/^-//' >glob.c <<'End of glob.c'
-/*
-
-	glob.c - filename generation and brace expansion
-
-	This file is part of zsh, the Z shell.
-
-   zsh is free software; no one can prevent you from reading the source
-   code, or giving it to someone else.
-   This file is copyrighted under the GNU General Public License, which
-   can be found in the file called COPYING.
-
-   Copyright (C) 1990 Paul Falstad
-
-   zsh is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY.  No author or distributor accepts
-   responsibility to anyone for the consequences of using it or for
-   whether it serves any particular purpose or works at all, unless he
-   says so in writing.  Refer to the GNU General Public License
-   for full details.
-
-   Everyone is granted permission to copy, modify and redistribute
-   zsh, but only under the conditions described in the GNU General Public
-   License.   A copy of this license is supposed to have been given to you
-   along with zsh so you can know your rights and responsibilities.
-   It should be in a file named COPYING.
-
-   Among other things, the copyright notice and this notice must be
-   preserved on all copies.
-
-*/
-
-#include "zsh.h"
-#include "funcs.h"
-#ifndef INT_MAX
-#include <limits.h>
-#endif
-#include <sys/dir.h>
-#include <sys/errno.h>
-
-#define exists(X) (access(X,0) == 0)
-#define magicerr() { if (magic) putc('\n',stderr); errflag = 1; }
-
-static int gtype;	/* file type for (X) */
-static int mode;	/* != 0 if we are parsing glob patterns */
-static int sense; /* (X) or (^X) */
-static int pathpos;	/* position in pathbuf */
-static int matchsz;	/* size of matchbuf */
-static int matchct;	/* number of matches found */
-static char pathbuf[MAXPATHLEN];	/* pathname buffer */
-static char **matchbuf;		/* array of matches */
-static char **matchptr;		/* &matchbuf[matchct] */
-
-/* pathname component in filename patterns */
-
-/* qath is a struct xpath * */
-
-struct xpath {
-	qath next;
-	comp comp;
-	int closure;	/* 1 if this is a (foo/)# */
-	};
-struct xcomp {
-	comp nx1,nx2;
-	char *str;
-	};
-
-void glob(table list,Node *np)
-{
-Node node = (*np)->last;	/* the node before this one */
-Node next = (*np)->next;	/* the node after this one */
-int sl;		/* length of the pattern */
-char *ostr;	/* the pattern before the parser chops it up */
-char *wd;	/* the cwd */
-qath q;		/* pattern after parsing */
-char *str = (*np)->dat;	/* the pattern */
-
-	sl = strlen(str);
-	ostr = strdup(str);
-	remnode(list,*np);
-	gtype = 0;
-	if (str[sl-1] == Outpar)	/* check for (X) or (^X) */
-		{
-		if (sl > 4 && str[sl-4] == Inpar && str[sl-3] == Hat)
-			sense = 1;
-		else if (sl > 3 && str[sl-3] == Inpar)
-			sense = 0;
-		else
-			sense = 2;
-		if (sense != 2)
-			{
-			str[sl-3-sense] = '\0';
-			switch (str[sl-2])
-				{
-				case '@': gtype = S_IFLNK; break;
-				case '=': gtype = S_IFSOCK; break;
-				case Inang: gtype = S_IFIFO; break;
-				case '/': gtype = S_IFDIR; break;
-				case '.': gtype = S_IFREG; break;
-				case Star:  gtype = 0100; break;
-				case '%': gtype = S_IFCHR; break;
-				case 'R': gtype = 0004; break;
-				case 'W': gtype = 0002; break;
-				case 'X': gtype = 0001; break;
-				case 'r': gtype = 0400; break;
-				case 'w': gtype = 0200; break;
-				case 'x': gtype = 0100; break;
-				default:
-					magicerr();
-					zerr("unknown file attribute");
-					return;
-				};
-			}
-		}
-	else if (str[sl-1] == '/')		/* foo/ == foo(/) */
-		{
-		gtype = S_IFDIR;
-		sense = 0;
-		}
-	if (*str == '/')	/* pattern has absolute path */
-		{
-		wd = zgetwd();
-		str++;
-		chdir("/");
-		pathbuf[0] = '/';
-		pathbuf[pathpos = 1] = '\0';
-		}
-	else		/* pattern is relative to cwd */
-		{
-		wd = NULL;
-		pathbuf[pathpos = 0] = '\0';
-		}
-	q = parsepat(str);
-	if (!q || errflag)	/* if parsing failed */
-		{
-		if (isset(NOBADPATTERN))
-			{
-			insnode(list,node,ostr);
-			return;
-			}
-		magicerr();
-		zerr("bad pattern: %s",ostr);
-		free(ostr);
-		return;
-		}
-	matchptr = matchbuf = (char **) zalloc((matchsz = 16)*sizeof(char *));
-	matchct = 0;
-	scanner(q);		/* do the globbing */
-	freepath(q);
-	if (wd)		/* reset cwd */
-		{
-		chdir(wd);
-		free(wd);
-		}
-	if (!matchct && unset(NULLGLOB))
-		if (unset(NONOMATCH))
-			{
-			if (!errflag)
-				{
-				magicerr();
-				zerr("no matches found: %s",ostr);
-				}
-			free(matchbuf);
-			free(ostr);
-			errflag = 1;
-			return;
-			}
-		else
-			{
-			*matchptr++ = strdup(ostr);
-			matchct = 1;
-			}
-	qsort(&matchbuf[0],matchct,sizeof(char *),notstrcmp);
-	matchptr = matchbuf;
-	while (matchct--)			/* insert matches in the arg list */
-		insnode(list,node,*matchptr++);
-	free(matchbuf);
-	free(ostr);
-	if (magic)
-		magic = 2;	/* tell readline we did something */
-	*np = (next) ? next->last : list->last;
-}
-
-int notstrcmp(char **a,char **b)
-{
-char *c = *b,*d = *a;
-
-	for (; *c == *d && *c; c++,d++);
-	return ((int) (unsigned char) *c-(int) (unsigned char) *d);
-}
-
-/* add a match to the list */
-
-void insert(char *s)
-{
-struct stat buf;
-
-	if (isset(MARKDIRS) && !lstat(s,&buf) && S_ISDIR(buf.st_mode)) /* grrr */
-		{
-		char *t;
-		int ll = strlen(s);
-
-		t = zalloc(ll+2);
-		strcpy(t,s);
-		t[ll] = '/';
-		t[ll+1] = '\0';
-		free(s);
-		s = t;
-		}
-	*matchptr++ = s;
-	if (++matchct == matchsz)
-		{
-		matchbuf = (char **) realloc(matchbuf,sizeof(char **)*(matchsz *= 2));
-		matchptr = matchbuf+matchct;
-		}
-}
-
-/* check to see if str is eligible for filename generation */
-
-int haswilds(char *str)	
-{
-	if (!str[1] && (*str == Inbrack || *str == Outbrack))
-		return 0;
-	if (str[0] == '%')
-		return 0;
-	for (; *str; str++)
-		if (!strncmp(str,"..../",5))
-			return 1;
-		else if (*str == Pound || *str == Hat || *str == Star ||
-				*str == Bar || *str == Inbrack || *str == Inang ||
-				*str == Quest)
-			return 1;
-	return 0;
-}
-
-/* check to see if str is eligible for brace expansion */
-
-int hasbraces(char *str)
-{
-int mb,bc,cmct1,cmct2;
-char *lbr = NULL;
-
-	if (str[0] == Inbrace && str[1] == Outbrace)
-		return 0;
-	for (mb = bc = cmct1 = cmct2 = 0; *str; str++)
-		{
-		if (*str == Inbrace)
-			{
-			if (!bc)
-				lbr = str;
-			bc++;
-			if (str[4] == Outbrace && str[2] == '-') /* {a-z} */
-				{
-				cmct1++;
-				if (bc == 1)
-					cmct2++;
-				}
-			}
-		else if (*str == Outbrace)
-			{
-			bc--;
-			if (!bc && !cmct2)
-				{
-				*lbr = '{';
-				*str = '}';
-				}
-			cmct2 = 0;
-			}
-		else if (*str == Comma && bc)
-			{
-			cmct1++;
-			if (bc == 1)
-				cmct2++;
-			}
-		if (bc > mb)
-			mb = bc;
-		if (bc < 0)
-			return 0;
-		}
-	return (mb && bc == 0 && cmct1);
-}
-
-/* expand stuff like >>*.c */
-
-int xpandredir(struct fnode *fn,table tab)
-{
-table fake;
-char *nam;
-struct fnode *ff;
-int ret = 0;
-
-	fake = newtable();
-	addnode(fake,fn->u.name);
-	prefork(fake);
-	if (!errflag)
-		postfork(fake,GLOB);
-	if (errflag)
-		{
-		freetable(fake,freestr);
-		return 0;
-		}
-	if (fake->first && !fake->first->next)
-		{
-		fn->u.name = fake->first->dat;
-		untokenize(fn->u.name);
-		}
-	else
-		while (nam = getnode(fake))
-			{
-			ff = alloc(sizeof(struct fnode));
-			ff->u.name = nam;
-			ff->type = fn->type;
-			addnode(tab,ff);
-			ret = 1;
-			}
-	free(fake);
-	return ret;
-}
-
-/* concatenate s1 and s2 in dynamically allocated buffer */
-
-char *dyncat(char *s1,char *s2)
-{
-char *ptr;
- 
-	ptr = zalloc(strlen(s1)+strlen(s2)+1);
-	strcpy(ptr,s1);
-	strcat(ptr,s2);
-	return ptr;
-}
-
-/* concatenate s1, s2, and s3 in dynamically allocated buffer */
-
-char *tricat(char *s1,char *s2,char *s3)
-{
-char *ptr;
-
-	ptr = zalloc(strlen(s1)+strlen(s2)+strlen(s3)+1);
-	strcpy(ptr,s1);
-	strcat(ptr,s2);
-	strcat(ptr,s3);
-	return ptr;
-}
-
-/* brace expansion */
-
-void xpandbraces(table list,Node *np)
-{
-Node node = (*np),last = node->last;
-char *str = node->dat,*str3 = str,*str2;
-int prev;
-
-	if (magic)
-		magic = 2;
-	for (; *str != Inbrace; str++);
- 	if (str[2] == '-' && str[4] == Outbrace)	 /* {a-z} */
-		{
-		char c1,c2;
-
-		remnode(list,node);
-		chuck(str);
-		c1 = *str;
-		chuck(str);
-		chuck(str);
-		c2 = *str;
-		chuck(str);
-		if (istok(c1))
-			c1 = tokens[c1-Pound];
-		if (istok(c2))
-			c2 = tokens[c2-Pound];
-		if (c1 < c2)
-			for (; c2 >= c1; c2--)	/* {a-z} */
-				{
-				*str = c2;
-				insnode(list,last,strdup(str3));
-				}
-		else
-			for (; c2 <= c1; c2++)	/* {z-a} */
-				{
-				*str = c2;
-				insnode(list,last,strdup(str3));
-				}
-		free(str3);
-		*np = last->next;
-		return;
-		}
-	prev = str-str3;
-	str2 = getparen(str++);
-	if (!str2)
-		{
-		errflag = 1;
-		zerr("how did you get this error?");
-		return;
-		}
-	remnode(list,node);
-	node = last;
-	FOREVER
-		{
-		char *zz,*str4;
-		int cnt;
-		
-		for (str4 = str, cnt = 0; cnt || *str != Comma && *str !=
-				Outbrace; str++)
-			if (*str == Inbrace)
-				cnt++;
-			else if (*str == Outbrace)
-				cnt--;
-			else if (!*str)
-				exit(10);
-		zz = zalloc(prev+(str-str4)+strlen(str2)+1);
-		strncpy(zz,str3,prev);
-		zz[prev] = '\0';
-		strncat(zz,str4,str-str4);
-		strcat(zz,str2);
-		insnode(list,node,zz);
-		node = node->next;
-		if (*str != Outbrace)
-			str++;
-		else
-			break;
-		}
-	free(str3);
-	*np = last->next;
-}
-
-/* get closing paren, given pointer to opening paren */
-
-char *getparen(char *str)
-{
-int cnt = 1;
-char typein = *str++,typeout = typein+1;
-
-	for (; *str && cnt; str++)
-		if (*str == typein)
-			cnt++;
-		else if (*str == typeout)
-			cnt--;
-	if (!str && cnt)
-		return NULL;
-	return str;
-}
-
-/* check to see if a matches b (b is not a filename pattern) */
-
-int matchpat(char *a,char *b)
-{
-comp c;
-int val;
-
-	c = parsereg(b);
-	if (!c)
-		{
-		zerr("bad pattern: %s");
-		errflag = 1;
-		return NULL;
-		}
-	val = doesmatch(a,c,0);
-	freecomp(c);
-	return val;
-}
-
-/* do the ${foo%%bar}, ${foo#bar} stuff */
-/* please do not laugh at this code. */
-
-void getmatch(char **sp,char *pat,int dd)
-{
-comp c;
-char *t,*lng = NULL,cc,*s = *sp;
-
-	c = parsereg(pat);
-	if (!c)
-		{
-		magicerr();
-		zerr("bad pattern: %s",pat);
-		return;
-		}
-	if (!(dd & 2))
-		{
-		for (t = s; t==s || t[-1]; t++)
-			{
-			cc = *t;
-			*t = '\0';
-			if (doesmatch(s,c,0))
-				{
-				if (!(dd & 1))
-					{
-					*t = cc;
-					t = strdup(t);
-					free(s);
-					freecomp(c);
-					*sp = t;
-					return;
-					}
-				lng = t;
-				}
-			*t = cc;
-			}
-		if (lng)
-			{
-			t = strdup(lng);
-			free(s);
-			freecomp(c);
-			*sp = t;
-			return;
-			}
-		}
-	else
-		{
-		for (t = s+strlen(s); t >= s; t--)
-			{
-			if (doesmatch(t,c,0))
-				{
-				if (!(dd & 1))
-					{
-					*t = '\0';
-					freecomp(c);
-					return;
-					}
-				lng = t;
-				}
-			}
-		if (lng)
-			{
-			*lng = '\0';
-			freecomp(c);
-			return;
-			}
-		}
-	freecomp(c);
-}
-
-/* add a component to pathbuf */
-
-void addpath(char *s)
-{
-	while (pathbuf[pathpos++] = *s++);
-	pathbuf[pathpos-1] = '/';
-	pathbuf[pathpos] = '\0';
-}
-
-/* do the globbing */
-
-void scanner(qath q)
-{
-comp c;
-
-	if (q->closure)			/* (foo/)# */
-		if (q->closure == 2)		/* (foo/)## */
-			q->closure = 1;
-		else
-			scanner(q->next);
-	if (c = q->comp)
-		{
-		if (!(c->nx1 || c->nx2) && !haswilds(c->str))
-			if (q->next)
-				{
-				char *wd = NULL;
-				
-				if (errflag)
-					return;
-				if (islink(c->str) || !strcmp(c->str,".."))
-					wd = zgetwd();
-				if (!chdir(c->str))
-					{
-					int oppos = pathpos;
-					
-					addpath(c->str);
-					scanner((q->closure) ? q : q->next);
-					if (wd)
-						chdir(wd);
-					else if (strcmp(c->str,"."))
-						chdir("..");
-					pathbuf[pathpos = oppos] = '\0';
-					}
-				else
-					{
-					magicerr();
-					zerr("%e: %s",errno,c->str);
-					if (wd)
-						chdir(wd);
-					else if (strcmp(c->str,"."))
-						chdir("..");
-					return;
-					}
-				}
-			else
-				{
-				if (exists(c->str))
-					insert(dyncat(pathbuf,c->str));
-				}
-		else
-			{
-			char *fn;
-			int type,type3,dirs = !!q->next;
-			struct direct *de;
-			DIR *lock = opendir(".");
-			static struct stat buf;
-			 
-			if (lock == NULL)
-				{
-				magicerr();
-				if (errno != EINTR)
-					zerr("%e: %s",errno,pathbuf);
-				return;
-				}
-			readdir(lock); readdir(lock); 	/* skip . and .. */
-			while (de = readdir(lock))
-				{
-				if (errflag)
-					break;
-				fn = &de->d_name[0];
-				if (dirs)
-					{
-					if (lstat(fn,&buf) == -1)
-						{
-						magicerr();
-						zerr("%e: %s",errno,fn);
-						}
-					type3 = buf.st_mode & S_IFMT;
-					if (type3 != S_IFDIR)
-						continue;
-					}
-				else
-					if (gtype)	/* do the (X) (^X) stuff */
-						{
-						if (lstat(fn,&buf) == -1)
-							{
-							if (errno != ENOENT)
-								{
-								magicerr();
-								zerr("%e: %s",errno,fn);
-								}
-							continue;
-							}
-						type3 = (type = buf.st_mode) & S_IFMT;
-						if (gtype & 0777)
-							{
-							if ((!(type & gtype) ^ sense) || type3 == S_IFLNK)
-								continue;
-							}
-						else if (gtype == S_IFCHR)
-							{
-							if ((type3 != S_IFCHR && type3 != S_IFBLK) ^ sense)
-								continue;
-							}
-						else if ((gtype != type3) ^ sense)
-							continue;
-						}
-				if (doesmatch(fn,c,unset(GLOBDOTS)))
-					if (dirs)
-						{
-						if (!chdir(fn))
-							{
-							int oppos = pathpos;
-					
-							addpath(fn);
-							scanner((q->closure) ? q : q->next); /* scan next level */
-							chdir("..");
-							pathbuf[pathpos = oppos] = '\0';
-							}
-						}
-					else
-						insert(dyncat(pathbuf,fn));
-				}
-			closedir(lock);
-			}
-		}
-	else
-		{
-		zerr("no idea how you got this error message.");
-		errflag = 1;
-		}
-}
-
-/* do the [..(foo)..] business */
-
-int minimatch(char **pat,char **str)
-{
-char *pt = *pat+1,*s = *str;
-	
-	for (; *pt != Outpar; s++,pt++)
-		if ((*pt != Quest || !*s) && *pt != *s)
-			{
-			*pat = getparen(*pat)-1;
-			return 0;
-			}
-	*str = s-1;
-	return 1;
-}
-
-/* see if str matches c; first means worry about matching . explicitly */
-
-int doesmatch(char *str,comp c,int first)
-{
-char *pat = c->str;
-
-	FOREVER
-		{
-		if (!*pat)
-			{
-			if (errflag)
-				return 0;
-			if (!(*str || c->nx1 || c->nx2))
-				return 1;
-			return (c->nx1 && doesmatch(str,c->nx1,first)) ||
-				(c->nx2 && doesmatch(str,c->nx2,first));
-			}
-		if (first && *str == '.' && *pat != '.')
-			return 0;
-		if (*pat == Star)	/* final * is not expanded to ?#; returns success */
-			return 1;
-		first = 0;
-		if (*pat == Quest && *str)
-			{
-			str++;
-			pat++;
-			continue;
-			}
-		if (*pat == Hat)
-			return 1-doesmatch(str,c->nx1,first);
-		if (*pat == Inbrack)
-			if (pat[1] == Hat)
-				{
-				for (pat += 2; *pat != Outbrack && *pat; pat++)
-					if (*pat == '-' && pat[-1] != Hat && pat[1] != Outbrack)
-						{
-						if (pat[-1] <= *str && pat[1] >= *str)
-							break;
-						}
-					else if (*str == *pat)
-						break;
-				if (!*pat)
-					{
-					zerr("something is very wrong.");
-					return 0;
-					}
-				if (*pat != Outbrack)
-					break;
-				pat++;
-				str++;
-				continue;
-				}
-			else
-				{
-				for (pat++; *pat != Outbrack && *pat; pat++)
-					if (*pat == Inpar)
-						{
-						if (minimatch(&pat,&str))
-							break;
-						}
-					else if (*pat == '-' && pat[-1] != Inbrack && pat[1] != Outbrack)
-						{
-						if (pat[-1] <= *str && pat[1] >= *str)
-							break;
-						}
-					else if (*str == *pat)
-						break;
-				if (!pat || !*pat)
-					{
-					zerr("oh dear.  that CAN'T be right.");
-					return 0;
-					}
-				if (*pat == Outbrack)
-					break;
-				for (str++; *pat != Outbrack; pat++);
-				pat++;
-				continue;
-				}
-		if (*pat == Inang)
-			{
-			int t1,t2,t3;
-			char *ptr;
-
-			if (*++pat == Outang)	/* handle <> case */
-				{
-				(void) zstrtol(str,&ptr,10);
-				if (ptr == str)
-					break;
-				str = ptr;
-				pat++;
-				}
-			else
-				{
-				t1 = zstrtol(str,&ptr,10);
-				if (ptr == str)
-					break;
-				str = ptr;
-				t2 = zstrtol(pat,&ptr,10);
-				if (*ptr != '-')
-					exit(31);
-				t3 = zstrtol(ptr+1,&pat,10);
-				if (!t3)
-					t3 = INT_MAX;
-				if (*pat++ != Outang)
-					exit(21);
-				if (t1 < t2 || t1 > t3)
-					break;
-				}
-			continue;
-			}
-		if (*str == *pat)
-			{
-			str++;
-			pat++;
-			continue;
-			}
-		break;
-		}
-	return 0;
-}
-
-static char *pptr;
-
-qath parsepat(char *str)
-{
-	mode = 0;
-	pptr = str;
-	return parseqath();
-}
-
-comp parsereg(char *str)
-{
-	mode = 1;
-	pptr = str;
-	return parsecompsw();
-}
-
-qath parseqath(void)
-{
-comp c1;
-qath p1;
-
-	if (pptr[0] == '.' && pptr[1] == '.' && pptr[2] == '.' && pptr[3] ==
-			'.' && pptr[4] == '/')
-		{
-		pptr[0] = Inpar;
-		pptr[1] = Star;
-		pptr[2] = '/';
-		pptr[3] = Outpar;
-		pptr[4] = Pound;	/* "..../" -> "( * /)#" */
-		}
-	if (*pptr == Inpar)
-		{
-		char *str;
-		int pars = 1;
-
-		for (str = pptr+1; *str && pars; str++)
-			if (*str == Inpar)
-				pars++;
-			else if (*str == Outpar)
-				pars--;
-		if (str[0] != Pound || str[-1] != Outpar || str[-2] != '/')
-			goto kludge;
-		pptr++;
-		if (!(c1 = parsecompsw()))
-			return NULL;
-		if (pptr[0] == '/' && pptr[1] == Outpar && pptr[2] == Pound)
-			{
-			int pdflag = 0;
-
-			pptr += 3;
-			if (*pptr == Pound)
-				{
-				pdflag = 1;
-				pptr++;
-				}
-			p1 = (qath) alloc(sizeof(struct xpath));
-			p1->comp = c1;
-			p1->closure = 1+pdflag;
-			p1->next = parseqath();
-			return (p1->comp) ? p1 : NULL;
-			}
-		}
-	else
-		{
-kludge:
-		if (!(c1 = parsecompsw()))
-			return NULL;
-		if (*pptr == '/' || !*pptr)
-			{
-			int ef = *pptr == '/';
-
-			p1 = (qath) alloc(sizeof(struct xpath));
-			p1->comp = c1;
-			p1->closure = 0;
-			p1->next = (*pptr == '/') ? (pptr++,parseqath()) : NULL;
-			return (ef && !p1->next) ? NULL : p1;
-			}
-		}
-	magicerr();
-	errflag = 1;
-	return NULL;
-}
-
-comp parsecomp(void)
-{
-comp c = (comp) alloc(sizeof(struct xcomp)),c1,c2;
-char *s = c->str = alloc(MAXPATHLEN*2),*ls = NULL;
-
-	c->nx2 = NULL;
-	while (*pptr && (mode || *pptr != '/') && *pptr != Bar &&
-			*pptr != Outpar)
-		{
-		if (*pptr == Hat)
-			{
-			*s++ = Hat;
-			*s++ = '\0';
-			pptr++;
-			if (!(c->nx1 = parsecomp()))
-				{
-				free(c->str);
-				free(c);
-				return NULL;
-				}
-			return c;
-			}
-		if (*pptr == Star && pptr[1] && (mode || pptr[1] != '/'))
-			{
-			*s++ = '\0';
-			pptr++;
-			c->nx1 = c1 = (comp) alloc(sizeof(struct xcomp));
-			*((c1->nx1 = c1)->str = strdup("?")) = Quest;
-			c->nx2 = c1->nx2 = parsecomp();
-			return (c->nx2) ? c : NULL;
-			}
-		if (*pptr == Inpar)
-			{
-			*s++ = '\0';
-			pptr++;
-			c->nx1 = c1 = parsecompsw();
-			if (*pptr != Outpar)
-				{
-				errflag = 1;
-				free(c);
-				free(c->str);
-				return NULL;
-				}
-			pptr++;
-			if (*pptr == Pound)
-				{
-				int dpnd = 0;
-
-				pptr++;
-				if (*pptr == Pound)
-					{
-					pptr++;
-					dpnd = 1;
-					}
-				c2 = parsecomp();
-				if (dpnd)
-					c->nx2 = NULL;
-				else
-					c->nx2 = c2;
-				if (!c2)
-					{
-					free(c);
-					free(c->str);
-					return NULL;
-					}
-				adjustcomp(c1,c2,c1);
-				return c;
-				}
-			c2 = parsecomp();
-			if (!c2)
-				{
-				free(c);
-				free(c->str);
-				return NULL;
-				}
-			adjustcomp(c1,c2,NULL);
-			return c;
-			}
-		if (*pptr == Pound)
-			{
-			int dpnd = 0;
-
-			*s = '\0';
-			pptr++;
-			if (*pptr == Pound)
-				{
-				pptr++;
-				dpnd = 1;
-				}
-			if (!ls)
-				return NULL;
-			c->nx1 = c1 = (comp) alloc(sizeof(struct xcomp));
-			(c1->nx2 = c1)->str = strdup(ls);
-			c->nx2 = c1->nx1 = parsecomp();
-			if (!c->nx2)
-				{
-				free(c);
-				free(c->str);
-				return NULL;
-				}
-			if (dpnd)
-				c->nx2 = NULL;
-			*ls++ = '\0';
-			return c;
-			}
-		ls = s;
-		if (*pptr == Inang)
-			{
-			int dshct;
-
-			dshct = (pptr[1] == Outang);
-			*s++ = *pptr++;
-			while (*pptr && (*s++ = *pptr++) != Outang)
-				if (s[-1] == '-')
-					dshct++;
-				else if (!isdigit(s[-1]))
-					break;
-			if (s[-1] != Outang || dshct != 1)
-				{
-				free(c);
-				free(c->str);
-				return NULL;
-				}
-			}
-		else if (*pptr == Inbrack)
-			{
-			while (*pptr && (*s++ = *pptr++) != Outbrack);
-			if (s[-1] != Outbrack)
-				{
-				free(c);
-				free(c->str);
-				return NULL;
-				}
-			}
-		else if (istok(*pptr) && *pptr != Star && *pptr != Quest)
-			*s++ = tokens[*pptr++-Pound];
-		else
-			*s++ = *pptr++;
-		}
-	*s++ = '\0';
-	c->nx1 = NULL;
-	return c;
-}
-
-comp parsecompsw(void)
-{
-comp c1,c2,c3;
-
-	c1 = parsecomp();
-	if (!c1)
-		return NULL;
-	if (*pptr == Bar)
-		{
-		c2 = (comp) alloc(sizeof(struct xcomp));
-		pptr++;
-		c3 = parsecompsw();
-		if (!c3)
-			return NULL;
-		c2->str = strdup("");
-		c2->nx1 = c1;
-		c2->nx2 = c3;
-		return c2;
-		}
-	return c1;
-}
-
-#define MARKER ((void *) 1L)
-
-void adjustcomp(comp c1,comp c2,comp c3)
-{
-comp z;
-
-	if (c1->nx1 == c2 && c1->nx2 == c3)
-		return;
-	if (c1->nx1)
-		{
-		if ((z = c1->nx1) == MARKER)
-			return;
-		c1->nx1 = MARKER;
-		adjustcomp(z,c2,c3);
-		c1->nx1 = z;
-		}
-	if (c1->nx2)
-		adjustcomp(c1->nx2,c2,c3);
-	if (!(c1->nx1 || c1->nx2))
-		{
-		c1->nx1 = c2;
-		c1->nx2 = c3;
-		}
-}
-
-void freepath(qath p)
-{
-	if (p)
-		{
-		freepath(p->next);
-		freecomp(p->comp);
-		free(p);
-		}
-}
-
-void freecomp(comp c)
-{
-	if (c && c->str)
-		{
-		free(c->str);
-		c->str = NULL;
-		freecomp(c->nx1);
-		freecomp(c->nx2);
-		free(c);
-		}
-}
-
-/* tokenize and see if ss matches tt */
-
-int patmatch(char *ss,char *tt)
-{
-char *s = ss,*t;
-
-	for (; *s; s++)
-		if (*s == '\\')
-			chuck(s);
-		else
-			for (t = tokens; *t; t++)
-				if (*t == *s)
-					{
-					*s = (t-tokens)+Pound;
-					break;
-					}
-	return matchpat(ss,tt);
-}
-
-/* remove unnecessary Nulargs */
-
-void remnulargs(char *s)
-{
-int nl = *s;
-char *t = s;
-
-	while (*s)
-		if (*s == Nularg)
-			chuck(s);
-		else
-			s++;
-	if (!*t && nl)
-		{
-		t[0] = Nularg;
-		t[1] = '\0';
-		}
-}
-
End of glob.c
echo glob.pro 1>&2
sed 's/^-//' >glob.pro <<'End of glob.pro'
-void glob(table list,Node *np);
-int notstrcmp(char **a,char **b);
-void insert(char *s);
-int haswilds(char *str);
-int hasbraces(char *str);
-int xpandredir(struct fnode *fn,table tab);
-char *dyncat(char *s1,char *s2);
-char *tricat(char *s1,char *s2,char *s3);
-void xpandbraces(table list,Node *np);
-char *getparen(char *str);
-int matchpat(char *a,char *b);
-void getmatch(char **sp,char *pat,int dd);
-void addpath(char *s);
-void scanner(qath q);
-int minimatch(char **pat,char **str);
-int doesmatch(char *str,comp c,int first);
-qath parsepat(char *str);
-comp parsereg(char *str);
-qath parseqath(void);
-comp parsecomp(void);
-comp parsecompsw(void);
-void adjustcomp(comp c1,comp c2,comp c3);
-void freepath(qath p);
-void freecomp(comp c);
-int patmatch(char *ss,char *tt);
-void remnulargs(char *s);
End of glob.pro
echo hist.c 1>&2
sed 's/^-//' >hist.c <<'End of hist.c'
-/*
-
-	hist.c - ! history	
-
-	This file is part of zsh, the Z shell.
-
-   zsh is free software; no one can prevent you from reading the source
-   code, or giving it to someone else.
-   This file is copyrighted under the GNU General Public License, which
-   can be found in the file called COPYING.
-
-   Copyright (C) 1990 Paul Falstad
-
-   zsh is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY.  No author or distributor accepts
-   responsibility to anyone for the consequences of using it or for
-   whether it serves any particular purpose or works at all, unless he
-   says so in writing.  Refer to the GNU General Public License
-   for full details.
-
-   Everyone is granted permission to copy, modify and redistribute
-   zsh, but only under the conditions described in the GNU General Public
-   License.   A copy of this license is supposed to have been given to you
-   along with zsh so you can know your rights and responsibilities.
-   It should be in a file named COPYING.
-
-   Among other things, the copyright notice and this notice must be
-   preserved on all copies.
-
-*/
-
-#include "zsh.h"
-#include "funcs.h"
-
-int lastc;
-
-/* add a character to the current history word */
-
-void hwaddc(int c)
-{
-	if (hlastw)
-		{
-		if (c == EOF || c == HERR)
-			return;
-		*hlastp++ = c;
-		if (hlastp-hlastw == hlastsz)
-			{
-			hlastw = realloc(hlastw,hlastsz *= 2);
-			hlastp = hlastw+(hlastsz/2);
-			}
-		}
-}
-
-#define habort() { errflag = 1; return HERR; }
-
-/* get a character after performing history substitution */
-
-int hgetc(void)
-{
-int c,ev,farg,larg,argc,marg = -1,cflag = 0,bflag = 0;
-char buf[256],*ptr;
-table slist,elist;
-
-tailrec:
-	c = hgetch();
-	if (stophist)
-		{
-		hwaddc(c);
-		return c;
-		}
-	if (firstch && c == '^' && !(ungots && !magic))
-		{
-		firstch = 0;
-		hungets(strdup(":s^"));
-		c = '!';
-		goto hatskip;
-		}
-	if (c != ' ')
-		firstch = 0;
-	if (c == '\\')
-		{
-		int g = hgetch();
-		
-		if (g != '!')
-			hungetch(g);
-		else
-			{
-			hwaddc('!');
-			return '!';
-			}
-		}
-	if (c != '!' || (ungots && !magic))
-		{
-		hwaddc(c);
-		return c;
-		}
-hatskip:
-	if ((c = hgetch()) == '{')
-		{
-			bflag = cflag = 1;
-			c = hgetch();
-			}
-		if (c == '\"')
-			{
-			stophist = 1;
-			goto tailrec;
-			}
-		if (!cflag && znspace(c) || c == '=' || c == '(')
-			{
-			hungetch(c);
-			hwaddc('!');
-			return '!';
-			}
-		cflag = 0;
-		ptr = buf;
-
-		/* get event number */
-
-		if (c == '?')
-			{
-			FOREVER
-				{
-				c = hgetch();
-				if (c == '?' || c == '\n')
-					break;
-				else
-					*ptr++ = c;
-				}
-			if (c != '\n')
-				c = hgetch();
-			*ptr = NULL;
-			ev = hconsearch(last = strdup(buf),&marg);
-			if (ev == -1)
-				{
-				herrflush();
-				zerr("no such event: %s",buf);
-				habort();
-				}
-			}
-		else
-			{
-			int t0;
-	 
-			FOREVER
-				{
-				if (znspace(c) || c == ':' || c == '^' || c == '$' || c == '*'
-						|| c == '%' || c == '}')
-					break;
-				if (ptr != buf && c == '-')
-					break;
-				*ptr++ = c;
-				if (c == '#' || c == '!')
-					{
-					c = hgetch();
-					break;
-					}
-				c = hgetch();
-				}
-			*ptr = 0;
-			if (!*buf)
-				ev = dev;
-			else if (t0 = atoi(buf))
-				ev = (t0 < 0) ? cev+t0 : t0;
-			else if (*buf == '!')
-				ev = cev-1;
-			else if (*buf == '#')
-				ev = cev;
-			else if ((ev = hcomsearch(buf)) == -1)
-				{
-				zerr("event not found: %s",buf);
-				while (c != '\n')
-					c = hgetch();
-				habort();
-				}
-			}
-
-		/* get the event */
-
-		if (!(elist = getevent(dev = ev)))
-			habort();
-
-		/* extract the relevant arguments */
-
-		argc = getargc(elist)-1;
-		if (c == ':')
-			{
-			cflag = 1;
-			c = hgetch();
-			}
-		if (c == '*')
-			{
-			farg = 1;
-			larg = argc;
-			cflag = 0;
-			}
-		else
-			{
-			hungetch(c);
-			larg = farg = getargspec(argc,marg);
-			if (larg == -2)
-				habort();
-			if (farg != -1)
-				cflag = 0;
-			c = hgetch();
-			if (c == '*')
-				{
-				cflag = 0;
-				larg = argc;
-				}
-			else if (c == '-')
-				{
-				cflag = 0;
-				larg = getargspec(argc,marg);
-				if (larg == -2)
-					habort();
-				if (larg == -1)
-					larg = argc-1;
-				}
-			else
-				hungetch(c);
-			}
-		if (farg == -1)
-			farg = 0;
-		if (larg == -1)
-			larg = argc;
-		if (!(slist = getargs(elist,farg,larg)))
-			habort();
-
-		/* do the modifiers */
-
-		FOREVER
-			{
-			c = (cflag) ? ':' : hgetch();
-			cflag = 0;
-			if (c == ':')
-				{
-				int gbal = 0;
-			
-				if ((c = hgetch()) == 'g')
-					{
-					gbal = 1;
-					c = hgetch();
-					}
-				switch(c)
-					{
-					case 'p':
-						hflag = 2;
-						break;
-					case 'h':
-						if (!apply1(gbal,remtpath,slist))
-							{
-							herrflush();
-							zerr("modifier failed: h");
-							habort();
-							}
-						break;
-					case 'e':
-						if (!apply1(gbal,rembutext,slist))
-							{
-							herrflush();
-							zerr("modifier failed: e");
-							habort();
-							}
-						break;
-					case 'r':
-						if (!apply1(gbal,remtext,slist))
-							{
-							herrflush();
-							zerr("modifier failed: r");
-							habort();
-							}
-						break;
-					case 't':
-						if (!apply1(gbal,remlpaths,slist))
-							{
-							herrflush();
-							zerr("modifier failed: t");
-							habort();
-							}
-						break;
-					case 's':
-						{
-						int del;
-						char *ptr1,*ptr2;
-					
-						del = hgetch();
-						ptr1 = hdynread(del);
-						if (!ptr1)
-							habort();
-						ptr2 = hdynread2(del);
-						if (strlen(ptr1))
-							{
-							if (last)
-								free(last);
-							last = ptr1;
-							}
-						if (rast)
-							free(rast);
-						rast = ptr2;
-						}
-					case '&':
-						if (last && rast)
-							{
-							if (subst(gbal,slist,last,rast))
-								habort();
-							}
-						else
-							{
-							herrflush();
-							zerr("no previous substitution with &");
-							habort();
-							}
-						break;
-					case 'q':
-						apply1(0,quote,slist);
-						break;
-					case 'x':
-						apply1(0,quotebreak,slist);
-						break;
-					default:
-						herrflush();
-						zerr("illegal modifier: %c",c);
-					habort();
-					break;
-				}
-			}
-		else
-			{
-			if (c != '}' || !bflag)
-				hungetch(c);
-			if (c != '}' && bflag)
-				{
-				zerr("'}' expected");
-				habort();
-				}
-			break;
-			}
-		}
-	
-	/* stuff the resulting string in the input queue and start over */
-
-	hungets(makehlist(slist,1));
-	hflag |= 1;
-	goto tailrec;
-}
-
-/* begin reading a string */
-
-void strinbeg(void)
-{
-	strin = 1;
-}
-
-/* done reading a string */
-
-void strinend(void)
-{
-	strin = 0;
-	firstch = 1;
-	hflag = 0;
-	free(ungots);
-	ungotptr = ungots = NULL;
-	peek = EMPTY;
-}
-
-static char *line = NULL,*oline = NULL;
-
-/* stuff a whole FILE into the input queue */
-
-int stuff(char *fn)
-{
-FILE *in;
-char *buf;
-int len;
-
-	if (!(in = fopen(fn,"r")))
-		{
-		zerr("can't open %s",fn);
-		return 1;
-		}
-	fseek(in,0,2);
-	len = ftell(in);
-	fseek(in,0,0);
-	buf = alloc(len+1);
-	if (!(fread(buf,len,1,in)))
-		{
-		zerr("read error on %s",fn);
-		fclose(fn);
-		free(buf);
-		return 1;
-		}
-	fclose(in);
-	if (!line)
-		line = oline = buf;
-	else
-		{
-		line = dyncat(line,buf);
-		free(oline);
-		oline = line;
-		}
-	return 0;
-}
-
-/* get a char without history */
-
-int hgetch(void)
-{
-char *pmpt = NULL,*s;
-
-	if (ungots)
-		{
-		if (*ungotptr)
-			{
-			if (*ungotptr == ALPOP)	/* done expanding an alias,
-												pop the alias stack */
-				{
-				if (!alix)
-					{
-					ungotptr++;
-					return lastc = HERR;
-					}
-				alstack[--alix]->inuse = 0;
-				s = alstack[alix]->text;
-				if (*s && s[strlen(s)-1] == ' ')
-					alstat = ALSTAT_MORE;
-				else
-					alstat = ALSTAT_JUNK;
-				ungotptr++;
-				return lastc = hgetch();
-				}
-			return lastc = *ungotptr++;
-			}
-		if (strin)
-			return lastc = EOF;
-		ungotptr = 0;
-		free(ungots);
-		ungots = NULL;
-		}
-kludge:
-	if (errflag)
-		{
-		if (oline)
-			free(oline);
-		oline = line = NULL;
-		return lastc = HERR;
-		}
-	if (line && *line)
-		return lastc = (*line++);
-	if (line)
-		free(oline);
-	if (interact)
-		if (!firstln)
-			pmpt = putprompt("PROMPT2");
-		else
-			pmpt = putprompt("PROMPT");
-	if (interact && SHTTY == -1)
-		write(2,pmpt,strlen(pmpt));
-	oline = line = (interact && SHTTY != -1) ? readline(pmpt) : 
-		fgets(zalloc(256),256,bshin);
-	if (isset(VERBOSE) && line)
-		fputs(line,stderr);
-	if (!line)
-		return lastc = EOF;
-	if (line[strlen(line)-1] == '\n')
-		lineno++;
-	firstch = 1;
-	firstln = 0;
-	goto kludge;
-}
-
-/* unget a character */
-
-void hungetch(int c)
-{
-static char ubuf2[] = {'x',0};
-
-	if (c == EOF)
-		return;
-	ubuf2[0] = c;
-	hungets(strdup(ubuf2));
-}
-
-/* unget a character and remove it from the history word */
-
-void hungetc(int c)
-{
-	if (hlastw)
-		{
-		if (hlastw == hlastp)
-			zerr("hungetc attempted at buffer start");
-		else
-			hlastp--;
-		}
-	hungetch(c);
-}
-
-void hflush(void)
-{
-	if (ungots)
-		free(ungots);
-	ungots = ungotptr = NULL;
-}
-
-/* unget a string into the input queue */
-
-void hungets(char *str)
-{
-	if (ungots && !*ungotptr)
-		{
-		free(ungots);
-		ungots = NULL;
-		}
-	if (ungots)
-		{
-		char *ptr;
-		
-		ptr = dyncat(str,ungotptr);
-		free(ungots);
-		free(str);
-		ungotptr = ungots = ptr;
-		}
-	else
-		ungots = ungotptr = str;
-}
-
-/* initialize the history mechanism */
-
-void hbegin(void)
-{
-	firstln = firstch = 1;
-	histremmed = errflag = hflag = 0;
-	stophist = isset(NOBANGHIST);
-	if (interact)
-		{
-		inittty();
-		dev = cev++;
-		while (cev-tfev >= tevs)
-			{
-			freetable(getnode(histlist),freestr);
-			tfev++;
-			}
-		addnode(histlist,curtab = newtable());
-		}
-}
-
-void inittty(void)
-{
-	attachtty(shpgrp);
-	settyinfo(&shttyinfo);
-}
-
-/* say we're done using the history mechanism */
-
-int hend(void)
-{
-char *ptr;
-int flag;
-
-	if (!interact)
-		return 1;
-	if (!curtab)
-		return 0;
-	flag = hflag;
-	hflag = 0;
-	if (curtab->first && (*(char *) curtab->last->dat == '\n'))
-		free(remnode(curtab,curtab->last));
-	if (!curtab->first)
-		{
-		freetable(remnode(histlist,histlist->last),freestr);
-		cev--;
-		flag = 0;
-		}
-	if (flag)
-		{
-		fprintf(stderr,"%s\n",ptr = makehlist(curtab,0));
-		free(ptr);
-		}
-	curtab = NULL;
-	return !(flag & 2 || errflag);
-}
-
-/* remove the current line from the history list */
-
-void remhist(void)
-{
-	if (!interact)
-		return;
-	if (!histremmed)
-		{
-		histremmed = 1;
-		freetable(remnode(histlist,histlist->last),freestr);
-		cev--;
-		}
-}
-
-/* begin a word */
-
-void hwbegin(void)
-{
-	if (hlastw)
-		free(hlastw);
-	hlastw = hlastp = zalloc(hlastsz = 32);
-}
-
-/* add a word to the history list */
-
-char *hwadd(void)
-{
-char *ret = hlastw;
-
-	if (hlastw)
-		*hlastp = '\0';
-	if (hlastw && lastc != EOF && !errflag)
-		if (curtab && !alix/* && alstat != ALSTAT_JUNK*/)
-			{
-			addnode(curtab,hlastw);
-			hlastw = NULL;
-			}
-	if (alstat == ALSTAT_JUNK)
-		alstat = 0;
-	return ret;
-}
-
-/* get an argument specification */
-
-int getargspec(int argc,int marg)
-{
-int c,ret = -1;
- 
-	if ((c = hgetch()) == '0')
-		return 0;
-	if (isdigit(c))
-		{
-		ret = 0;
-		while (isdigit(c))
-			{
-			ret = ret*10+c-'0';
-			c = hgetch();
-			}
-		hungetch(c);
-		}
-	else if (c == '^')
-		ret = 1;
-	else if (c == '$')
-		ret = argc;
-	else if (c == '%')
-		{
-		if (marg == -1)
-			{
-			herrflush();
-			zerr("%% with no previous word matched");
-			return -2;
-			}
-		ret = marg;
-		}
-	else
-		hungetch(c);
-	return ret;
-}
-
-/* do ?foo? search */
-
-int hconsearch(char *str,int *marg)
-{
-int t0,t1;
-Node node,node2;
- 
-	if (cev-tfev < 1)
-		return -1;
-	for (t0 = cev-1,node = histlist->last->last;
-			t0 >= tfev; t0--,node = node->last)
-		for (t1 = 0,node2 = ((table) node->dat)->first; node2; t1++,node2 =
-				node2->next)
-			if (strstr(node2->dat,str))
-				{
-				*marg = t1;
-				return t0;
-				}
-	return -1;
-}
-
-/* do !foo search */
-
-int hcomsearch(char *str)
-{
-int t0;
-Node node,node2;
- 
-	if (cev-tfev < 1)
-		return -1;
-	for (t0 = cev-1,node = histlist->last->last; t0 >= tfev;
-			t0--,node = node->last)
-		if ((node2 = ((table) node->dat)->first)->dat &&
-				strstr(node2->dat,str))
-			return t0;
-	return -1;
-}
-
-/* apply func to a list */
-
-int apply1(int gflag,int (*func)(void **),table list)
-{
-Node node;
-int flag = 0;
- 
-	for (node = list->first; node; node = node->next)
-		if ((flag |= func(&node->dat)) && !gflag)
-			return 1;
-	return flag;
-}
-
-/* various utilities for : modifiers */
-
-int remtpath(void **junkptr)
-{
-char *str = *junkptr,*cut;
- 
-	if (cut = strrchr(str,'/'))
-		{
-		*cut = NULL;
-		return 1;
-		}
-	return 0;
-}
- 
-int remtext(void **junkptr)
-{
-char *str = *junkptr,*cut;
- 
-	if ((cut = strrchr(str,'.')) && cut != str)
-		{
-		*cut = NULL;
-		return 1;
-		}
-	return 0;
-}
- 
-int rembutext(void **junkptr)
-{
-char *str = *junkptr,*cut;
- 
-	if ((cut = strrchr(str,'.')) && cut != str)
-		{
-		*junkptr = strdup(cut+1);  /* .xx or xx? */
-		free(str);
-		return 1;
-		}
-	return 0;
-}
- 
-int remlpaths(void **junkptr)
-{
-char *str = *junkptr,*cut;
- 
-	if (cut = strrchr(str,'/'))
-		{
-		*cut = NULL;
-		*junkptr = strdup(cut+1);
-		free(str);
-		return 1;
-		}
-	return 0;
-}
- 
-int subst(int gbal,table slist,char *ptr1,char *ptr2)
-{
-Node node;
-int iflag = 0;
- 
-	for (node = slist->first; node; )
-		if (subststr(&node->dat,ptr1,ptr2,gbal))
-			{
-			iflag = 1;
-			if (!gbal)
-				return 0;
-			}
-		else
-			node = node->next;
-	if (!iflag)
-		{
-		herrflush();
-		zerr("string not found: %s",ptr1);
-		return 1;
-		}
-	return 0;
-}
- 
-int subststr(void **strptr,char *in,char *out,int gbal)
-{
-char *str = *strptr,*cut,*sptr,*ss;
-int ret = 0;
-
-maze:
-	if (cut = (char *) strstr(str,in))
-		{
-		char *incop;
-		
-		incop = strdup(in);
-		*cut = '\0';
-		cut += strlen(in);
-		ss = *strptr;
-		*strptr = tricat(*strptr,sptr = convamps(out,incop),cut);
-		free(ss);
-		free(sptr);
-		free(incop);
-		if (gbal)
-			{
-			str = (char *) *strptr+(cut-str)+strlen(in);
-			ret = 1;
-			goto maze;
-			}
-		return 1;
-		}
-	return ret;
-}
- 
-char *convamps(char *out,char *in)
-{
-char *ptr,*ret,*pp;
-int slen,inlen = strlen(in);
- 
-	for (ptr = out, slen = 0; *ptr; ptr++,slen++)
-		if (*ptr == '\\')
-			ptr++;
-		else if (*ptr == '&')
-			slen += inlen-1;
-	ret = pp = zalloc(slen+1);
-	for (ptr = out; *ptr; ptr++)
-		if (*ptr == '\\')
-			*pp++ = *++ptr;
-		else if (*ptr == '&')
-			{
-			strcpy(pp,in);
-			pp += inlen;
-			}
-		else
-			*pp++ = *ptr;
-	*pp = '\0';
-	return ret;
-}
-
-/* make a string out of a history list */
-
-char *makehlist(table tab,int freeit)
-{
-int ccnt;
-Node node;
-char *ret,*ptr;
-char sep = *ifs;
-
-	for (ccnt = 0, node = (freeit == 2) ? tab->first->next : tab->first;
-			node; node = node->next)
-		ccnt += strlen(node->dat)+1;
-	if (!ccnt)
-		return strdup("");
-	ptr = ret = zalloc(ccnt);
-	for (node = (freeit == 2) ? tab->first->next : tab->first;
-			node; node = node->next)
-		{
-		strcpy(ptr,node->dat);
-		ptr += strlen(node->dat);
-		if (freeit == 1)
-			free(node->dat);
-		*ptr++ = sep;
-		}
-	*--ptr = '\0';
-	return ret;
-}
-
-table quietgetevent(int ev)
-{
-Node node;
- 
-	ev -= tfev;
-	for (node = histlist->first; ev && node; node = node->next, ev--);
-	if (ev)
-		return NULL;
-	return node->dat;
-}
-
-table getevent(int ev)
-{
-Node node;
-int oev = ev;
- 
-	ev -= tfev;
-	for (node = histlist->first; ev && node; node = node->next, ev--);
-	if (ev || !node)
-		{
-		herrflush();
-		zerr("no such event: %d",oev);
-		return NULL;
-		}
-	return node->dat;
-}
- 
-int getargc(table tab)
-{
-int argc;
-Node node;
- 
-	for (argc = 0, node = tab->first; node; node = node->next, argc++);
-	return argc;
-}
- 
-table getargs(table elist,int arg1,int arg2)
-{
-table ret = newtable();
-Node node;
-int oarg1 = arg1,oarg2 = arg2;
- 
-	for (node = elist->first; arg1 && node; node = node->next, arg1--,arg2--);
-	if (!node)
-		{
-		herrflush();
-		zerr("no such word in event: %d",oarg1);
-		return NULL;
-		}
-	for (arg2++; arg2 && node; node = node->next, arg2--)
-		addnode(ret,strdup(node->dat));
-	if (arg2 && !node)
-		{
-		herrflush();
-		zerr("no such word in event: %d",oarg2);
-		return NULL;
-		}
-	return ret;
-}
-
-int quote(void **tr)
-{
-char *ptr,*rptr,**str = (char **) tr;
-int len = 1;
- 
-	for (ptr = *str; *ptr; ptr++,len++)
-		if (*ptr == '\'')
-			len += 3;
-	ptr = *str;
-	*str = rptr = alloc(len);
-	for (ptr = *str; *ptr; )
-		if (*ptr == '\'')
-			{
-			*rptr++ = '\'';
-			*rptr++ = '\\';
-			*rptr++ = '\'';
-			*rptr++ = '\'';
-			ptr++;
-			}
-		else
-			*rptr++ = *ptr++;
-	return 0;
-}
- 
-int quotebreak(void **tr)
-{
-char *ptr,*rptr,**str = (char **) tr;
-int len = 1;
- 
-	for (ptr = *str; *ptr; ptr++,len++)
-		if (*ptr == '\'')
-			len += 3;
-		else if (znspace(*ptr))
-			len += 2;
-	ptr = *str;
-	*str = rptr = alloc(len);
-	for (ptr = *str; *ptr; )
-		if (*ptr == '\'')
-			{
-			*rptr++ = '\'';
-			*rptr++ = '\\';
-			*rptr++ = '\'';
-			*rptr++ = '\'';
-			ptr++;
-			}
-		else if (znspace(*ptr))
-			{
-			*rptr++ = '\'';
-			*rptr++ = *ptr++;
-			*rptr++ = '\'';
-			}
-		else
-			*rptr++ = *ptr++;
-	return 0;
-}
-
-void stradd(char **p,char *d)
-{
-char *s = *p;
-
-	while (*s++ = *d++);
-	*p = s-1;
-}
-
-/* get a prompt string */
-
-char *putprompt(char *fm)
-{
-char *ss,*ttyname(int);
-static char buf[256];
-char *bp = buf;
-int t0;
-struct tm *tm = NULL;
-time_t timet;
-
-	clearerr(stdin);
-	fm = getparm(fm);
-	for(;*fm;fm++)
-		{
-		if (bp-buf >= 220)
-			break;
-		if (*fm == '%')
-			switch (*++fm)
-				{
-				case '~':
-					if (!strncmp(cwd,home,t0 = strlen(home)))
-						{
-						*bp++ = '~';
-						stradd(&bp,cwd+t0);
-						break;
-						}
-				case 'd':
-				case '/':
-					stradd(&bp,cwd);
-					break;
-				case 'c':
-				case '.':
-					for (ss = cwd+strlen(cwd); ss > cwd; ss--)
-						if (*ss == '/')
-							{
-							ss++;
-							break;
-							}
-					stradd(&bp,ss);
-					break;
-				case 'h':
-				case '!':
-					sprintf(bp,"%d",cev);
-					bp += strlen(bp);
-					break;
---cut here---cut here---cut here---

cca04@phsun3 (P.J. Mitchell) (12/19/90)

From article <4742@idunno.Princeton.EDU>, by pfalstad@phoenix.Princeton.EDU (Paul John Falstad):

Is it just me or were the contents of the readline directory missing ?

Ta.
--
Paul Mitchell (CMA#136(18) MAG#65715 DoD#0145) | Computer Centre,
JANET:  p.j.mitchell@uk.ac.keele.seq1          | Keele University, Keele,
USENET: p.j.mitchell@seq1.keele.ac.uk          | Staffordshire, ST5 5BG, U.K.
BITNET: p.j.mitchell%seq1.keele.ac.uk@ukacrl   | (+44 or 0)782 621111 ext 3302