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

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

---cut here---cut here---cut here---
-bash(1),
-ksh(1),
-cat(1),
-cd(1),
-chmod(1),
-cut(1),
-echo(1),
-emacs(1),
-env(1),
-gmacs(1),
-newgrp(1),
-stty(1),
-test(1),
-umask(1),
-vi(1),
-dup(2),
-exec(2),
-fork(2),
-ioctl(2),
-lseek(2),
-paste(1),
-pipe(2),
-signal(2),
-umask(2),
-ulimit(2),
-wait(2),
-rand(3),
-a.out(5),
-profile(5),
-environ(7),
-xtetris(6).
-.SH AUTHOR
-Paul Falstad <pfalstad@phoenix.princeton.edu>
-.PP
-The command line editor is a hacked-up version
-of the GNU readline library,
-written by Brian Fox (<bfox@ai.MIT.Edu>) of the Free
-Software Foundation.  This shell is therefore
-under the GNU public license.  I eventually plan
-to write my own command line editor to make everything
-my own code, but \fBzsh\fP will probably still be under
-the GPL, or perhaps something less restrictive.
-.SH CAVEATS
-.PP
-Using
-.B fc
-built-in command within a compound command will cause the whole
-command to disappear from the history file.
-.PP
-Shell functions are put in the function table when their declarations
-are parsed, not when they are executed.  Thus function declarations
-inside \fBif\fP clauses, for example, will not work as expected.
-(This is a bug, not a caveat.)
-.PP
-The command line editor gets confused if you have termcap sequences
-(like %S) in your prompt.
-.PP
-The main shell does not get along with the command line editor.
-One of them will have to go.
-.PP
-Use of this shell is reserved for faculty, staff,
-graduate students,
-and special guests
-of the Princeton University 
-Computer Science department.
End of zsh.1
echo COPYING 1>&2
sed 's/^-//' >COPYING <<'End of COPYING'
-
-		    GNU GENERAL PUBLIC LICENSE
-		     Version 1, February 1989
-
- Copyright (C) 1989 Free Software Foundation, Inc.
-                    675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The license agreements of most software companies try to keep users
-at the mercy of those companies.  By contrast, our General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  The
-General Public License applies to the Free Software Foundation's
-software and to any other program whose authors commit to using it.
-You can use it for your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Specifically, the General Public License is designed to make
-sure that you have the freedom to give away or sell copies of free
-software, that you receive source code or can get it if you want it,
-that you can change the software or use pieces of it in new free
-programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of a such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must tell them their rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any program or other work which
-contains a notice placed by the copyright holder saying it may be
-distributed under the terms of this General Public License.  The
-"Program", below, refers to any such program or work, and a "work based
-on the Program" means either the Program or any work containing the
-Program or a portion of it, either verbatim or with modifications.  Each
-licensee is addressed as "you".
-
-  1. You may copy and distribute verbatim copies of the Program's source
-code as you receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice and
-disclaimer of warranty; keep intact all the notices that refer to this
-General Public License and to the absence of any warranty; and give any
-other recipients of the Program a copy of this General Public License
-along with the Program.  You may charge a fee for the physical act of
-transferring a copy.
-
-  2. You may modify your copy or copies of the Program or any portion of
-it, and copy and distribute such modifications under the terms of Paragraph
-1 above, provided that you also do the following:
-
-    a) cause the modified files to carry prominent notices stating that
-    you changed the files and the date of any change; and
-
-    b) cause the whole of any work that you distribute or publish, that
-    in whole or in part contains the Program or any part thereof, either
-    with or without modifications, to be licensed at no charge to all
-    third parties under the terms of this General Public License (except
-    that you may choose to grant warranty protection to some or all
-    third parties, at your option).
-
-    c) If the modified program normally reads commands interactively when
-    run, you must cause it, when started running for such interactive use
-    in the simplest and most usual way, to print or display an
-    announcement including an appropriate copyright notice and a notice
-    that there is no warranty (or else, saying that you provide a
-    warranty) and that users may redistribute the program under these
-    conditions, and telling the user how to view a copy of this General
-    Public License.
-
-    d) You may charge a fee for the physical act of transferring a
-    copy, and you may at your option offer warranty protection in
-    exchange for a fee.
-
-Mere aggregation of another independent work with the Program (or its
-derivative) on a volume of a storage or distribution medium does not bring
-the other work under the scope of these terms.
-
-  3. You may copy and distribute the Program (or a portion or derivative of
-it, under Paragraph 2) in object code or executable form under the terms of
-Paragraphs 1 and 2 above provided that you also do one of the following:
-
-    a) accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of
-    Paragraphs 1 and 2 above; or,
-
-    b) accompany it with a written offer, valid for at least three
-    years, to give any third party free (except for a nominal charge
-    for the cost of distribution) a complete machine-readable copy of the
-    corresponding source code, to be distributed under the terms of
-    Paragraphs 1 and 2 above; or,
-
-    c) accompany it with the information you received as to where the
-    corresponding source code may be obtained.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form alone.)
-
-Source code for a work means the preferred form of the work for making
-modifications to it.  For an executable file, complete source code means
-all the source code for all modules it contains; but, as a special
-exception, it need not include source code for modules which are standard
-libraries that accompany the operating system on which the executable
-file runs, or for standard header files or definitions files that
-accompany that operating system.
-
-  4. You may not copy, modify, sublicense, distribute or transfer the
-Program except as expressly provided under this General Public License.
-Any attempt otherwise to copy, modify, sublicense, distribute or transfer
-the Program is void, and will automatically terminate your rights to use
-the Program under this License.  However, parties who have received
-copies, or rights to use copies, from you under this General Public
-License will not have their licenses terminated so long as such parties
-remain in full compliance.
-
-  5. By copying, distributing or modifying the Program (or any work based
-on the Program) you indicate your acceptance of this license to do so,
-and all its terms and conditions.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the original
-licensor to copy, distribute or modify the Program subject to these
-terms and conditions.  You may not impose any further restrictions on the
-recipients' exercise of the rights granted herein.
-
-  7. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of the license which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-the license, you may choose any version ever published by the Free Software
-Foundation.
-
-  8. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	Appendix: How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to humanity, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these
-terms.
-
-  To do so, attach the following notices to the program.  It is safest to
-attach them to the start of each source file to most effectively convey
-the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) 19yy  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 1, or (at your option)
-    any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) 19xx name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the
-appropriate parts of the General Public License.  Of course, the
-commands you use may be called something other than `show w' and `show
-c'; they could even be mouse-clicks or menu items--whatever suits your
-program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  program `Gnomovision' (a program to direct compilers to make passes
-  at assemblers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-That's all there is to it!
End of COPYING
echo README 1>&2
sed 's/^-//' >README <<'End of README'
-Read "INSTALL" for information on getting this shell running.
-
-zsh is free software.  See the file COPYING for copying permission.
-
-	This shell was "developed" by me, Paul Falstad, a sophomore at Princeton
-University.  I borrowed _heavily_ from ksh, bash, tcsh, sh, and csh, as
-well as adding a few (IMHO) useful features.  zsh was at first intended
-to be a subset of csh for the Commodore Amiga, but the project sort of
-ballooned; now I want it to be a cross between ksh and tcsh.  It should
-be a powerful "command and programming language" that is well-designed
-and logical (like ksh), but it should also be built for humans (like
-tcsh), with all the neat features like spell checking, login/logout
-watching and termcap support that are probably too weird to make it into
-an AT&T product.  This version of the shell has fallen far short of that
-goal; I just wanted to release _something_, because this is obviously
-going to be an extremely long project.
-
-	This is version v1.0 of zsh.  I incorporated the GNU "readline"
-editor, written by Brian Fox, into the shell, just to make my life
-temporarily easier.  I made lots of changes to it, so if there are any
-bugs in the editor, they're probably my fault.  readline will not be a
-part of the next version of zsh.
-
-	If anyone has any questions, suggestions, comments, bugs, flames, or
-any other mail of any kind, send it to pfalstad@phoenix.princeton.edu.
-Thanks to Kartik Subbarao, Daniel Bernstein ("Yay.  So sell it."),
-Kennedy Lemke, Chet Ramey (for the bash man page, and for putting features
-in the man page that weren't in our version of bash), Brian Fox (for
-helping me put off a lot of work, and for writing bash), Richard M. Stallman
-(for gdb and gcc; not for emacs though ;-) ) and many others.
-
End of README
echo INSTALL 1>&2
sed 's/^-//' >INSTALL <<'End of INSTALL'
-I was not able to port zsh to many platforms because I don't have
-accounts on many platforms.  It shouldn't be too much trouble if you
-manage to decipher my code.  I have tested zsh on SunOS 4.1, SunOS 4.0.3,
-4.3BSD UNIX.
-
-You need to edit the files config.h, config.local.h, makefile, and
-readline/Makefile.  The comments should make clear what you have to do.
-Note that the files in the readline directory have been greatly
-modified, so you can't just copy over your changes from bash if you
-have it installed.
-
-Once you have done that, you might be able to do a make without any
-problem.  If you have trouble, and can't get zsh to work, send me mail,
-and I'll try to help.  If anyone manages to get zsh ported to some other
-platform, please mail me so I can tell other people about your changes
-and incorporate them into the next version.
-
End of INSTALL
echo makefile 1>&2
sed 's/^-//' >makefile <<'End of makefile'
-#! /bin/make -f
-#
-#	makefile for zsh
-#
-#	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.
-#
-OBJS=hist.o glob.o table.o subst.o builtin.o loop.o vars.o\
-parse.o lex.o init.o jobs.o exec.o zhistory.o utils.o math.o test.o
-READLINE=readline/funmap.o readline/keymaps.o readline/readline.o
-BINDIR=/usr/local/bin
-MANDIR=/usr/local/man/man1
-CFLAGS=-O -fstrength-reduce -fomit-frame-pointer -finline-functions \
-	-fsigned-char -fdelayed-branch
-CC=gcc
-ZSHPATH=zsh
-THINGS_TO_TAR=zsh.1 COPYING README INSTALL makefile sample.zshrc \
-sample.zlogin sample.zshrc.mine sample.zlogin.mine \
-alias.pro builtin.c builtin.pro config.h config.local.h \
-exec.c exec.pro funcs.h glob.c glob.pro hist.c hist.pro init.c \
-init.pro jobs.c jobs.pro lex.c lex.pro loop.c loop.pro math.c \
-math.pro parse.c parse.pro subst.c subst.pro table.c \
-table.pro test.c test.pro utils.c utils.pro vars.c vars.pro zhistory.c \
-readline/chardefs.h readline/emacs_keymap.c \
-readline/funmap.c readline/history.h readline/keymaps.c \
-readline/keymaps.h readline/readline.c readline/readline.h \
-readline/vi_keymap.c readline/vi_mode.c readline/Makefile \
-zsh.h proto
-
-.c.o:
-	$(CC) $(CFLAGS) -c -o $*.o $<
-
-$(ZSHPATH): $(OBJS) $(READLINE)
-	$(CC) -o $(ZSHPATH) $(OBJS) $(READLINE) -s -ltermcap
-
-$(OBJS): config.h
-
-zhistory.o: readline/history.h
-
-$(READLINE):
-	cd readline;make
-
-clean:
-	rm -f *.o zsh core readline/*.o
-
-install: zsh
-	install -s -m 755 zsh $(BINDIR)
-	install -m 444 zsh.1 $(MANDIR)
-
-tar: zsh.tar.Z
-
-zsh.tar: $(THINGS_TO_TAR)
-	tar -cf zsh.tar $(THINGS_TO_TAR)
-
-zsh.tar.Z: zsh.tar
-	compress -f zsh.tar
-
-shar: $(THINGS_TO_TAR)
-	bundle $(THINGS_TO_TAR) > zsh.shar
-
End of makefile
echo sample.zshrc 1>&2
sed 's/^-//' >sample.zshrc <<'End of sample.zshrc'
-setenv() { export $1=$2 }
-
-umask 022
-
-PATH=$HOME/scr:$HOME/bin/$HOSTTYPE:/usr/local/bin:/usr/ucb:\
-/usr/bin:/bin:/usr/local/bin/X11:/usr/etc:/etc
-CDPATH=$HOME:/usr:/
-export MANPATH=/usr/man:/usr/local/man
-
-HISTSIZE=50
-setopt ignoreeof
-
-PROMPT='%n@%m [%h] %# '
-
-alias a alias
-
-a vi. 	'vi ~/.cshrc'
-a s. 	'. ~/.cshrc'
-a more. 'more ~/.cshrc'
-
-chpwd() { pwd; ls -F }
-lsl() { ls -algF $* | more }
-
-a back cd -
-a h history
-a cls 	/usr/ucb/clear
-a type 	cat
-a copy 	cp
-a move 	mv
-a del 	rm
-a lo 	exit
-a lsa 	'ls -aF'
-a dir   'ls -l'
-a ll    'ls -F'
-
End of sample.zshrc
echo sample.zlogin 1>&2
sed 's/^-//' >sample.zlogin <<'End of sample.zlogin'
-eval $(tset -Q -s '?xterm')
-stty dec crt kill ^U dsusp ^X
-msgs -q
-date
-biff y
-
-WATCH=$(echo $(<~/.friends) | tr ' ' :)
-MAIL=/usr/spool/mail/$USERNAME
-export DISPLAY=$(hostname):0.0
-
-limit coredumpsize 0
-/usr/games/fortune
-uptime
End of sample.zlogin
echo sample.zshrc.mine 1>&2
sed 's/^-//' >sample.zshrc.mine <<'End of sample.zshrc.mine'
-#
-# my rc file for zsh
-#
-PATH=~/scr:~/bin/$HOSTTYPE:/usr/princeton/bin:/usr/ucb:/usr/bin:/bin:\
-/u/maruchck/scr:/u/cs320/bin:/u/maruchck/bin:\
-/usr/princeton/bin/X11:/usr/etc:/etc
-CDPATH=~:~/src/cs320:~/src
-umask 022
-alias a alias
-a pd pushd
-a pop popd
-limit core 0
-a c cp
-a grep egrep
-a ps sps
-a j jobs
-a hide 'ARGV0=$(randline ~/pub/strings) '
-a rn hide /usr/princeton/bin/rn.4.1
-a v mv
-a t cat
-a where hostname'; echo >/dev/null'
-a l ls -AF
-a m make
-a mm hide less 
-a talk hide talk
-a h history
-a a.out ./a.out
-a more less
-a strings strings -
-a lock lock -p
-a nw 'l -ltr | tail'
-a -a 'M' \| less
-a -a 'GF' \| fgrep -f ~/.friends
-a -a 'sub' subbarao
-a -a 'mjm' maruchck
-a -a 'paswd' '<(ypcat passwd)'
-a -a 'cex' '/u/pup/centrex'
-a rable ls -AFltrd '*(R)'
-a nrable ls -AFltrd '*(^R)'
-a ';' vi
-a 0 vi
-a '<<' more
-mostglob egrep sed
-noglob find
-PROMPT='Z %h %M:%~ '
-FCEDIT=vi
-LESSTERM=$(echo $TERMCAP | sed s/:ti=[^:]*:te=[^:]*:/:ti=:te=:/)
-a less TERMCAP='"$LESSTERM"' /usr/princeton/bin/less
-zsh=~/src/zsh
-a k9 kill -9
-cx() { chmod +x $* }
-acx() { chmod 755 $* }
-mere() { nroff -man -Tman $1 | less -s }
-
-[ `tty` = /dev/console ] || {
-	PERIOD=40
-	periodic() {
-		echo checking news...  # check news every 40 minutes
-		rn -c
-	}
-}
-
-randline() {
-	integer z;
-	z=$(wc -l <$1)
-	sed -n $[RANDOM%z+1]p $1
-	unset z
-}
-
-eval "proto () { $(grep -v '^#' ~/scr/proto) }"
-
-snoop() {
-	(( $# )) || set `users`
-	fgrep -i -f </u/pup/st{udents,aff} <(
-		for i
-		do
-			ypmatch $i passwd
-		done | cut -d: -f5 | cut -d, -f1 |
-			awk '{ printf "%s,%s\n",$NF,substr($1,1,1) }') 
-}
-
-MAIL=/usr/spool/mail/pfalstad
-MAILCHECK=30
-HISTSIZE=600
-setopt notify globdots autolist correct dextract pushdtohome cdablevars
-unsetopt bgnice
-WATCH=$(echo $(<~/.friends) | tr ' ' :)
-WATCHFMT='%n %a %l from %m at %t.'
-LOGCHECK=0
-
-[ -t ] && {
-	(cd ; hostname >! .where)
-}
-
-export MANPATH=/usr/man:/usr/princeton/man:/u/cad/man
-
-setenv() { export $1=$2 }
-
End of sample.zshrc.mine
echo sample.zlogin.mine 1>&2
sed 's/^-//' >sample.zlogin.mine <<'End of sample.zlogin.mine'
-#
-# my login file for zsh
-#
-cd
-ls -l /etc/motd
-stty dec new cr0
-eval $(tset -s -Q '?xterm')
-stty -tabs
-umask 022
-export MAIL=/usr/spool/mail/$USER
-MAILCHECK=60
-# biff y
-msgs -fp
-uptime
-/usr/games/fortune
-log
-echo Thought for the day: $(randline ~/pub/commands)
-from 2>/dev/null
-cat .todo
-cat '. '
-echo last login $(date) on $(hostname) >! .' '
End of sample.zlogin.mine
echo alias.pro 1>&2
sed 's/^-//' >alias.pro <<'End of alias.pro'
-char *dynread(char stop);
-int filesub(void **namptr);
-char *gethome(char *user,int len);
-char *completehome(char *user,int len);
-char *getsparmval(char *s,int len);
-void setparml(char *s,int len,char *v);
-void parmsub(table list);
-void parminsall(table l,Node *nn,char **aptr,char **bptr);
-void comminsall(table l,Node *nn,char **aptr,char **bptr);
-void parmsuber(void **aptr,char **bptr);
-void modify(void **str,char **ptr);
-void tabmodify(table tab,char **ptr);
-int napply(int (*func)(void **),table list);
-int napplysplit(int (*func)(void **),table list);
-void split(Node node,table list);
-char *dstackent(int val);
-void doshfuncs(comm comm);
-void execshfunc(comm comm);
-struct anode *mkanode(char *txt,int cmflag);
-char *docompsubs(char *str,int *i);
-void docmdsubs(char **str);
-void dovarsubs(char **str);
End of alias.pro
echo builtin.c 1>&2
sed 's/^-//' >builtin.c <<'End of builtin.c'
-/*
-
-	builtin.c - handles builtin commands
-
-	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"
-#include <sys/signal.h>
-#include <sys/fcntl.h>
-#include <sys/errno.h>
-#include <utmp.h>
-#define MAXPATHLEN 1024
-
-int echo(comm comm)
-{
-table list;
-char *str;
-int nline = 1;
- 
-	list = comm->args;
-	if (full(list))
-		if (!strcmp("--",list->first->dat))
-			free(getnode(list));
-		else if (!strcmp("-n",list->first->dat))
-			{
-			free(getnode(list));
-			nline = 0;
-			}
-	if (str = getnode(list))
-		{
-		printf("%s",str);
-		free(str);
-		while (str = getnode(list))
-			{
-			printf(" %s",str);
-			free(str);
-			}
-		}
-	if (nline)
-		printf("\n");
-	return 0;
-}
-
-/* print the directory stack */
-
-void pdstack(void)
-{
-Node node;
-
-	printdir(cwd);
-	for (node = dirstack->first; node; node = node->next)
-		{
-		putchar(' ');
-		printdir(node->dat);
-		}
-	putchar('\n');
-}
-
-/* exit */
-
-int zexit(comm comm)
-{
-	if (interact)
-		if (!stopmsg)
-			{
-			checkjobs();
-			if (stopmsg)
-				{
-				stopmsg = 2;
-				return 1;
-				}
-			}
-		else
-			killrunjobs();
-	if (islogin && unset(NORCS))
-		sourcehome(".zlogout");
-	if (comm && full(comm->args))
-		lastval = atoi(getnode(comm->args));
-	if (sigtrapped[SIGEXIT])
-		dotrap(SIGEXIT);
-	exit(lastval); return 0;
-}
-
-/* return */
-
-int zreturn(comm comm)
-{
-	if (full(comm->args))
-		lastval = atoi(getnode(comm->args));
-	retflag = 1;
-	return lastval;
-}
-
-int logout(comm comm)
-{
-	if (!islogin)
-		{
-		zerrnam("logout","not login shell");
-		return 1;
-		}
-	return zexit(comm);
-}
-
-int Unset(comm comm)
-{
-table list = comm->args;
-char *s;
- 
-	while (full(list))
-		{
-		s = getnode(list);
-		unsetparm(s);
-		free(s);
-		}
-	return 0;
-}
-
-int set(comm comm)
-{
-char *s,*t;
-
-	if (!full(comm->args))
-		{
-		char **p = environ;
-
-		while (*p)
-			puts(*p++);
-		listhtable(parmhtab,(void (*)(char *,char *)) pparm);
-		return 0;
-		}
-	s = getnode(comm->args);
-	t = getnode(pparms);
-	freetable(pparms,freestr);
-	pparms = newtable();
-	addnode(pparms,t);
-	while (s)
-		{
-		addnode(pparms,s);
-		s = getnode(comm->args);
-		}
-	return 0;
-}
-
-struct option {
-	char *name;
-	char id;
-	};
-
-static struct option optns[] = {
-	"clobber",'1',
-	"nobadpattern",'2',
-	"nonomatch",'3',
-	"globdots",'4',
-	"notify",'5',
-	"allexport",'a',
-	"errexit",'e',
-	"bgnice",'6',
-	"ignoreeof",'7',
-	"keyword",'k',
-	"markdirs",'8',
-	"monitor",'m',
-	"noexec",'n',
-	"noglob",'F',
-	"norcs",'f',
-	"shinstdin",'s',
-	"nounset",'u',
-	"verbose",'v',
-	"xtrace",'x',
-	"interactive",'i',
-	"autolist",'9',
-	"correct",'0',
-	"dextract",'A',
-	"nobeep",'B',
-	"printexitvalue",'C',
-	"pushdtohome",'D',
-	"pushdsilent",'E',
-	"nullglob",'G',
-	"rmstarsilent",'H',
-	"ignorebraces",'I',
-	"cdablevars",'J',
-	"nobanghist",'K',
-	NULL,0
-};
-
-int setopt(comm comm)
-{
-	return csetopt(comm,0);
-}
-
-int unsetopt(comm comm)
-{
-	return csetopt(comm,1);
-}
-
-/* common code for setopt and unsetopt */
-
-int csetopt(comm comm,int isun)
-{
-char *s,*os,*cmd;
-int flag;
-struct option *opp;
-
-	cmd = (isun) ? "unsetopt" : "setopt";
-	if (!full(comm->args))
-		{
-		if (isun)
-			return 0;
-		for (opp = optns; opp->name; opp++)
-			if (opts[opp->id] == OPT_SET)
-				puts(opp->name);
-		return 0;
-		}
-	while ((os = s = getnode(comm->args)) && ((flag = *s == '-') || *s == '+'))
-		{
-		while (*++s)
-			if (*s == INTERACTIVE || *s == MONITOR)
-				zerrnam(cmd,"can't change that option");
-			else if (opts[*s & 0x7f] != OPT_INVALID)
-				opts[*s & 0x7f] = (flag^isun) ? OPT_SET : OPT_UNSET;
-			else
-				zerrnam(cmd,"illegal option: %c",*s);
-		free(os);
-		}
-	if (!s)
-		return 0;
-	while (s)
-		{
-		for (opp = optns; opp->name; opp++)
-			if (!strcmp(opp->name,s))
-				break;
-		if (opp->name)
-			{
-			if (opp->id == INTERACTIVE || opp->id == MONITOR)
-				zerrnam(cmd,"can't change that option");
-			else
-				opts[opp->id] = (isun) ? OPT_UNSET : OPT_SET;
-			}
-		else
-			{
-			zerrnam(cmd,"no such option: %s",s);
-			free(s);
-			return 1;
-			}
-		free(s);
-		s = getnode(comm->args);
-		}
-	return 0;
-}
-
-/* print a positional parameter */
-
-void pparm(char *s,struct pmnode *t)
-{
-	if (s && t)
-		if (t->isint)
-			printf("%s=%ld\n",s,t->u.val);
-		else
-			{
-			printf("%s=",s);
-			niceprint(t->u.str);
-			putchar('\n');
-			}
-}
-
-int dirs(comm comm)
-{
-	if (comm->args->first)
-		{
-		if (dirstack)
-			freetable(dirstack,freestr);
-		dirstack = comm->args;
-		comm->args = NULL;
-		}
-	else
-		pdstack();
-	return 0;
-}
-
-/* call func once for each entry in a hash table */
-
-void listhtable(htable ht,void (*func)(char *,char *))
-{
-int t0;
-struct hnode *hn;
-
-	for (t0 = ht->hsize-1; t0 >= 0; t0--)
-		for (hn = ht->nodes[t0]; hn; hn = hn->hchain)
-			func(hn->nam,hn->dat);
-}
-
-/* print an alias (used with listhtable) */
-
-void palias(char *s,struct anode *t)
-{
-	if (t && t->cmd >= 0)
-		{
-		printf((t->cmd) ? "alias %-13s " : "alias -a %-10s ",s);
-		niceprint(t->text);
-		putchar('\n');
-		}
-}
-
-/* print a shell function (used with listhtable) */
-
-void pshfunc(char *s,list l)
-{
-char *t;
-
-	t = getltext(l);
-	untokenize(t);
-	printf("%s() {\n%s\n}\n",s,t);
-	free(t);
-}
-
-void niceprint(char *s)
-{
-	niceprintf(s,stdout);
-}
-
-void niceprintf(char *s,FILE *f)
-{
-	for (; *s; s++)
-		{
-		if (*s >= 32 && *s <= 126)
-			fputc(*s,f);
-		else if (*s == '\n')
-			{
-			putc('\\',f);
-			putc('n',f);
-			}
-		else
-			{
-			putc('^',f);
-			fputc(*s | 0x40,f);
-			}
-		}
-}
-
-/* build a command line from a linked list */
-
-char *buildline(table t)
-{
-char *str = strdup(""),*s,*os;
-
-	while (s = getnode(t))
-		{
-		os = str;
-		str = (*os) ? tricat(os," ",s) : strdup(s);
-		free(s);
-		free(os);
-		}
-	return str;
-}
-
-int Alias(comm comm)
-{
-char *s1,*s2;
-int anyflag = 0;
-
-	if (!(s1 = getnode(comm->args)))
-		{
-		listhtable(alhtab,(void (*)(char *,char *)) palias);
-		return 0;
-		}
-	if (!strcmp(s1,"-a"))
-		{
-		anyflag = 1;
-		free(s1);
-		if (!(s1 = getnode(comm->args)))
-			{
-			zerrnam("alias","alias -a requires 2 arguments");
-			return 1;
-			}
-		}
-	if (!comm->args->first)
-		{
-		palias(s1,gethnode(s1,alhtab));
-		free(s1);
-		return 0;
-		}
-	s2 = buildline(comm->args);
-	addhnode(s1,mkanode(s2,!anyflag),alhtab,freeanode);
-	return 0;
-}
-
-int cd(comm comm)
-{
-	if (!full(comm->args))
-		return chcd("cd",strdup(getparm("HOME")));
-	if (comm->args->first->next)
-		{
-		char *s,*t,*u,*v;
-		int sl,tl;
-
-		if (comm->args->first->next->next)
-			{
-			zerrnam("cd","too many arguments");
-			return 1;
-			}
-		s = getnode(comm->args);
-		t = getnode(comm->args);
-		if (!(u = (char *) strstr(cwd,s)))
-			{
-			zerrnam("cd","string not in pwd: %s",s);
-			return 1;
-			}
-		sl = strlen(s);
-		tl = strlen(t);
-		v = zalloc((u-cwd)+tl+strlen(u+sl)+1);
-		strncpy(v,cwd,u-cwd);
-		strcpy(v+(u-cwd),t);
-		strcat(v,u+sl);
-		free(s);
-		free(t);
-		return chcd("cd",v);
-		}
-	return chcd("cd",getnode(comm->args));
-}
-
-int dot(comm comm)
-{
-char *s;
-
-	if (!full(comm->args))
-		return 1;
-	s = getnode(comm->args);
-	if (source(s))
-		{
-		zerrnam(".","%e: %s",errno,s);
-		free(s);
-		return 1;
-		}
-	free(s);
-	return 0;
-}
-
-int Umask(comm comm)
-{
-char *s,*t;
-int t0;
-
-	if (!full(comm->args))
-		{
-		t0 = umask(0);
-		umask(t0);
-		printf("%03o\n",t0);
-		return 0;
-		}
-	s = getnode(comm->args);
-	t0 = strtol(s,&t,8);
-	if (*t)
-		{
-		zerrnam("umask","bad umask");
-		free(s);
-		return 1;
-		}
-	umask(t0);
-	free(s);
-	return 0;
-}
-
-int which(comm comm)
-{
-struct chnode *chn;
-struct anode *a;
-char *str = getnode(comm->args),*cnam;
-
-	if (!str)
-		{
-		zerrnam("which","argument required");
-		return 1;
-		}
-	if ((a = gethnode(str,alhtab)) && a->cmd)
-		{
-		if (a->cmd < 0)
-			printf("%s: shell reserved word\n",str);
-		else
-			printf("%s: aliased to %s\n",str,a->text);
-		free(str);
-		return 0;
-		}
-	if (gethnode(str,shfunchtab))
-		printf("%s: shell function\n",str);
-	else if (chn = gethnode(str,chtab))
-		{
-		if (chn->type != BUILTIN)
-			puts(chn->u.nam);
-		else
-			printf("%s: shell built-in command\n",str);
-		}
-	else if (!(cnam = findcmd(str)))
-		{
-		zerr("command not found: %s",str);
-		free(str);
-		return 1;
-		}
-	else
-		puts(cnam);
-	free(str);
-	return 0;
-}
- 
-int popd(comm comm)
-{
-int val = 0;
-char *s;
-Node node;
-
-	if (comm->args->first && *(s = comm->args->first->dat) == '+')
-		val = atoi(s+1);
-	if (val--)
-		{
-		if (val < 0)
-			node = dirstack->last;
-		else
-			for (node = dirstack->first; val && node; node = node->next,
-				val--);
-		free(remnode(dirstack,node));
-		if (unset(PUSHDSILENT))
-			pdstack();
-		return 0;
-		}
-	else
-		{
-		if (!full(dirstack))
-			{
-			zerrnam("popd","dir stack empty");
-			return 1;
-			}
-		val = chcd("popd",getnode(dirstack));
-		if (unset(PUSHDSILENT))
-			pdstack();
-		return val;
-		}
-}
- 
-int pushd(comm comm)
-{
-char *s;
-int num;
-
-	if (comm->args->first)
-		{
-		s = getnode(comm->args);
-		
-		if (*s == '+')
-			{
-			if (!(num = atoi(s+1)))
-				{
-				free(s);
-				return 0;
-				}
-			free(s);
-			if (isset(DEXTRACT))
-				{
-				Node n = dirstack->first;
-
-				insnode(dirstack,(Node) dirstack,strdup(cwd));
-				while (--num && n)
-					n = n->next;
-				if (!n)
-					{
-					zerrnam("pushd","not that many dir stack entries");
-					return 1;
-					}
-				insnode(dirstack,(Node) dirstack,remnode(dirstack,n));
-				}
-			else
-				{
-				addnode(dirstack,strdup(cwd));
-				while(--num)
-					addnode(dirstack,getnode(dirstack));
-				}
-			num = chcd("pushd",getnode(dirstack));
-			if (unset(PUSHDSILENT))
-				pdstack();
-			return num;
-			}
-		pushnode(dirstack,strdup(cwd));
-		num = chcd("pushd",s);
-		if (num)
-			free(getnode(dirstack));
-		else if (unset(PUSHDSILENT))
-			pdstack();
-		return num;
-		}
-	else
-		{
-		char *s;
-		
-		if (isset(PUSHDTOHOME))
-			s = strdup(getparm("HOME"));
-		else
-			s = getnode(dirstack);
-		if (!s)
-			{
-			zerrnam("pushd","dir stack empty");
-			return 1;
-			}
-		pushnode(dirstack,strdup(cwd));
-		num = chcd("pushd",s);
-		if (num)
-			free(getnode(dirstack));
-		else if (unset(PUSHDSILENT))
-			pdstack();
-		return num;
-		}
-}
-
-/* common code for pushd, popd, cd */
-
-int chcd(char *cnam,char *cd)
-{
-char *s,*t;
-char buf[MAXPATHLEN],*new = cd;
-int t0,val,esav,pnew = 0;
-
-	if (cd[0] == '-' && !cd[1])
-		{
-		free(cd);
-		cd = getparm("OLDPWD");
-		cd = strdup((cd) ? cd : ".");
-		}
-	if (*cd == '/')
-		{
-		val = chdir(new = cd);
-		esav = errno;
-		}
-	else
-		for (t0 = 0; t0 != cdpathct; t0++)
-			{
-			sprintf(buf,"%s/%s",cdpath[t0],cd);
-			if ((val = chdir(new = buf)) != -1)
-				{
-				if (t0)
-					pnew = 1;
-				break;
-				}
-			if (t0 && errno != ENOENT && errno != ENOTDIR)
-				zerrnam(cnam,"warning: %e: %s",errno,buf);
-			if (!t0)
-				esav = errno;
-			}
-	if (val == -1 && errno == ENOENT)
-		{
-		t = strdup(cd);
-		if (isset(CDABLEVARS) && (s = getparm(t)) && *s == '/')
-			if (chdir(new = s) != -1)
-				{
-				val = 0;
-				pnew = 1;
-				goto goneto;
-				}
-		free(t);
-		zerrnam(cnam,"%e: %s",esav,cd);
-		free(cd);
-		return 1;
-		}
-goneto:
-	if (val == -1)
-		{
-		zerrnam(cnam,"%e: %s",esav,cd);
-		free(cd);
-		return 1;
-		}
-	else
-		{
-		list l;
-
-		if (cwd)
-			setparm(strdup("OLDPWD"),cwd,0,0);
-		cwd = findcwd(new);
-		setparm(strdup("PWD"),strdup(cwd),0,0);
-		if (pnew)
-			{
-			printdir(cwd);
-			putchar('\n');
-			}
-		if (l = gethnode("chpwd",shfunchtab))
-			newrunlist(l);
-		}
-	return 0;
-}
- 
-int shift(comm comm)
-{
-char *s;
-int sh = 1;
- 
-	if (comm->args->first && (s = comm->args->first->dat))
-		sh = atoi(s);
-	while (sh-- && pparms->first->next)
-		remnode(pparms,pparms->first->next);
-	return 0;
-}
- 
-int unhash(comm comm)
-{
-char *s;
- 
-	if (!(s = getnode(comm->args)))
-		{
-		zerrnam("unhash","argument required");
-		return 1;
-		}
-	while (s)
-		{
-		if (!gethnode(s,chtab))
-			{
-			zerrnam("unhash","not in command table: %s",s);
-			return 1;
-			}
-		free(remhnode(s,chtab));
-		free(s);
-		s = getnode(comm->args);
-		}
-	return 0;
-}
-
-int rehash(comm comm)
-{
-	parsepath();
-	return 0;
-}
-
-int hash(comm comm)
-{
-char *s,*t;
-struct chnode *chn;
-
-	if (!(s = getnode(comm->args)) || !(t = getnode(comm->args)))
-		{
-		zerrnam("hash","not enough arguments");
-		if (s)
-			free(s);
-		return 1;
-		}
-	chn = alloc(sizeof(struct chnode));
-	chn->type = EXCMD_PREDOT;
-	chn->globstat = GLOB;
-	chn->u.nam = t;
-	addhnode(s,chn,chtab,freechnode);
-	return 0;
-}
-
-int Break(comm comm)
-{
-char *s;
- 
-	if (!loops)
-		{
-		zerrnam("break","not in loop");
-		return 1;
-		}
-	if (!(s = getnode(comm->args)))
-		breaks = 1;
-	else if (atoi(s))
-		{
-		breaks = atoi(s);
-		free(s);
-		}
-	else
-		{
-		zerrnam("break","numeric argument required");
-		free(s);
-		return 1;
-		}
-	return 0;
-}
- 
-int colon(comm comm)
-{
-	return 0;
-}
- 
-int Glob(comm comm)
-{
-struct chnode *chn;
-char *s;
- 
-	while (s = getnode(comm->args))
-		{
-		chn = gethnode(s,chtab);
-		free(s);
-		if (chn)
-			chn->globstat = GLOB;
-		}
-	return 0;
-}
- 
-int noglob(comm comm)
-{
-struct chnode *chn;
-char *s;
- 
-	while (s = getnode(comm->args))
-		{
-		chn = gethnode(s,chtab);
-		free(s);
-		if (chn)
-			chn->globstat = NOGLOB;
-		}
-	return 0;
-}
- 
-int mostglob(comm comm)
-{
-struct chnode *chn;
-char *s;
- 
-	while (s = getnode(comm->args))
-		{
-		chn = gethnode(s,chtab);
-		free(s);
-		if (chn)
-			chn->globstat = MOSTGLOB;
-		}
-	return 0;
-}
-
-int unfunction(comm comm)
-{
-char *s1;
-list l;
-
-	while (s1 = getnode(comm->args))
-		{
-		unsettrap(s1);
-		if (l = remhnode(s1,shfunchtab))
-			freelist(l);
-		free(s1);
-		}
-	return 0;
-}
-
-int unalias(comm comm)
-{
-char *s1;
-struct anode *an;
-
-	while (s1 = getnode(comm->args))
-		{
-		if (an = remhnode(s1,alhtab))
-			freeanode(an);
-		free(s1);
-		}
-	return 0;
-}
-
-/* != 0 if s is a prefix of t */
-
-int prefix(char *s,char *t)
-{
-	while (*s && *t && *s == *t) s++,t++;
-	return (!*s);
-}
-
-/* convert %%, %1, %foo, %?bar? to a job number */
-
-int getjob(char *s,char *prog)
-{
-int t0,retval;
-char *os = s;
-
-	if (*s++ != '%')
-		{
-		zerrnam(prog,"bad job specifier");
-		retval = -1; goto done;
-		}
-	if (*s == '%' || *s == '+' || !*s)
-		{
-		if (topjob == -1)
-			{
-			zerrnam(prog,"no current job");
-			retval = -1; goto done;
-			}
-		retval = topjob; goto done;
-		}
-	if (*s == '-')
-		{
-		if (prevjob == -1)
-			{
-			zerrnam(prog,"no previous job");
-			retval = -1; goto done;
-			}
-		retval = prevjob; goto done;
-		}
-	if (isdigit(*s))
-		{
-		t0 = atoi(s);
-		if (t0 && t0 < MAXJOB && jobtab[t0].stat && t0 != curjob)
-			{ retval = t0; goto done; }
-		zerrnam(prog,"no such job");
-		retval = -1; goto done;
-		}
-	if (*s == '?')
-		{
-		struct procnode *pn;
-
-		for (t0 = 0; t0 != MAXJOB; t0++)
-			if (jobtab[t0].stat && t0 != curjob)
-				for (pn = jobtab[t0].procs; pn; pn = pn->next)
-					if (strstr(pn->text,s+1))
-						{ retval = t0; goto done; }
-		zerrnam(prog,"job not found: %s",s);
-		retval = -1; goto done;
-		}
-	for (t0 = 0; t0 != MAXJOB; t0++)
-		if (jobtab[t0].stat && jobtab[t0].procs && t0 != curjob && 
-				prefix(s,jobtab[t0].procs->text))
-			{ retval = t0; goto done; }
-	zerrnam(prog,"job not found: %s",s);
-	retval = -1;
-done:
-	free(os);
-	return retval;
-}
-
-int fg(comm comm)
-{
-char *s1;
-int ocj = curjob,job;
-
-	scanjobs();
-	if (!jobbing)
-		{
-		zerr("no job control in this shell.");
-		return 1;
-		}
-	if (s1 = getnode(comm->args))
-		job = getjob(s1,"fg");
-	else
-		{
-		if (topjob == -1 || topjob == curjob)
-			{
-			zerrnam("fg","no current job");
-			return 1;
-			}
-		job = topjob;
-		}
-	if (job == -1)
-		return 1;
-	makerunning(jobtab+job);
-	if (topjob == job)
-		{
-		topjob = prevjob;
-		prevjob = job;
-		}
-	if (prevjob == job)
-		setprevjob();
-	printjob(jobtab+job,-1);
-	curjob = job;
-	if (strcmp(jobtab[job].cwd,cwd))
-		{
-		printf("(pwd: ");
-		printdir(jobtab[job].cwd);
-		printf(")\n");
-		}
-	settyinfo(&jobtab[job].ttyinfo);
-	attachtty(jobtab[job].gleader);
-	killpg(jobtab[job].gleader,SIGCONT);
-	waitjobs();
-	curjob = ocj;
-	return 0;
-}
-
-int bg(comm comm)
-{
-char *s1;
-int job,stopped;
-
-	scanjobs();
-	if (!jobbing)
-		{
-		zerr("no job control in this shell.");
-		return 1;
-		}
-	if (s1 = getnode(comm->args))
-		job = getjob(s1,"bg");
-	else
-		{
-		if (topjob == -1 || topjob == curjob)
-			{
-			zerrnam("bg","no current job");
-			return 1;
-			}
-		job = topjob;
-		}
-	if (job == -1)
-		return 1;
-	if (!(jobtab[job].stat & STAT_STOPPED))
-		{
-		zerrnam("bg","job already in background");
-		return 1;
-		}
-	stopped = jobtab[job].stat & STAT_STOPPED;
-	if (stopped)
-		makerunning(jobtab+job);
-	if (topjob == job)
-		{
-		topjob = prevjob;
-		prevjob = -1;
-		}
-	if (prevjob == job)
-		prevjob = -1;
-	if (prevjob == -1)
-		setprevjob();
-	if (topjob == -1)
-		{
-		topjob = prevjob;
-		setprevjob();
-		}
-	printjob(jobtab+job,(stopped) ? -1 : 0);
-	if (stopped)
-		killpg(jobtab[job].gleader,SIGCONT);
-	return 0;
-}
-
-int jobs(comm comm)
-{
-int job,lng = 0;
-
-	if (full(comm->args))
-		{
-		if (comm->args->first->next || (strcmp(comm->args->first->dat,"-l")
-				&& strcmp(comm->args->first->dat,"-p")))
-			{
-			zerrnam("jobs","usage: jobs [ -lp ]");
-			return 1;
-			}
-		lng = (strcmp(comm->args->first->dat,"-l")) ? 2 : 1;
-		}
-	for (job = 0; job != MAXJOB; job++)
-		if (job != curjob && jobtab[job].stat)
-			printjob(job+jobtab,lng);
-	stopmsg = 2;
-	return 0;
-}
-
-int Kill(comm comm)
-{
-int sig = SIGTERM;
-char *s;
-
-	s = getnode(comm->args);
-	if (s && *s == '-')
-		{
-		if (isdigit(s[1]))
-			sig = atoi(s+1);
-		else
-			{
-			if (s[1] == 'l' && s[2] == '\0')
-				{
-				printf("%s",sigs[0]);
-				for (sig = 1; sig != SIGCOUNT; sig++)
-					printf(" %s",sigs[sig]);
-				putchar('\n');
-				return 0;
-				}
-			for (sig = 0; sig != SIGCOUNT; sig++)
-				if (!strcmp(sigs[sig],s+1))
-					break;
-			if (sig == SIGCOUNT)
-				{
-				zerrnam("kill","unknown signal: SIG%s",s+1);
-				zerrnam("kill","type kill -l for a list of signals");
-				return 1;
-				}
-			}
-		s = getnode(comm->args);
-		}
-	while (s)
-		{
-		if (*s == '%')
-			{
-			int job = getjob(s,"kill");
-
-			if (killjb(jobtab+job,sig) == -1)
-				{
-				zerrnam("kill","kill failed: %e",errno);
-				return 1;
-				}
-			if (jobtab[job].stat & STAT_STOPPED && sig == SIGCONT)
-				jobtab[job].stat &= ~STAT_STOPPED;
-			if (sig != SIGKILL)
-				killpg(jobtab[job].gleader,SIGCONT);
-			}
-		else
-			if (kill(atoi(s),sig) == -1)
-				{
-				zerrnam("kill","kill failed: %e");
-				return 1;
-				}
-		s = getnode(comm->args);
-		}
-	return 0;
-}
-
-int export(comm comm)
-{
-char *s,*t;
-struct pmnode *pm;
-
-	while (s = getnode(comm->args))
-		{
-		if (t = strchr(s,'='))
-			{
-			*t = '\0';
-			if (pm = gethnode(s,parmhtab))
-				freepm(remhnode(s,parmhtab));
-			*t = '=';
-			putenv(s);
-			}
-		else
-			{
-			if (!(pm = gethnode(s,parmhtab)))
-				{
-				if (!getenv(s))
-					{
-					zerrnam("export","parameter not set: %s",s);
-					free(s);
-					return 1;
-					}
-				}
-			else if (pm->isint)
-				{
-				zerrnam("export","can't export integer parameters");
-				free(s);
-				return 1;
-				}
-			else
-				{
-				t = tricat(s,"=",pm->u.str);
-				putenv(t);
-				free(remhnode(s,parmhtab));
-				}
-			}
-		}
-	return 0;
-}
-
-int integer(comm comm)
-{
-char *s,*t;
-struct pmnode *uu;
-
-	while (s = getnode(comm->args))
-		{
-		if (t = strchr(s,'='))
-			{
-			*t = '\0';
-			setparm(s,t+1,0,1);
-			*t = '=';
-			}
-		else
-			{
-			uu = gethnode(s,parmhtab);
-			if (uu)
-				{
-				if (!uu->isint)
-					{
-					uu->isint = 1;
-					uu->u.val = matheval(uu->u.str);
-					}
-				}
-			else
-				setiparm(s,0,1);
-			}
-		}
-	return 0;
-}
-
-static char *recs[] = {
-	"cputime","filesize","datasize","stacksize","coredumpsize",
-	"resident","descriptors"
-	};
-
-int limit(comm comm)
-{
-char *s;
-int hard = 0,t0,lim;
-long val;
-
-	if (!(s = getnode(comm->args)))
-		{
-		showlimits(0,-1);
-		return 0;
-		}
-	if (!strcmp(s,"-s"))
-		{
-		if (full(comm->args))
-			zerr("limit","arguments after -s ignored");
-		for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
-			if (setrlimit(t0,limits+t0) < 0)
-				zerr("limit","setrlimit failed: %e",errno);
-		return 0;
-		}
-	if (!strcmp(s,"-h"))
-		{
-		hard = 1;
-		free(s);
-		if (!(s = getnode(comm->args)))
-			{
-			showlimits(1,-1);
-			return 0;
-			}
-		}
-	while (s)
-		{
-		for (lim = -1, t0 = 0; t0 != RLIM_NLIMITS; t0++)
-			if (!strncmp(recs[t0],s,strlen(s)))
-				{
-				if (lim != -1)
-					lim = -2;
-				else
-					lim = t0;
-				}
-		if (lim < 0)
-			{
-			zerrnam("limit",
-				(lim == -2) ? "ambiguous resource specification: %s"
-								: "no such resource: %s",s);
-			free(s);
-			return 1;
-			}
-		free(s);
-		if (!(s = getnode(comm->args)))
-			{
-			showlimits(hard,lim);
-			return 0;
-			}
-		if (!lim)
-			{
-			char *ss = s;
-			
-			val = strtol(s,&s,10);
-			if (*s)
-				if ((*s == 'h' || *s == 'H') && !s[1])
-					val *= 3600L;
-				else if ((*s == 'm' || *s == 'M') && !s[1])
-					val *= 60L;
-				else if (*s == ':')
-					val = val*60+strtol(s+1,&s,10);
-				else
-					{
-					zerrnam("limit","unknown scaling factor: %s",s);
-					free(ss);
-					return 1;
-					}
-			}
-#ifdef RLIMIT_NOFILE
-		else if (lim == RLIMIT_NOFILE)
-			val = strtol(s,&s,10);
-#endif
-		else
-			{
-			char *ss = s;
-			
-			val = strtol(s,&s,10);
-			if (!*s || ((*s == 'k' || *s == 'K') && !s[1]))
-				val *= 1024L;
-			else if ((*s == 'M' || *s == 'm') && !s[1])
-				val *= 1024L*1024;
-			else
-				{
-				zerrnam("limit","unknown scaling factor: %s",s);
-				free(ss);
-				return 1;
-				}
-			free(ss);
-			}
-		if (hard)
-			if (val > limits[lim].rlim_max && geteuid())
-				{
-				zerrnam("limit","can't raise hard limits");
-				return 1;
-				}
-			else
-				{
-				limits[lim].rlim_max = val;
-				if (limits[lim].rlim_max < limits[lim].rlim_cur)
-					limits[lim].rlim_cur = limits[lim].rlim_max;
-				}
-		else
-			if (val > limits[lim].rlim_max)
-				{
-				zerrnam("limit","limit exceeds hard limit");
-				return 1;
-				}
-			else
-				limits[lim].rlim_cur = val;
-		s = getnode(comm->args);
-		}
-	return 0;
-}
-
-int unlimit(comm comm)
-{
-char *s = getnode(comm->args);
-int hard = 0,t0,lim;
-
-	if (s && !strcmp(s,"-h"))
-		{
-		hard = 1;
-		if (geteuid())
-			{
-			zerrnam("unlimit","can't remove hard limits");
-			return 1;
-			}
-		free(s);
-		s = getnode(comm->args);
-		}
-	if (!s)
-		{
-		for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
-			{
-			if (hard)
-				limits[t0].rlim_max = RLIM_INFINITY;
-			else
-				limits[t0].rlim_cur = limits[t0].rlim_max;
-			}
-		return 0;
-		}
-	while (s)
-		{
-		for (lim = -1, t0 = 0; t0 != RLIM_NLIMITS; t0++)
-			if (!strncmp(recs[t0],s,strlen(s)))
-				{
-				if (lim != -1)
-					lim = -2;
-				else
-					lim = t0;
-				}
-		if (lim < 0)
-			{
-			zerrnam("unlimit",
-				(lim == -2) ? "ambiguous resource specification: %s"
-								: "no such resource: %s",s);
-			free(s);
-			return 1;
-			}
-		free(s);
-		if (hard)
-			limits[lim].rlim_max = RLIM_INFINITY;
-		else
-			limits[lim].rlim_cur = limits[lim].rlim_max;
-		s = getnode(comm->args);
-		}
-	return 0;
-}
-
-void showlimits(int hard,int lim)
-{
-int t0;
-long val;
-
-	for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
-		if (t0 == lim || lim == -1)
-			{
-			printf("%-16s",recs[t0]);
-			val = (hard) ? limits[t0].rlim_max : limits[t0].rlim_cur;
-			if (val == RLIM_INFINITY)
-				printf("unlimited\n");
-			else if (!t0)
-				printf("%d:%02d:%02d\n",(int) (val/3600),
-					(int) (val/60) % 60,(int) (val % 60));
-#ifdef RLIMIT_NOFILE
-			else if (t0 == RLIMIT_NOFILE)
-				printf("%d\n",(int) val);
-#endif
-			else if (val >= 1024L*1024L)
-				printf("%ldMb\n",val/(1024L*1024L));
-			else
-				printf("%ldKb\n",val/1024L);
-			}
-}
-
-int sched(comm comm)
-{
-char *s = getnode(comm->args);
-time_t t;
-long h,m;
-struct tm *tm;
-struct schnode *sch,*sch2,*schl;
-int t0;
-
-	if (s && *s == '-')
-		{
-		t0 = atoi(s+1);
-
-		if (!t0)
-			{
-			zerrnam("sched","usage for delete: sched -<item#>.");
-			return 1;
-			}
-		for (schl = (struct schnode *) &scheds, sch = scheds, t0--;
-				sch && t0; sch = (schl = sch)->next, t0--);
-		if (!sch)
-			{
-			zerrnam("sched","not that many entries");
-			return 1;
-			}
-		schl->next = sch->next;
-		free(sch->cmd);
-		free(sch);
-		return 0;
-		}
-	if (s && !full(comm->args))
-		{
-		zerrnam("sched","not enough arguments");
-		return 1;
-		}
-	if (!s)
-		{
-		char tbuf[40];
-
-		for (t0 = 1, sch = scheds; sch; sch = sch->next,t0++)
-			{
-			t = sch->time;
-			tm = localtime(&t);
-			strftime(tbuf,20,"%a %b %e %k:%M:%S",tm);
-			printf("%3d %s %s\n",t0,tbuf,sch->cmd);
-			}
-		return 0;
-		}
-	if (*s == '+')
-		{
-		h = strtol(s+1,&s,10);
-		if (*s != ':')
-			{
-			zerrnam("sched","bad time specifier");
-			return 1;
-			}
-		m = strtol(s+1,&s,10);
-		if (*s)
-			{
-			zerrnam("sched","bad time specifier");
-			return 1;
-			}
-		t = time(NULL)+h*3600+m*60;
-		}
-	else
-		{
-		h = strtol(s,&s,10);
-		if (*s != ':')
-			{
-			zerrnam("sched","bad time specifier");
-			return 1;
-			}
-		m = strtol(s+1,&s,10);
-		if (*s && *s != 'a' && *s != 'p')
-			{
-			zerrnam("sched","bad time specifier");
-			return 1;
-			}
-		t = time(NULL);
-		tm = localtime(&t);
-		t -= tm->tm_sec+tm->tm_min*60+tm->tm_hour*3600;
-		if (*s == 'p')
-			h += 12;
-		t += h*3600+m*60;
-		if (t < time(NULL))
-			t += 3600*24;
-		}
-	sch = alloc(sizeof(struct schnode));
-	sch->time = t;
-	sch->cmd = buildline(comm->args);
-	sch->next = NULL;
-	for (sch2 = (struct schnode *) &scheds; sch2->next; sch2 = sch2->next);
-	sch2->next = sch;
-	return 0;
-}
-
-int eval(comm comm)
-{
-char *s = buildline(comm->args);
-list list;
-
-	hungets(s);
-	strinbeg();
-	if (!(list = parlist(1)))
-		{
-		hflush();
-		strinend();
-		return 1;
-		}
-	strinend();
-	runlist(list);
-	return lastval;
-}
-
-int Brk(comm comm)
-{
-	printf("%lx\n",(long) sbrk(0));
-	return 0;
-}
-
-static struct utmp *wtab;
-static int wtabsz;
-
-int log(comm comm)
-{
-	if (!getparm("WATCH"))
-		return 1;
-	if (wtab)
-		free(wtab);
-	wtab = (struct utmp *) zalloc(1);
-	wtabsz = 0;
-	watch();
-	return 0;
-}
-
-int let(comm comm)
-{
-char *str;
-long val;
-
-	while (str = getnode(comm->args))
-		val = matheval(str);
-	return !val;
-}
-
-int Read(comm comm)
-{
-char *str,*pmpt;
-int r = 0,bsiz,c,gotnl = 0;
-char *buf,*bptr;
-char cc;
-
-	str = getnode(comm->args);
-	if (str && !strcmp(str,"-r"))
-		{
-		r = 1;
-		str = getnode(comm->args);
-		}
-	if (!str)
-		str = strdup("REPLY");
-	if (interact)
-		{
-		for (pmpt = str; *pmpt && *pmpt != '?'; pmpt++);
-		if (*pmpt++)
-			{
-			write(2,pmpt,strlen(pmpt));
-			*pmpt = '\0';
-			}
-		}
-	while (full(comm->args))
-		{
-		buf = bptr = zalloc(bsiz = 64);
-		FOREVER
-			{
-			if (gotnl)
-				break;
-			if (read(0,&cc,1) == 1)
-				c = cc;
-			else
-				c = EOF;
-			if (c == EOF || znspace(c))
-				break;
-			*bptr++ = c;
-			if (bptr == buf+bsiz)
-				{
-				buf = realloc(buf,bsiz *= 2);
-				bptr = buf+(bsiz/2);
-				}
-			}
-		if (c == EOF)
-			return 1;
-		if (c == '\n')
-			gotnl = 1;
-		*bptr = '\0';
-		setparm(str,buf,0,0);
-		str = getnode(comm->args);
-		}
-	buf = bptr = zalloc(bsiz = 64);
-	if (!gotnl)
-		FOREVER
-			{
-			if (read(0,&cc,1) == 1)
-				c = cc;
-			else
-				c = EOF;
-			if (c == EOF || c == '\n')
-				break;
-			*bptr++ = c;
-			if (bptr == buf+bsiz)
-				{
-				buf = realloc(buf,bsiz *= 2);
-				bptr = buf+(bsiz/2);
-				}
-			*bptr = '\0';
-			}
-	if (c == EOF)
-		return 1;
-	setparm(str,buf,0,0);
-	return 0;
-}
-
-int fc(comm comm)
-{
-char *ename = getparm("FCEDIT"),*str,*s;
-int n = 0,l = 0,r = 0,first = -1,last = -1,retval;
-table subs = NULL;
-
-	if (!interact)
-		{
-		zerrnam("fc","not interactive shell");
-		return 1;
-		}
-	remhist();
-	if (!ename)
-		ename = DEFFCEDIT;
-	str = getnode(comm->args);
-	for (; str && *str == '-' && str[1] && !isdigit(str[1]);
-			str = getnode(comm->args))
-		while (str[1])
-			switch(*++str)
-				{
-				case 'e':
-					if (str[1])
-						{
-						zerrnam("fc","editor name expected after -e");
-						return 1;
-						}
-					ename = getnode(comm->args);
-					if (!ename)
-						{
-						zerrnam("fc","editor name expected after -e");
-						return 1;
-						}
-					break;
-				case 'n':
-					n = 1;
-					break;
-				case 'l':
-					l = 1;
-					break;
-				case 'r':
-					r = 1;
-					break;
-				default:
-					zerrnam("fc","bad option: %c",*str);
-					return 1;
-				}
-	subs = newtable();
-	while (str)
-		{
-		for (s = str; *s && *s != '='; s++);
-		if (!*s)
-			break;
-		*s++ = '\0';
-		addnode(subs,str);
-		addnode(subs,s);
-		str = getnode(comm->args);
-		}
-	if (str)
-		{
-		first = fcgetcomm(str);
-		if (first == -1)
-			{
-			freetable(subs,freestr);
-			return 1;
-			}
-		str = getnode(comm->args);
-		}
-	if (str)
-		{
-		last = fcgetcomm(str);
-		if (last == -1)
-			{
-			freetable(subs,freestr);
-			return 1;
-			}
-		if (full(comm->args))
-			{
-			zerrnam("fc","too many arguments");
-			freetable(subs,freestr);
-			return 1;
-			}
-		}
-	if (first == -1)
-		{
-		first = (l) ? cev-16 : cev;
-		if (last == -1)
-			last = cev;
-		}
-	if (first < tfev)
-		first = tfev;
-	if (last == -1)
-		last = first;
-	if (l)
-		retval = fclist(stdout,!n,r,first,last,subs);
-	else
-		{
-		FILE *out;
-		char *fn = gettemp();
-
-		out = fopen(fn,"w");
-		if (!out)
-			zerrnam("fc","can't open temp file: %e",errno);
-		else
-			{
-			retval = 1;
-			if (!fclist(out,0,r,first,last,subs))
-				if (fcedit(ename,fn))
-					if (stuff(fn))
-						zerrnam("fc","%e: %s",errno,s);
-					else
-						retval = 0;
-			}
-		unlink(fn);
-		free(fn);
-		}
-	freetable(subs,freestr);
-	return retval;
-}
-
-/* get the history event associated with s */
-
-int fcgetcomm(char *s)
-{
-int cmd;
-
-	if (cmd = atoi(s))
-		{
-		if (cmd < 0)
-			cmd = cev+cmd+1;
-		return cmd;
-		}
-	cmd = hcomsearch(s);
-	if (cmd == -1)
-		zerrnam("fc","event not found: %s",s);
-	return cmd;
-}
-
-/* list a series of history events to a file */
-
-int fclist(FILE *f,int n,int r,int first,int last,table subs)
-{
-int done = 0,ct;
-Node node;
-char *s;
-
-	if (!subs->first)
-		done = 1;
-	last -= first;
-	first -= tfev;
-	if (r)
-		first += last;
-	for (node = histlist->first,ct = first; ct && node;
-		node = node->next, ct--);
-	first += tfev;
-	while (last-- >= 0)
-		{
-		if (!node)
-			{
-			zerrnam("fc","no such event: %d",first);
-			return 1;
-			}
-		s = makehlist(node->dat,0);
-		done |= fcsubs(&s,subs);
-		if (n)
-			fprintf(f,"%5d  ",first);
-		if (f == stdout)
-			{
-			niceprintf(s,f);
-			putc('\n',f);
-			}
-		else
-			fprintf(f,"%s\n",s);
-		node = (r) ? node->last : node->next;
-		(r) ? first-- : first++;
-		}
-	if (f != stdout)
-		fclose(f);
-	if (!done)
-		{
-		zerrnam("fc","no substitutions performed");
-		return 1;
-		}
-	return 0;
-}
-
-/* perform old=new substituion */
-
-int fcsubs(char **sp,table tab)
-{
-Node n;
-char *s1,*s2,*s3,*s4,*s = *sp,*s5;
-int subbed = 0;
-
-	for (n = tab->first; n; )
-		{
-		s1 = n->dat;
-		n = n->next;
-		s2 = n->dat;
-		n = n->next;
-		s5 = s;
-		while (s3 = (char *) strstr(s5,s1))
-			{
-			s4 = zalloc(1+(s3-s)+strlen(s2)+strlen(s3+strlen(s1)));
-			strncpy(s4,s,s3-s);
-			s4[s3-s] = '\0';
-			strcat(s4,s2);
-			s5 = s4+strlen(s4);
-			strcat(s4,s3+strlen(s1));
-			free(s);
-			s = s4;
-			subbed = 1;
-			}
-		}
-	*sp = s;
-	return subbed;
-}
-
-int fcedit(char *ename,char *fn)
-{
-	if (!strcmp(ename,"-"))
-		return 1;
-	return !zyztem(ename,fn);
-}
-
-int disown(comm comm)
-{
-char *str;
-int t0;
-static struct jobnode zero;
-
-	while (str = getnode(comm->args))
-		{
-		t0 = getjob(str,"disown");
-		if (t0 == -1)
-			return 1;
-		jobtab[t0] = zero;
-		}
-	return 0;
-}
-
-int function(comm comm)
-{
-	if (full(comm->args))
-		{
-		zerrnam("function","too many arguments");
-		return 1;
-		}
-	listhtable(shfunchtab,(void (*)(char *,char *)) pshfunc);
-	return 0;
-}
-
-int (*funcs[])(comm) = {
-	echo,zexit,logout,Unset,dirs,
-	Alias,cd,which,popd,
-   dot,pushd,shift,unhash,Break,
-	colon,Glob,noglob,mostglob,unalias,
-	fg,bg,jobs,Kill,export,
-	Umask,cd,limit,unlimit,eval,
-	unfunction,set,Brk,log,builtin,
-	sched,let,fc,
-	rehash,hash,disown,test,Read,
-	integer,setopt,unsetopt,zreturn,function,
-	test,
-	NULL
-	};
-char *funcnams[] = {
-	"echo","exit","logout","unset","dirs",
-	"alias","cd","which","popd",
-	".","pushd","shift","unhash","break",
-	":","glob","noglob","mostglob","unalias",
-	"fg","bg","jobs","kill","export",
-	"umask","chdir","limit","unlimit","eval",
-	"unfunction","set","brk","log","builtin",
-	"sched","let","fc",
-	"rehash","hash","disown","test","read",
-	"integer","setopt","unsetopt","return","function",
-	"["
-	};
-
-int builtin(comm comm)
-{
-char *s;
-int t0;
-
-	s = getnode(comm->args);
-	if (!s)
-		{
-		zerrnam("builtin","not enough arguments");
-		return 1;
-		}
-	for (t0 = 0; funcs[t0]; t0++)
-		if (!strcmp(funcnams[t0],s))
-			break;
-	if (!funcs[t0])
-		{
-		zerrnam("builtin","no such builtin: %s",s);
-		return 1;
-		}
-	return (funcs[t0])(comm);
-}
-
-/* add builtins to the command hash table */
-
-void addintern(htable ht)
-{
-int (**ptr)(comm);
-struct chnode *ch;
-char **nam;
- 
-	for (ptr = funcs, nam = funcnams; *ptr; ptr++,nam++)
-		{
-		ch = alloc(sizeof(struct chnode));
-		ch->type = BUILTIN;
-		ch->u.func = *ptr;
-		addhnode(strdup(*nam),ch,ht,freechnode);
-		}
-}
-
-/* get the time of login/logout for WATCH */
-
-static time_t getlogtime(struct utmp *u,int inout)
-{
-FILE *in;
-struct utmp uu;
-int first = 1;
-
-	if (inout)
-		return u->ut_time;
-	if (!(in = fopen(WTMP_FILE,"r")))
-		return time(NULL);
-	fseek(in,0,2);
-	do
-		{
-		if (fseek(in,((first) ? -1 : -2)*sizeof(struct utmp),1))
-			{
-			fclose(in);
-			return time(NULL);
-			}
-		first = 0;
-		if (!fread(&uu,sizeof(struct utmp),1,in))
-			{
-			fclose(in);
-			return time(NULL);
-			}
-		}
-	while (memcmp(&uu,u,sizeof(struct utmp)));
-	do
-		if (!fread(&uu,sizeof(struct utmp),1,in))
-			{
-			fclose(in);
-			return time(NULL);
-			}
-	while (strncmp(uu.ut_line,u->ut_line,8));
-	fclose(in);
-	return uu.ut_time;
-}
-
-/* print a login/logout event */
-
-static void watchlog2(int inout,struct utmp *u,char *fmt)
-{
-char *p,buf[40],*bf;
-int i;
-time_t timet;
-struct tm *tm = NULL;
-
-	while (*fmt)
-		if (*fmt != '%')
-			putchar(*fmt++);
-		else
-			{
-			fmt++;
-			switch(*fmt++)
-				{
-				case 'n':
-					printf("%.*s",8,u->ut_name);
-					break;
-				case 'a':
-					printf("%s",(!inout) ? "logged off" : "logged on");
-					break;
-				case 'l':
-					printf("%.*s",5,u->ut_line+3);
-					break;
-				case 'm':
-					for (p = u->ut_host,i = 16; i && *p;i--,p++)
-						{
-						if (*p == '.' && !isdigit(p[1]))
-							break;
-						putchar(*p);
-						}
-					break;
-				case 'M':
-					printf("%.*s",16,u->ut_host);
-					break;
-				case 't':
-				case '@':
-					timet = getlogtime(u,inout);
-					tm = localtime(&timet);
-					strftime(buf,40,"%l:%M%p",tm);
-					printf("%s",(*buf == ' ') ? buf+1 : buf);
-					break;
-				case 'T':
-					timet = getlogtime(u,inout);
-					tm = localtime(&timet);
-					strftime(buf,40,"%k:%M",tm);
-					printf("%s",buf);
-					break;
-				case 'w':
-					timet = getlogtime(u,inout);
-					tm = localtime(&timet);
-					strftime(buf,40,"%a %e",tm);
-					printf("%s",buf);
-					break;
-				case 'W':
-					timet = getlogtime(u,inout);
-					tm = localtime(&timet);
-					strftime(buf,40,"%m/%d/%y",tm);
-					printf("%s",buf);
-					break;
-				case 'D':
-					timet = getlogtime(u,inout);
-					tm = localtime(&timet);
-					strftime(buf,40,"%y-%m-%d",tm);
-					printf("%s",buf);
-					break;
-				case '%':
-					putchar('%');
-					break;
-				case 'S':
-					bf = buf;
-					if (tgetstr("so",&bf))
-						fputs(buf,stdout);
-					break;
-				case 's':
-					bf = buf;
-					if (tgetstr("se",&bf))
-						fputs(buf,stdout);
-					break;
-				case 'B':
-					bf = buf;
-					if (tgetstr("md",&bf))
-						fputs(buf,stdout);
-					break;
-				case 'b':
-					bf = buf;
-					if (tgetstr("me",&bf))
-						fputs(buf,stdout);
-					break;
-				case 'U':
-					bf = buf;
-					if (tgetstr("us",&bf))
-						fputs(buf,stdout);
-					break;
-				case 'u':
-					bf = buf;
-					if (tgetstr("ue",&bf))
-						fputs(buf,stdout);
-					break;
-				default:
-					putchar('%');
-					putchar(fmt[-1]);
-					break;
-				}
-			}
-	putchar('\n');
-}
-
-/* check the list for login/logouts */
-
-static void watchlog(int inout,struct utmp *u,char *w,char *fmt)
-{
-char *v;
-
-	if (!strcmp(w,"all"))
-		{
-		watchlog2(inout,u,fmt);
-		return;
-		}
-	for(;;)
-		if (v = strchr(w,':'))
-			{
-			if (!strncmp(u->ut_name,w,v-w))
-				watchlog2(inout,u,fmt);
-			w = v+1;
-			}
-		else
-			{
-			if (!strncmp(u->ut_name,w,8))
-				watchlog2(inout,u,fmt);
-			break;
-			}
-}
-
-/* compare 2 utmp entries */
-
-static int ucmp(struct utmp *u,struct utmp *v)
-{
-	if (u->ut_time == v->ut_time)
-		return strncmp(u->ut_line,v->ut_line,8);
-	return u->ut_time - v->ut_time;
-}
-
-/* initialize the user list */
-
-void readwtab(void)
-{
-struct utmp *uptr;
-int wtabmax = 32;
-FILE *in;
-
-	wtabsz = 0;
-	uptr = wtab = (struct utmp *) zalloc(wtabmax*sizeof(struct utmp));
-	in = fopen(UTMP_FILE,"r");
-	while (fread(uptr,sizeof(struct utmp),1,in))
-		if (uptr->ut_host[0])
-			{
-			uptr++;
-			if (++wtabsz == wtabmax)
-				uptr = (wtab = (struct utmp *) realloc(wtab,(wtabmax*=2)*
-					sizeof(struct utmp)))+wtabsz;
-			}
-	fclose(in);
-	if (wtabsz)
-		qsort(wtab,wtabsz,sizeof(struct utmp),ucmp);
-}
-
-/* check for login/logout events; executed before each prompt
-	if WATCH is set */
-
-void watch(void)
-{
-char *s = getparm("WATCH");
-char *fmt = getparm("WATCHFMT");
-FILE *in;
-int utabsz = 0,utabmax = wtabsz+4,uct,wct;
-struct utmp *utab,*uptr,*wptr;
-
-	holdintr();
-	if (!fmt)
-		fmt = "%n has %a %l from %m.";
-	if (!wtab)
-		{
-		readwtab();
-		noholdintr();
-		return;
-		}
-	uptr = utab = (struct utmp *) zalloc(utabmax*sizeof(struct utmp));
-	in = fopen(UTMP_FILE,"r");
-	while (fread(uptr,sizeof *uptr,1,in))
-		if (uptr->ut_host[0])
-			{
-			uptr++;
-			if (++utabsz == utabmax)
-				uptr = (utab = (struct utmp *) realloc(utab,(utabmax*=2)*
-					sizeof(struct utmp)))+utabsz;
-			}
-	fclose(in);
-	noholdintr();
-	if (errflag)
-		{
-		free(utab);
-		return;
-		}
-	if (utabsz)
-		qsort(utab,utabsz,sizeof(struct utmp),ucmp);
-
-	wct = wtabsz; uct = utabsz;
-	uptr = utab; wptr = wtab;
-	if (errflag)
-		{
-		free(utab);
-		return;
-		}
-	while ((uct || wct) && !errflag)
-		if (!uct || (wct && ucmp(uptr,wptr) > 0))
-			wct--,watchlog(0,wptr++,s,fmt);
-		else if (!wct || (uct && ucmp(uptr,wptr) < 0))
-			uct--,watchlog(1,uptr++,s,fmt);
-		else
-			uptr++,wptr++,wct--,uct--;
-	free(wtab);
-	wtab = utab;
-	wtabsz = utabsz;
-	fflush(stdout);
-}
-
End of builtin.c
echo builtin.pro 1>&2
sed 's/^-//' >builtin.pro <<'End of builtin.pro'
-int echo(comm comm);
-void pdstack(void);
-int zexit(comm comm);
-int zreturn(comm comm);
-int logout(comm comm);
-int Unset(comm comm);
-int set(comm comm);
-int setopt(comm comm);
-int unsetopt(comm comm);
-int csetopt(comm comm,int isun);
-void pparm(char *s,struct pmnode *t);
-int dirs(comm comm);
-void listhtable(htable ht,void (*func)(char *,char *));
-void palias(char *s,struct anode *t);
-void pshfunc(char *s,list l);
-void niceprint(char *s);
-void niceprintf(char *s,FILE *f);
-char *buildline(table t);
-int Alias(comm comm);
-int cd(comm comm);
-int dot(comm comm);
-int Umask(comm comm);
-int which(comm comm);
-int popd(comm comm);
-int pushd(comm comm);
-int chcd(char *cnam,char *cd);
-int shift(comm comm);
-int unhash(comm comm);
-int rehash(comm comm);
-int hash(comm comm);
-int Break(comm comm);
-int colon(comm comm);
-int Glob(comm comm);
-int noglob(comm comm);
-int mostglob(comm comm);
-int unfunction(comm comm);
-int unalias(comm comm);
-int prefix(char *s,char *t);
-int getjob(char *s,char *prog);
-int fg(comm comm);
-int bg(comm comm);
-int jobs(comm comm);
-int Kill(comm comm);
-int export(comm comm);
-int integer(comm comm);
-int limit(comm comm);
-int unlimit(comm comm);
-void showlimits(int hard,int lim);
-int sched(comm comm);
-int eval(comm comm);
-int Brk(comm comm);
-int log(comm comm);
-int let(comm comm);
-int Read(comm comm);
-int fc(comm comm);
-int fcgetcomm(char *s);
-int fclist(FILE *f,int n,int r,int first,int last,table subs);
-int fcsubs(char **sp,table tab);
-int fcedit(char *ename,char *fn);
-int disown(comm comm);
-int function(comm comm);
-int builtin(comm comm);
-void addintern(htable ht);
-void readwtab(void);
-void watch(void);
End of builtin.pro
echo config.h 1>&2
sed 's/^-//' >config.h <<'End of config.h'
-/*
-
-	config.h - configuration file
-
-	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.
-
-*/
-
-/* define this if you have WAITPID */
-
-#define WAITPID
-
-/* define if the return type of signal handlers is int */
-
-/* #define INTHANDTYPE  */
-
-/* the return type of handlers */
-
-#define HANDTYPE void
-
-/* define this if you have putenv */
-
-#define PUTENV 
-
-/* define this if you have strstr */
-
-#define STRSTR
-
-/* define this if you have strftime */
-
-/* #define STRFTIME */
-
-/* define if you have struct termios, else struct sgttyb */
-
-#define TERMIOS
-
-#include "config.local.h"
-
End of config.h
echo config.local.h 1>&2
sed 's/^-//' >config.local.h <<'End of config.local.h'
-/*
-
-	config.local.h - local machine configuration file
-
-	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.
-
-*/
-
-/* a string corresponding to the host type */
-
-#define HOSTTYP "sun4"
-
-/* define if you prefer "suspended" to "stopped" */
-
-#define USE_SUSPENDED
-
-/* the path of zsh in the file system */
-
-#define MYSELF "/usr/princeton/bin/zsh"
-
-/* the default editor for the fc builtin */
-
-#define DEFFCEDIT "/usr/ucb/vi"
-
-/* the file to source whenever zsh is run; if undefined, don't source
-	anything */
-
-#define GLOBALZSHRC "/etc/zshrc"
-
-/* the file to source whenever zsh is run as a login shell; if
-	undefined, don't source anything */
-
-#define GLOBALZLOGIN "/etc/zlogin"
-
-/* the default HISTSIZE */
-
-#define DEFAULT_HISTSIZE 128
-
-/* the path of utmp */
-
-#define UTMP_FILE "/etc/utmp"
-
-/* the path of wtmp */
-
-#define WTMP_FILE "/var/adm/wtmp"
-
-/* define if you have problems with job control or tty modes.
-	gcc-cpp does not seem to handle ioctls correctly. */
-
-/*#define BUGGY_GCC*/
-
-/* define if you like interactive comments */
-
-/*#define INTERACTIVE_COMMENTS*/
-
-/* define if you want warnings about nonexistent path components */
-
-#define PATH_WARNINGS
-
End of config.local.h
echo exec.c 1>&2
sed 's/^-//' >exec.c <<'End of exec.c'
-/*
-
-	exec.c - command execution
-
-	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"
-#include <sys/errno.h>
-#include <sys/dir.h>
-
-#define execerr() { if (forked) exit(1); freecmd(comm); \
-	closemnodes(mfds); errflag = 1; return; }
-#define magicerr() { if (magic) putc('\n',stderr); errflag = 1; }
-
-/* execute a string */
-
-void execstring(char *s)
-{
-list l;
-
-	hungets(strdup("\n"));
-	hungets(s);
-	strinbeg();
-	if (!(l = parlist(1)))
-		{
-		strinend();
-		hflush();
-		return;
-		}
-	if (peek != EOF && peek != EMPTY)
-		{
-		strinend();
-		hflush();
-		return;
-		}
-	strinend();
-	execlist(l);
-}
-
-/* duplicate a list and run it */
-
-void newrunlist(list l)
-{
-list a = duplist(l); runlist(a);
-}
-
-/* fork and set limits */
-
-int phork(void)
-{
-int pid = fork(),t0;
-
-	if (pid == -1)
-		{
-		zerr("fork failed: %e",errno);
-		return -1;
-		}
-	if (!pid)
-		for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
-			setrlimit(t0,limits+t0);
-	return pid;
-}
-
-/* execute a current shell command */
-
-void execcursh(comm comm)
-{
-	runlist(comm->left);
-	comm->left = NULL;
-}
-
-/* execve an external command */
-
-void execute(char *arg0,table args)
-{
-char **argv;
-char *z,*s,buf[MAXPATHLEN],buf2[MAXPATHLEN];
-struct chnode *cn;
-int t0,tl,ee = 0;
-
-#define zexecve(X,Y,Z) {execve(z=(X),Y,Z);\
-	if(errno!=ENOENT){ee = errno;strcpy(buf2,buf);}}
-
-	cn = gethnode(arg0,chtab);
-	if (s = getenv("STTY"))
-		zyztem("stty",s);
-	if (z = getenv("ARGV0"))
-		z = strdup(z);
-	else
-		z = arg0;
-	argv = makecline(z,args);
-	fixsigs();
-	if (cn)
-		{
-		if (cn->type == EXCMD_POSTDOT)
-			{zexecve(arg0,argv,environ);}
-		{zexecve(cn->u.nam,argv,environ);}
-		}
-	for (s = arg0; *s; s++)
-		if (*s == '/')
-			{
-			execve(arg0,argv,environ);
-			zerr("%e: %s",errno,arg0);
-			_exit(1);
-			}
-	for (t0 = pathct; t0; t0--,path++)
-		if (**path == '.')
-			{zexecve(arg0,argv,environ);}
-		else
-			{
-			tl = strlen(*path);
-			strcpy(buf,*path);
-			buf[tl] = '/';
-			if (strlen(arg0)+strlen(buf)+1 >= MAXPATHLEN)
-				{
-				zerr("command too long: %s",arg0);
-				_exit(1);
-				}
-			strcpy(buf+tl+1,arg0);
-			{zexecve(buf,argv,environ);}
-			}
-	if (ee)
-		{
-		z = buf2;
-		errno = ee;
-		goto errs;
-		}
-	zerr("command not found: %s",arg0);
-	_exit(1);
-errs:
-	zerr("%e: %s",errno,z);
-	_exit(1);
-}
-
-#define try(X) { if (!access(X,X_OK)) return strdup(X); }
-
-/* get the pathname of a command */
-
-char *findcmd(char *arg0)
-{
-char *s,buf[MAXPATHLEN];
-int t0,tl;
-struct chnode *cn = gethnode(arg0,chtab);
-char **pp = path;
-
-	if (cn)
-		{
-		if (cn->type == EXCMD_POSTDOT)
-			{
-			strcpy(buf,"./");
-			strcat(buf,arg0);
-			try(buf);
-			}
-		try(cn->u.nam);
-		}
-	for (s = arg0; *s; s++)
-		if (*s == '/')
-			{
-			try(arg0);
-			goto failed;
-			}
-	for (t0 = pathct; t0; t0--,pp++)
-		if (**pp == '.')
-			{
-			strcpy(buf,"./");
-			strcat(buf,arg0);
-			try(buf);
-			}
-		else
-			{
-			tl = strlen(*pp);
-			strcpy(buf,*pp);
-			buf[tl] = '/';
-			strcpy(buf+tl+1,arg0);
-			try(buf);
-			}
-failed:
-	return NULL;
-}
-
-void execlist(list list)
-{
-	execlist1(list);
-	freelist(list);
-}
-
-void execlist1(list list)
-{
-	if (breaks)
-		return;
-	switch(list->type)
-		{
-		case SYNC:
-		case ASYNC:
-			execlist2(list->left,list->type,!list->right);
-			if (sigtrapped[SIGDEBUG])
-				dotrap(SIGDEBUG);
-			if (sigtrapped[SIGERR] && lastval)
-				dotrap(SIGERR);
-			if (list->right && !retflag)
-				execlist1(list->right);
-			break;
-		}
-}
-
-void execlist2(list2 list,int type,int last1)
-{
-	switch(list->type)
-		{
-		case END:
-			execpline(list,type,last1);
-			break;
-		case ORNEXT:
-			if (!execpline(list,SYNC,0))
-				execlist2(list->right,type,last1);
-			break;
-		case ANDNEXT:
-			if (execpline(list,SYNC,0))
-				execlist2(list->right,type,last1);
-			break;
-		}
-}
-
-int execpline(list2 l,int how,int last1)
-{
-int ipipe[2] = {0,0},opipe[2] = {0,0};
-
-	sigblock(sigmask(SIGCHLD));
-	curjob = getfreejob(); 
-	initjob(l->flags);
-	if (l->flags & PFLAG_COPROC)
-		{
-		how = ASYNC;
-		mpipe(ipipe);
-		mpipe(opipe);
-		if (spin)
-			{
-			close(spin);
-			close(spout);
-			}
-		spin = ipipe[0];
-		spout = opipe[1];
-		}
-	execpline2(l->left,how,opipe[0],ipipe[1],last1);
-	if (how == ASYNC)
-		{
-		spawnjob();
-		sigsetmask(0);
-		return 1;
-		}
-	else
-		{
-		waitjobs();
-		sigsetmask(0);
-		if (l->flags & PFLAG_NOT)
-			lastval = !lastval;
-		return !lastval;
-		}
-}
-
-void execpline2(pline pline,int how,int input,int output,int last1)
-{
-int pid;
-int pipes[2];
-
-	if (breaks)
-		return;
-	if (!pline)
-		return;
-	if (pline->type == END)
-		{
-		execcomm(pline->left,input,output,how==ASYNC,last1);
-		pline->left = NULL;
-		}
-	else
-		{
-		mpipe(pipes);
-
-		/* if we are doing "foo | bar" where foo is a current
-			shell command, do foo in the current shell and do
-			the rest of the pipeline in a subshell. */
-
-		if (pline->left->type >= CURSH && how == SYNC)
-			{
-			if (!(pid = fork()))
-				{
---cut here---cut here---cut here---

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

---cut here---cut here---cut here---
-				case 'M':
-					stradd(&bp,hostM);
-					break;
-				case 'm':
-					stradd(&bp,hostm);
-					break;
-				case 'S':
-					if (tgetstr("so",&bp))
-						bp--;
-					break;
-				case 's':
-					if (tgetstr("se",&bp))
-						bp--;
-					break;
-				case 'B':
-					if (tgetstr("md",&bp))
-						bp--;
-					break;
-				case 'b':
-					if (tgetstr("me",&bp))
-						bp--;
-					break;
-				case 'U':
-					if (tgetstr("us",&bp))
-						bp--;
-					break;
-				case 'u':
-					if (tgetstr("ue",&bp))
-						bp--;
-					break;
-				case 't':
-				case '@':
-					timet = time(NULL);
-					tm = localtime(&timet);
-					strftime(bp,16,"%l:%M%p",tm);
-					if (*bp == ' ')
-						chuck(bp);
-					bp += strlen(bp);
-					break;
-				case 'T':
-					timet = time(NULL);
-					tm = localtime(&timet);
-					strftime(bp,16,"%k:%M",tm);
-					bp += strlen(bp);
-					break;
-				case '*':
-					timet = time(NULL);
-					tm = localtime(&timet);
-					strftime(bp,16,"%k:%M:%S",tm);
-					bp += strlen(bp);
-					break;
-				case 'n':
-					stradd(&bp,username);
-					break;
-				case 'w':
-					timet = time(NULL);
-					tm = localtime(&timet);
-					strftime(bp,16,"%a %e",tm);
-					bp += strlen(bp);
-					break;
-				case 'W':
-					timet = time(NULL);
-					tm = localtime(&timet);
-					strftime(bp,16,"%m/%d/%y",tm);
-					bp += strlen(bp);
-					break;
-				case 'D':
-					timet = time(NULL);
-					tm = localtime(&timet);
-					strftime(bp,16,"%y-%m-%d",tm);
-					bp += strlen(bp);
-					break;
-				case 'l':
-					if (ss = ttyname(SHTTY))
-						stradd(&bp,ss+8);
-					else
-						stradd(&bp,"(none)");
-					break;
-				case '%':
-					*bp++ = '%';
-					break;
-				case '#':
-					*bp++ = (geteuid()) ? '%' : '#';
-					break;
-				default:
-					*bp++ = '%';
-					*bp++ = *fm;
-					break;
-				}
-		else	
-			*bp++ = *fm;
-		}
-	*bp = '\0';
-	return buf;
-}
-
-void herrflush(void)
-{
-	if (strin)
-		hflush();
-	else while (lastc != '\n' && lastc != HERR)
-		hgetch();
-	if (magic)
-		putc('\n',stderr);
-}
-
-/* read an arbitrary amount of data into a buffer until stop is found */
-
-char *hdynread(char stop)
-{
-int bsiz = 256,ct = 0,c;
-char *buf = zalloc(bsiz),*ptr;
- 
-	ptr = buf;
-	while ((c = hgetch()) != stop && c != '\n')
-		{
-		if (c == '\\')
-			c = hgetch();
-		*ptr++ = c;
-		if (++ct == bsiz)
-			{
-			buf = realloc(buf,bsiz *= 2);
-			ptr = buf+ct;
-			}
-		}
-	*ptr = 0;
-	if (c == '\n')
-		{
-		hungetch('\n');
-		zerr("delimiter expected");
-		errflag = 1;
-		free(buf);
-		return NULL;
-		}
-	return buf;
-}
- 
-char *hdynread2(char stop)
-{
-int bsiz = 256,ct = 0,c;
-char *buf = zalloc(bsiz),*ptr;
- 
-	ptr = buf;
-	while ((c = hgetch()) != stop && c != '\n')
-		{
-		if (c == '\n')
-			{
-			hungetch(c);
-			break;
-			}
-		if (c == '\\')
-			if ((c = hgetch()) == '&')
-				c = '&';
-		*ptr++ = c;
-		if (++ct == bsiz)
-			{
-			buf = realloc(buf,bsiz *= 2);
-			ptr = buf+ct;
-			}
-		}
-	*ptr = 0;
-	if (c == '\n')
-		hungetch('\n');
-	return buf;
-}
-
-/* set cbreak mode, or the equivalent */
-
-void setcbreak(void)
-{
-struct ttyinfo ti;
-
-	ti = shttyinfo;
-#ifdef TERMIOS
-	ti.termios.c_lflag &= ~ICANON;
-	ti.termios.c_cc[VMIN] = 1;
-	ti.termios.c_cc[VTIME] = 0;
-#else
-	ti.sgttyb.sg_flags |= CBREAK;
-#endif
-	settyinfo(&ti);
-}
-
-int getlineleng(void)
-{
-int z;
-
-	z = shttyinfo.winsize.ws_col;
-	return (z) ? z : 80;
-}
-
-void unsetcbreak(void)
-{
-	settyinfo(&shttyinfo);
-}
-
-/* give the tty to some process */
-
-void attachtty(long pgrp)
-{
-static int ep = 0;
-
-	if (jobbing)
-#ifdef BUGGY_GCC
-		if (SHTTY != -1 && ioctl(SHTTY,(0x80000000|((sizeof(int)&0xff)<<16)|
-			('t'<<8)|118),&pgrp) == -1 && !ep)
-#else
-		if (SHTTY != -1 && ioctl(SHTTY,TIOCSPGRP,&pgrp) == -1 && !ep)
-#endif
-			{
-			zerr("can't set tty pgrp: %e",errno);
-			opts[MONITOR] = OPT_UNSET;
-			ep =1;
-			}
-}
-
End of hist.c
echo hist.pro 1>&2
sed 's/^-//' >hist.pro <<'End of hist.pro'
-void hwaddc(int c);
-int hgetc(void);
-void strinbeg(void);
-void strinend(void);
-int stuff(char *fn);
-int hgetch(void);
-void hungetch(int c);
-void hungetc(int c);
-void hflush(void);
-void hungets(char *str);
-void hbegin(void);
-void inittty(void);
-int hend(void);
-void remhist(void);
-void hwbegin(void);
-char *hwadd(void);
-int getargspec(int argc,int marg);
-int hconsearch(char *str,int *marg);
-int hcomsearch(char *str);
-int apply1(int gflag,int (*func)(void **),table list);
-int remtpath(void **junkptr);
-int remtext(void **junkptr);
-int rembutext(void **junkptr);
-int remlpaths(void **junkptr);
-int subst(int gbal,table slist,char *ptr1,char *ptr2);
-int subststr(void **strptr,char *in,char *out,int gbal);
-char *convamps(char *out,char *in);
-char *makehlist(table tab,int freeit);
-table quietgetevent(int ev);
-table getevent(int ev);
-int getargc(table tab);
-table getargs(table elist,int arg1,int arg2);
-int quote(void **tr);
-int quotebreak(void **tr);
-void stradd(char **p,char *d);
-char *putprompt(char *fm);
-void herrflush(void);
-char *hdynread(char stop);
-char *hdynread2(char stop);
-void setcbreak(void);
-int getlineleng(void);
-void unsetcbreak(void);
-void attachtty(long pgrp);
End of hist.pro
echo init.c 1>&2
sed 's/^-//' >init.c <<'End of init.c'
-/*
-
-	init.c - initialization, main loop
-
-	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"
-#include <pwd.h>
-
-void main(int argc, char **argv)
-{
-int notect = 0;
-
-	setflags();
-	parseargs(argv);
-	setmoreflags();
-	setupvals();
-	initialize();
-	runscripts();
-	FOREVER
-		{
-		do
-			loop();
-		while (peek != EOF);
-		if (!(isset(IGNOREEOF) && interact))
-			{
-			if (interact)
-				fputs(islogin ? "logout\n" : "exit\n",stderr);
-			zexit(NULL);
-			continue;
-			}
-		zerrnam("\nzsh",(!islogin) ? "use 'exit' to exit."
-			: "use 'logout' to logout.");
-		notect++;
-		if (notect == 10)
-			zexit(NULL);
-		}
-}
-
-/* keep executing lists until EOF found */
-
-void loop(void)
-{
-list list;
-
-	FOREVER
-		{
-		peek = EMPTY;
-		if (interact)
-			preprompt();
-		hbegin();		/* init history mech */
-		intr();			/* interrupts on */
-		ainit();			/* init alias mech */
-		if (!(list = parlist1(0)))
-			{				/* if we couldn't parse a list */
-			hend();
-			if (!errflag)
-				if (peek == OUTPAR)
-					{
-					errflag = 1;
-					zerr("mismatched parenthesis");
-					}
-				else if (peek == OUTBRACE)
-					{
-					errflag = 1;
-					zerr("mismatched brace");
-					}
-				else if (peek != EOF && peek != EMPTY && peek != NEWLIN)
-					{
-					errflag = 1;
-					zerr("semicolon or newline expected");
-					}
-			if (peek == EOF && !errflag)
-				return;
-			continue;
-			}
-		if (peek != EMPTY && peek != EOF)
-			{
-			if (peek == OUTPAR)
-				zerr("mismatched parenthesis");
-			else if (peek == OUTBRACE)
-				zerr("mismatched brace");
-			else
-				zerr("semicolon or newline expected");
-			hend();
-			errflag = 1;
-			}
-		else if (hend())
-			{
-			if (stopmsg)		/* unset 'you have stopped jobs' flag */
-				stopmsg--;
-			execlist(list);
-			}
-		if (ferror(stderr))
-			{
-			zerr("write error");
-			clearerr(stderr);
-			}
-		if (subsh)				/* how'd we get this far in a subshell? */
-			exit(lastval);
-		if ((!interact && errflag) || retflag)
-			return;
-		if ((opts['t'] == OPT_SET) || (lastval && opts[ERREXIT] == OPT_SET))
-			{
-			if (sigtrapped[SIGEXIT])
-				dotrap(SIGEXIT);
-			exit(lastval);
-			}
-		}
-}
-
-void setflags(void)
-{
-int c;
-
-	for (c = 0; c != 128; c++)
-		opts[c] = OPT_INVALID;
-	opts['a'] = opts['e'] = opts['f'] = opts['h'] = opts['k'] = opts['n'] = 
-		opts['s'] = opts['t'] = opts['u'] = opts['v'] = opts['x'] = 
-		opts['c'] = OPT_UNSET;
-	opts['i'] = (isatty(0)) ? OPT_SET : OPT_UNSET;
-	for (c = '0'; c <= '9'; c++)
-		opts[c] = OPT_UNSET;
-	for (c = 'A'; c <= 'K'; c++)
-		opts[c] = OPT_UNSET;
-	opts[BGNICE] = opts[NOTIFY] = OPT_SET;
-}
-
-static char *cmd;
-
-void parseargs(char **argv)
-{
-char *argv0 = *argv;
-int bk = 0;
-
-	islogin = **(argv++) == '-';
-	SHIN = 0;
-	while (!bk && *argv && **argv == '-')
-		{
-		while (*++*argv)
-			{
-			if (opts[**argv] == OPT_INVALID)
-				{
-				zerr("bad option: -%c",**argv);
-				exit(1);
-				}
-			opts[**argv] = OPT_SET;
-			if (bk = **argv == 'b')
-				break;
-			if (**argv == 'c') /* -c command */
-				{
-				argv++;
-				if (!*argv)
-					{
-					zerr("string expected after -c");
-					exit(1);
-					}
-				cmd = strdup(*argv);
-				opts[INTERACTIVE] = OPT_UNSET;
-				break;
-				}
-			}
-		argv++;
-		}
-	pparms = newtable();
-	if (*argv)
-		{
-		if (opts[SHINSTDIN] == OPT_UNSET)
-			{
-			SHIN = movefd(open(argv0 = *argv,O_RDONLY));
-			if (SHIN == -1)
-				{
-				zerr("can't open input file: %s",*argv);
-				exit(1);
-				}
-			opts[INTERACTIVE] = OPT_UNSET;
-			argv++;
-			}
-		addnode(pparms,argv0);  /* assign positional parameters */
-		while (*argv)
-			addnode(pparms,strdup(*argv++));
-		}
-	else
-		{
-		addnode(pparms,strdup(argv0));
-		opts[SHINSTDIN] = OPT_SET;
-		}
-}
-
-void setmoreflags(void)
-{
-	setlinebuf(stderr);
-	setlinebuf(stdout);
-	subsh = 0;
-	opts[MONITOR] = (interact) ? OPT_SET : OPT_UNSET;
-	if (jobbing)
-		{
-		SHTTY = movefd((isatty(0)) ? dup(0) : open("/dev/tty",O_RDWR));
-		if (SHTTY == -1)
-			opts[MONITOR] = OPT_UNSET;
-		else
-			gettyinfo(&shttyinfo);	/* get tty state */
-		if ((shpgrp = getpgrp(0)) <= 0)
-			opts[MONITOR] = OPT_UNSET;
-		}
-	else
-		SHTTY = -1;
-}
-
-void setupvals(void)
-{
-struct passwd *pwd;
-char *ptr;
-
-	shtimer = time(NULL);	/* init $SECONDS */
-	/* build various hash tables; argument to newhtable is table size */
-	alhtab = newhtable(37);
-	parmhtab = newhtable(17);
-	shfunchtab = newhtable(17);
-	if (interact)
-		{
-		if (!getparm("PROMPT"))
-			setparm(strdup("PROMPT"),strdup("%M%# "),0,0);
-		if (!getparm("PROMPT2"))
-			setparm(strdup("PROMPT2"),strdup("> "),0,0);
-		if (!getparm("PROMPT3"))
-			setparm(strdup("PROMPT3"),strdup("?# "),0,0);
-		}
-	if (!getparm("PATH"))
-		setparm(strdup("PATH"),strdup("/bin:/usr/bin:/usr/ucb"),1,0);
-	setparm(strdup("VERSION"),strdup(VERSIONSTR),1,0);
-	home = xsymlink(getparm("HOME"));
-	setparm(strdup("HOME"),strdup(home),0,0);
-	setiparm(strdup("UID"),getuid(),1);
-	setiparm(strdup("EUID"),geteuid(),1);
-	setiparm(strdup("PPID"),getppid(),1);
-	lineno = 0;
-	pwd = getpwuid(getuid());
-	setparm(strdup("USERNAME"),strdup(pwd->pw_name),0,0);
-	username = strdup(pwd->pw_name);
-	setparm(strdup("HOSTTYPE"),strdup(HOSTTYP),0,0);
-	cwd = zgetwd();
-	setparm(strdup("PWD"),strdup(cwd),0,0);
-	if (!getparm("IFS"))
-		{
-		ifs = strdup(" \t\n");
-		setparm(strdup("IFS"),strdup(ifs),0,0);
-		}
-	hostM = alloc(512);	/* get hostname, with and without .podunk.edu */
-	hostm = hostM+256;
-	gethostname(hostm,256);
-	gethostname(hostM,256);
-	procnum = getpid();
-	for (ptr = hostM; *ptr && *ptr != '.'; ptr++);
-	*ptr = '\0';
-}
-
-void initialize(void)
-{
-int t0;
-
-	breaks = loops = incmd = 0;
-	lastmailcheck = 0;
-	lastmailval = -1;
-	tfev = 1;
-	tevs = DEFAULT_HISTSIZE;
-	histlist = newtable();
-	dirstack = newtable();
-	ungots = ungotptr = NULL;
-	signal(SIGQUIT,SIG_IGN);
-	for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
-		getrlimit(t0,limits+t0);
-	last = rast = NULL;
-	proclast = 0;
-	if (!interact || SHTTY == -1)
-		bshin = fdopen(SHIN,"r");
-	signal(SIGCHLD,handler);
-	addreswords();
-	addhnode(strdup("false"),mkanode(strdup("let 0"),1),alhtab,NULL);
-	addhnode(strdup("history"),mkanode(strdup("fc -l"),1),alhtab,NULL);
-	addhnode(strdup("nohup"),mkanode(strdup("nohup "),1),alhtab,NULL);
-	addhnode(strdup("r"),mkanode(strdup("fc -e -"),1),alhtab,NULL);
-	addhnode(strdup("true"),mkanode(strdup(":"),1),alhtab,NULL);
-	addhnode(strdup("pwd"),mkanode(strdup("echo $PWD"),1),alhtab,NULL);
-	parsepath();
-	parsecdpath();
-	if (jobbing)
-		{
-		signal(SIGTTOU,SIG_IGN);
-		signal(SIGTSTP,SIG_IGN);
-		signal(SIGTTIN,SIG_IGN);
-		signal(SIGPIPE,SIG_IGN);
-		attachtty(shpgrp);
-		}
-	if (interact)
-		{
-		signal(SIGTERM,SIG_IGN);
-		intr();
-		}
-}
-
-void addreswords(void)
-{
-char *reswds[] = {
-	"do", "done", "esac", "then", "elif", "else", "fi", "for", "case",
-	"if", "while", "function", "repeat", "time", "until", "exec", "command",
-	"select", "coproc", NULL
-	};
-int t0;
-
-	for (t0 = 0; reswds[t0]; t0++)
-		addhnode(strdup(reswds[t0]),mkanode(NULL,-1-t0),alhtab,NULL);
-}
-
-void runscripts(void)
-{
-	if (interact)
-		checkfirstmail();
-	if (opts[NORCS] == OPT_UNSET)
-		{
-#ifdef GLOBALZSHRC
-		source(GLOBALZSHRC);
-#endif
-		sourcehome(".zshrc");
-		if (islogin)
-			{
-#ifdef GLOBALZLOGIN
-			source(GLOBALZLOGIN);
-#endif
-			sourcehome(".zlogin");
-			}
-		}
-	if (opts['c'] == OPT_SET)
-		{
-		close(SHIN);
-		SHIN = movefd(open("/dev/null",O_RDONLY));
-		hungets(cmd);
-		strinbeg();
-		}
-}
-
-void ainit(void)
-{
-	alix = 0;		/* reset alias stack */
-	alstat = 0;
-	firstln = 1;
-}
End of init.c
echo init.pro 1>&2
sed 's/^-//' >init.pro <<'End of init.pro'
-void main(int argc, char **argv);
-void loop(void);
-void setflags(void);
-void parseargs(char **argv);
-void setmoreflags(void);
-void setupvals(void);
-void initialize(void);
-void addreswords(void);
-void runscripts(void);
-void ainit(void);
End of init.pro
echo jobs.c 1>&2
sed 's/^-//' >jobs.c <<'End of jobs.c'
-/*
-
-	jobs.c - job control
-
-	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"
-#include <sys/errno.h>
-
-#define WCOREDUMPED(x) ((x)&0x80)
-
-/* != 0 means the handler is active */
-
-static int handling = 0;
-
-/* != 0 means the shell is waiting for a job to complete */
-
-static int waiting = 0;
-
-/* != 0 means readline is active */
-
-extern int rl_active;
-
-/* != 0 means readline is waiting for a keypress */
-
-extern int rl_waiting;
-
-#ifdef INTHANDTYPE
-#define RETURN return 0
-#else
-#define RETURN return
-#endif
-
-/* the signal handler */
-
-HANDTYPE handler(int sig,int code)
-{
-long pid;
-int statusp;
-struct jobnode *jn;
-struct procnode *pn;
-struct rusage ru;
-
-	if (sig == SIGINT)
-		{
-		if (sigtrapped[SIGINT])
-			dotrap(SIGINT);
-		else
-			errflag = 1;
-		RETURN;
-		}
-	if (sig != SIGCHLD)
-		{
-		dotrap(sig);
-		RETURN;
-		}
-	for (;;)
-		{
-		pid = wait3(&statusp,WNOHANG|WUNTRACED,&ru);
-		if (pid == -1)
-			{
-			if (errno != ECHILD)
-				zerr("%e",errno);
-			RETURN;
-			}
-		if (!pid)
-			RETURN;
-		findproc(pid,&jn,&pn);	/* find the procnode of this pid */
-		if (jn)
-			{
-			pn->statusp = statusp;
-			handling = 1;
-			pn->ru_utime = ru.ru_utime;
-			pn->ru_stime = ru.ru_stime;
-			pn->endtime = time(NULL);
-			updatestatus(jn);
-			handling = 0;
-			}
-		else if (WIFSTOPPED(SP(statusp)))
-			kill(pid,SIGKILL);	/* kill stopped untraced children */
-		}
-	if (rl_active)
-		rl_prep_terminal();
-	RETURN;
-}
-
-/* change job table entry from stopped to running */
-
-void makerunning(struct jobnode *jn)
-{
-struct procnode *pn;
-
-	jn->stat &= ~STAT_STOPPED;
-	for (pn = jn->procs; pn; pn = pn->next)
-		if (WIFSTOPPED(SP(pn->statusp)))
-			pn->statusp = SP_RUNNING;
-}
-
-/* update status of job, possibly printing it */
-
-void updatestatus(struct jobnode *jn)
-{
-struct procnode *pn;
-int notrunning = 1,alldone = 1,val,job = jn-jobtab,somestopped = 0;
-
-	for (pn = jn->procs; pn; pn = pn->next)
-		{
-		if (pn->statusp == SP_RUNNING)
-			notrunning = 0;
-		if (pn->statusp == SP_RUNNING || WIFSTOPPED(SP(pn->statusp)))
-			alldone = 0;
-		if (WIFSTOPPED(SP(pn->statusp)))
-			somestopped = 1;
-		if (!pn->next && jn)
-			val = (WIFSIGNALED(SP(pn->statusp))) ?
-				0200 | WTERMSIG(SP(pn->statusp)) : WEXITSTATUS(SP(pn->statusp));
-		}
-	if (!notrunning)
-		return;
-	if (somestopped && (jn->stat & STAT_STOPPED))
-		return;
-	jn->stat |= (alldone) ? STAT_CHANGED|STAT_DONE :
-		STAT_CHANGED|STAT_STOPPED;
-	if (!alldone)
-		gettyinfo(&jn->ttyinfo);
-	if (job == curjob)
-		{
-		if (!val)
-			gettyinfo(&shttyinfo);
-		else
-			settyinfo(&shttyinfo);
-		lastval = val;
-		}
-	if (jn->stat & STAT_STOPPED)
-		{
-		prevjob = topjob;
-		topjob = job;
-		}
-	if ((isset(NOTIFY) || job == curjob) && jn->stat & STAT_LOCKED)
-		printjob(jn,0);
-	if (sigtrapped[SIGCHLD] && job != curjob)
-		dotrap(SIGCHLD);
-}
-
-/* find procnode and jobnode associated with pid */
-
-void findproc(int pid,struct jobnode **jptr,struct procnode **pptr)
-{
-struct procnode *pn;
-int jn;
-
-	for (jn = 1; jn != MAXJOB; jn++)
-		for (pn = jobtab[jn].procs; pn; pn = pn->next)
-			if (pn->pid == pid)
-				{
-				*pptr = pn;
-				*jptr = jobtab+jn;
-				return;
-				}
-	*pptr = NULL;
-	*jptr = NULL;
-}
-
-static char *sigmsg[32] = {
-	"done","hangup","interrupt","quit",
-	"illegal instruction","trace trap","IOT instruction","EMT instruction",
-	"floating exception","killed","bus error","segmentation fault",
-	"bad system call","broken pipe","SIGALRM","terminated",
-#ifdef USE_SUSPENDED
-	"SIGURG","suspended (signal)","suspended","continued",
-	"SIGCHLD","suspended (tty input)","suspended (tty output)","SIGIO",
-#else
-	"SIGURG","stopped (signal)","stopped","continued",
-	"SIGCHLD","stopped (tty input)","stopped (tty output)","SIGIO",
-#endif
-	"CPU time limit exceeded","file size limit exceeded","SIGVTALRM","SIGPROF",
-	"window changed","resource lost","SIGUSR1","SIGUSR2"
-	};
-
-/* lng = 0 means jobs 
-	lng = 1 means jobs -l
-	lng = 2 means jobs -p
-*/
-
-void printjob(struct jobnode *jn,int lng)
-{
-int job = jn-jobtab,len = 9,sig = -1,sflag = 0,llen,printed = 0;
-int conted = 0,lineleng = getlineleng(),doputnl = 0;
-struct procnode *pn;
-extern void rl_on_new_line(void);
-
-	if (lng < 0)
-		{
-		conted = 1;
-		lng = 0;
-		}
-
-	/* find length of longest signame, check to see if we
-		really need to print this job */
-
-	for (pn = jn->procs; pn; pn = pn->next)
-		{
-		if (pn->statusp != SP_RUNNING)
-			if (WIFSIGNALED(SP(pn->statusp)))
-				{
-				sig = WTERMSIG(SP(pn->statusp));
-				llen = strlen(sigmsg[sig]);
-				if (WCOREDUMPED(pn->statusp))
-					llen += 14;
-				if (llen > len)
-					len = llen;
-				if (sig != SIGINT && sig != SIGPIPE)
-					sflag = 1;
-				if (sig == SIGINT && job == curjob && interact)
-					doputnl = 1;
-				}
-			else if (WIFSTOPPED(SP(pn->statusp)))
-				{
-				sig = WSTOPSIG(SP(pn->statusp));
-				if (strlen(sigmsg[sig]) > len)
-					len = strlen(sigmsg[sig]);
-				}
-			else if (isset(PRINTEXITVALUE) && WEXITSTATUS(SP(pn->statusp)))
-				sflag = 1;
-		}
-	if (doputnl)
-		putc('\n',stderr);
-
-	/* print if necessary */
-
-	if (interact && jobbing && ((jn->stat & STAT_STOPPED) || sflag ||
-			job != curjob))
-		{
-		int len2,fline = 1;
-		struct procnode *qn;
-
-		if (handling && (!waiting || jn->stat & STAT_STOPPED))
-			putc('\n',stderr);
-		for (pn = jn->procs; pn;)
-			{
-			len2 = ((job == curjob) ? 5 : 10)+len; /* 2 spaces */
-			if (lng)
-				qn = pn->next;
-			else for (qn = pn->next; qn; qn = qn->next)
-				{
-				if (qn->statusp != pn->statusp)
-					break;
-				if (strlen(qn->text)+len2+((qn->next) ? 3 : 0) > lineleng)
-					break;
-				len2 += strlen(qn->text)+2;
-				}
-			if (job != curjob)
-				if (fline)
-					fprintf(stderr,"[%d]  %c ",jn-jobtab,(job == topjob) ? '+' :
-						(job == prevjob) ? '-' : ' ');
-				else
-					fprintf(stderr,(job > 9) ? "        " : "       ");
-			else
-				fprintf(stderr,"zsh: ");
-			if (lng)
-				if (lng == 1)
-					fprintf(stderr,"%d ",pn->pid);
-				else
-					{
-					fprintf(stderr,"%d ",jn->gleader);
-					lng = 0;
-					}
-			if (pn->statusp == SP_RUNNING)
-				if (!conted)
-					fprintf(stderr,"running%*s",len-7+2,"");
-				else
-					fprintf(stderr,"continued%*s",len-9+2,"");
-			else if (WIFEXITED(SP(pn->statusp)))
-				if (WEXITSTATUS(SP(pn->statusp)))
-					fprintf(stderr,"exit %-4d%*s",WEXITSTATUS(SP(pn->statusp)),
-						len-9+2,"");
-				else
-					fprintf(stderr,"done%*s",len-4+2,"");
-			else if (WIFSTOPPED(SP(pn->statusp)))
-				fprintf(stderr,"%-*s",len+2,sigmsg[WSTOPSIG(SP(pn->statusp))]);
-			else if (WCOREDUMPED(pn->statusp))
-				fprintf(stderr,"%s (core dumped)%*s",
-					sigmsg[WTERMSIG(SP(pn->statusp))],
-					len-14+2-strlen(sigmsg[WTERMSIG(SP(pn->statusp))]),"");
-			else
-				fprintf(stderr,"%-*s",len+2,sigmsg[WTERMSIG(SP(pn->statusp))]);
-			for (; pn != qn; pn = pn->next)
-				fprintf(stderr,(pn->next) ? "%s | " : "%s",pn->text);
-			putc('\n',stderr);
-			fline = 0;
-			}
-		printed = 1;
-		}
-
-	/* print "(pwd now: foo)" messages */
-
-	if (interact && job==curjob && strcmp(jn->cwd,cwd))
-		{
-		printf("(pwd now: ");
-		printdir(cwd);
-		printf(")\n");
-		fflush(stdout);
-		}
-
-	/* delete job if done */
-
-	if (jn->stat & STAT_DONE)
-		{
-		static struct jobnode zero;
-		struct procnode *nx;
-		char *s;
-
-		if (jn->stat & STAT_TIMED)
-			{
-			dumptime(jn);
-			printed = 1;
-			}
-		for (pn = jn->procs; pn; pn = nx)
-			{
-			nx = pn->next;
-			if (pn->text)
-				free(pn->text);
-			free(pn);
-			}
-		free(jn->cwd);
-		if (jn->filelist)
-			{
-			while (s = getnode(jn->filelist))
-				{
-				unlink(s);
-				free(s);
-				}
-			free(jn->filelist);
-			}
-		*jn = zero;
-		if (job == topjob)
-			{
-			topjob = prevjob;
-			prevjob = job;
-			}
-		if (job == prevjob)
-			setprevjob();
-		}
-	else
-		jn->stat &= ~STAT_CHANGED;
-	if (printed && rl_active)
-		{
-		rl_on_new_line();
-		if (rl_waiting)
-			rl_redisplay();
-		}
-}
-
-/* set the previous job to something reasonable */
-
-void setprevjob(void)
-{
-int t0;
-
-	for (t0 = MAXJOB-1; t0; t0--)
-		if (jobtab[t0].stat && jobtab[t0].stat & STAT_STOPPED &&
-				t0 != topjob && t0 != curjob)
-			break;
-	if (!t0)
-		for (t0 = MAXJOB-1; t0; t0--)
-			if (jobtab[t0].stat && t0 != topjob && t0 != curjob)
-				break;
-	prevjob = (t0) ? t0 : -1;
-}
-
-/* initialize a job table entry */
-
-void initjob(int flags)
-{
-	jobtab[curjob].cwd = strdup(cwd);
-	jobtab[curjob].stat = (flags & PFLAG_TIMED) | STAT_INUSE;
-	jobtab[curjob].ttyinfo = shttyinfo;
-	jobtab[curjob].gleader = 0;
-}
-
-/* add a process to the current job */
-
-struct procnode *addproc(long pid,char *text)
-{
-struct procnode *procnode;
-
-	if (!jobtab[curjob].gleader)
-		jobtab[curjob].gleader = proclast = pid;
-	proclast = pid;
-	procnode = alloc(sizeof(struct procnode));
-	procnode->pid = pid;
-	procnode->text = text;
-	procnode->next = NULL;
-	procnode->statusp = SP_RUNNING;
-	procnode->bgtime = time(NULL);
-	if (jobtab[curjob].procs)
-		{
-		struct procnode *n;
-
-		for (n = jobtab[curjob].procs; n->next && !n->next->lastfg; n = n->next);
-		procnode->next = n->next;
-		n->next = procnode;
-		}
-	else
-		jobtab[curjob].procs = procnode;
-	return procnode;
-}
-
-/* determine if it's all right to exec a command without
-	forking in last component of subshells; it's not ok if we have files
-	to delete */
-
-int execok(void)
-{
-struct jobnode *jn;
-
-	if (!exiting)
-		return 0;
-	for (jn = jobtab+1; jn != jobtab+MAXJOB; jn++)
-		if (jn->stat && jn->filelist)
-			return 0;
-	return 1;
-}
-
-/* wait for a SIGCHLD, wait for the handler to execute, and return */
-
-void chldsuspend(void)
-{
-struct sigvec vec = { handler,sigmask(SIGCHLD),SV_INTERRUPT };
-
-	sigvec(SIGCHLD,&vec,NULL);
-	sigpause(0);
-	signal(SIGCHLD,handler);
-}
-
-/* wait for the current job to finish */
-
-void waitjobs(void)
-{
-static struct jobnode zero;
-struct jobnode *jn;
-
-	if (jobtab[curjob].procs)	/* if any forks were done */
-		{
-		jobtab[curjob].stat |= STAT_LOCKED;
-		waiting = 1;
-		if (jobtab[curjob].stat & STAT_CHANGED)
-			printjob(jobtab+curjob,0);
-		while (jobtab[curjob].stat &&
-				!(jobtab[curjob].stat & (STAT_DONE|STAT_STOPPED)))
-			chldsuspend();
-		waiting = 0;
-		}
-	else	/* else do what printjob() usually does */
-		{
-		char *s;
-
-		jn = jobtab+curjob;
-		free(jn->cwd);
-		if (jn->filelist)
-			{
-			while (s = getnode(jn->filelist))
-				{
-				unlink(s);
-				free(s);
-				}
-			free(jn->filelist);
-			}
-		*jn = zero;
-		}
-	curjob = -1;
-}
-
-/* clear jobtab when entering subshells */
-
-void clearjobtab(void)
-{
-static struct jobnode zero;
-int t0;
-
-	for (t0 = 1; t0 != MAXJOB; t0++)
-		jobtab[curjob] = zero;
-}
-
-/* get a free entry in the job table to use */
-
-int getfreejob(void)
-{
-int mask,t0;
-
-	FOREVER	
-		{
-		mask = sigblock(sigmask(SIGCHLD));
-		for (t0 = 1; t0 != MAXJOB; t0++)
-			if (!jobtab[t0].stat)
-				{
-				sigsetmask(mask);
-				jobtab[t0].stat |= STAT_INUSE;
-				return t0;
-				}
-		sigsetmask(mask);
-		sleep(1);
-		}
-}
-
-/* print pids for & */
-
-void spawnjob(void)
-{
-struct procnode *pn;
-
-	if (!subsh)
-		{
-		if (topjob == -1 || !(jobtab[topjob].stat & STAT_STOPPED))
-			{
-			topjob = curjob;
-			setprevjob();
-			}
-		else if (prevjob == -1 || !(jobtab[prevjob].stat & STAT_STOPPED))
-			prevjob = curjob;
-		if (interact && jobbing)
-			{
-			fprintf(stderr,"[%d]",curjob);
-			for (pn = jobtab[curjob].procs; pn; pn = pn->next)
-				fprintf(stderr," %d",pn->pid);
-			fprintf(stderr,"\n");
-			}
-		}
-	jobtab[curjob].stat |= STAT_LOCKED;
-	curjob = -1;
-}
-
-void fixsigs(void)
-{
-	sigsetmask(0);
-}
-
-/* timing */
-
-static void addtimeval(struct timeval *s,struct timeval *t)
-{
-	s->tv_sec += t->tv_sec+(s->tv_usec+t->tv_usec)/1000000;
-	s->tv_usec = (s->tv_usec+t->tv_usec)%1000000;
-}
-
-static void printtime(time_t real,struct timeval *u,struct timeval *s,char *desc)
-{
-	if (!desc)
-		desc = "";
-	fprintf(stderr,"real: %lds  user: %ld.%03lds  sys: %ld.%03lds\n",
-		real,u->tv_sec,u->tv_usec/1000,s->tv_sec,s->tv_usec/1000);
-}
-
-static void printheader(void)
-{
-	fprintf(stderr,"  real       user      system\n");
-}
-
-static void printtimes(time_t real,struct timeval *u,struct timeval *s,char *desc)
-{
-	if (!desc)
-		desc = "";
-	fprintf(stderr,"% 8lds  % 4d.%03lds  % 4d.%03lds  %s\n",
-		real,u->tv_sec,u->tv_usec/1000,s->tv_sec,s->tv_usec/1000,desc);
-}
-
-void dumptime(struct jobnode *jn)
-{
-struct procnode *pn = jn->procs;
-struct timeval utot = { 0,0 },stot = { 0,0 };
-time_t maxend,minbeg;
-
-	if (!jn->procs)
-		return;
-	if (!jn->procs->next)
-		printtime(pn->endtime-pn->bgtime,&pn->ru_utime,&pn->ru_stime,pn->text);
-	else
-		{
-		maxend = jn->procs->endtime;
-		minbeg = jn->procs->bgtime;
-		printheader();
-		for (pn = jn->procs; pn; pn = pn->next)
-			{
-			printtimes(pn->endtime-pn->bgtime,&pn->ru_utime,&pn->ru_stime,pn->text);
-			addtimeval(&utot,&pn->ru_utime);
-			addtimeval(&stot,&pn->ru_stime);
-			if (pn->endtime > maxend)
-				maxend = pn->endtime;
-			if (pn->bgtime < minbeg)
-				minbeg = pn->bgtime;
-			}
-		printtimes(maxend-minbeg,&utot,&stot,"total");
-		}
-}
-
-/* SIGHUP any jobs left running */
-
-void killrunjobs(void)
-{
-int t0,killed = 0;
-
-	for (t0 = 1; t0 != MAXJOB; t0++)
-		if (t0 != curjob && jobtab[t0].stat &&
-				!(jobtab[t0].stat & STAT_STOPPED))
-			{
-			killpg(jobtab[t0].gleader,SIGHUP);
-			killed++;
-			}
-	if (killed)
-		zerr("warning: %d jobs SIGHUPed",killed);
-}
-
-/* check to see if user has jobs running/stopped */
-
-void checkjobs(void)
-{
-int t0;
-
-	for (t0 = 1; t0 != MAXJOB; t0++)
-		if (t0 != curjob && jobtab[t0].stat)
-			break;
-	if (t0 != MAXJOB)
-		{
-		if (jobtab[t0].stat & STAT_STOPPED)
-			{
-#ifdef USE_SUSPENDED
-			zerr("you have suspended jobs.");
-#else
-			zerr("you have stopped jobs.");
-#endif
-			}
-		else
-			zerr("you have running jobs.");
-		stopmsg = 1;
-		}
-}
-
-/* send a signal to a job (simply involves killpg if monitoring is on) */
-
-int killjb(struct jobnode *jn,int sig)
-{
-struct procnode *pn;
-int err;
-
-	if (jobbing)
-		return(killpg(jn->gleader,sig));
-	for (pn = jn->procs; pn; pn = pn->next)
-		if ((err = kill(pn->pid,sig)) == -1 && errno != ESRCH)
-			return -1;
-	return err;
-}
-
End of jobs.c
echo jobs.pro 1>&2
sed 's/^-//' >jobs.pro <<'End of jobs.pro'
-HANDTYPE handler(int sig,int code);
-void makerunning(struct jobnode *jn);
-void updatestatus(struct jobnode *jn);
-void findproc(int pid,struct jobnode **jptr,struct procnode **pptr);
-void printjob(struct jobnode *jn,int lng);
-void setprevjob(void);
-void initjob(int flags);
-struct procnode *addproc(long pid,char *text);
-int execok(void);
-void chldsuspend(void);
-void waitjobs(void);
-void clearjobtab(void);
-int getfreejob(void);
-void spawnjob(void);
-void fixsigs(void);
-void dumptime(struct jobnode *jn);
-void killrunjobs(void);
-void checkjobs(void);
-int killjb(struct jobnode *jn,int sig);
End of jobs.pro
echo lex.c 1>&2
sed 's/^-//' >lex.c <<'End of lex.c'
-/*
-
-	lex.c - lexical analysis
-
-	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"
-
-/* match the current token and get another
-	(actually just get another) */
-
-void matchit(void)
-{
-	do
-		gettok();
-	while (exalias());
-}
-
-int len = 0,bsiz = 256;
-char *bptr;
-
-/* add a char to the string buffer */
-
-void add(int c)
-{
-	*bptr++ = c;
-	if (bsiz == ++len)
-		bptr = len+(tstr = realloc(tstr,bsiz *= 2));
-}
-
-/* get a token */
-
-void gettok(void)
-{
-int bct = 0,pct = 0;
-int c,d,intpos = 1;
-static int dbparens = 0;
-
-beginning:
-	hlastw = NULL;
-	tstr = NULL;
-	while (zspace(c = hgetc()) || c == '\t' || c == ' ');
-	firstln = 0;
-	hwbegin();
-	hwaddc(c);
-	if (dbparens)	/* handle ((...)) */
-		{
-		int pct = 2;
-
-		peek = STRING;
-		len = dbparens = 0;
-		bptr = tstr = zalloc(bsiz = 256);
-		for (;;)
-			{
-			if (c == '(')
-				pct++;
-			else if (c == ')')
-				pct--;
-			else if (c == '\n')
-				{
-				zerr("parse error: )) expected");
-				peek = HERR;
-				free(tstr);
-				return;
-				}
-			else if (c == '$')
-				c = Qstring;
-			if (pct >= 2)
-				add(c);
-			if (pct)
-				c = hgetc();
-			else
-				break;
-			}
-		*bptr = '\0';
-		return;
-		}
-	peekfd = -1;
-	if (isdigit(c))	/* handle 1< foo */
-		{
-		d = hgetc();
-		hungetc(d);
-		if (d == '>' || d == '<')
-			{
-			peekfd = c-'0';
-			c = hgetc();
-			}
-		}
-
-	/* chars in initial position in word */
-
-	switch (c)
-		{
-		case '\\':
-			d = hgetc();
-			if (d == '\n')
-				goto beginning;
-			hungetc(d);
-			break;
-		case EOF:
-			peek = EOF;
-			return;
-		case HERR:
-			peek = HERR;
-			return;
-		case '\n':
-			peek = NEWLIN;
-			return;
-		case ';':
-			d = hgetc();
-			if (d != ';')
-				{
-				hungetc(d);
-				peek = SEMI;
-				}
-			else
-				peek = DSEMI;
-			return;
-		case '!':
-			if (!incmd)
-				{
-				peek = BANG;
-				return;
-				}
-			break;
-		case '&':
-			d = hgetc();
-			if (d != '&')
-				{
-				hungetc(d);
-				peek = AMPER;
-				}
-			else
-				peek = DAMPER;
-			return;
-		case '|':
-			d = hgetc();
-			if (d == '|')
-				peek = DBAR;
-			else if (d == '&')
-				peek = BARAMP;
-			else
-				{
-				hungetc(d);
-				peek = BAR;
-				}
-			return;
-		case '(':
-			if (incmd)
-				break;
-			d = hgetc();
-			if (d == '(')
-				{
-				peek = STRING;
-				tstr = strdup("let");
-				dbparens = 1;
-				return;
-				}
-			hungetc(d);
-			peek = INPAR;
-			return;
-		case ')':
-			peek = OUTPAR;
-			return;
-		case '{':
-			if (incmd)
-				break;
-			peek = INBRACE;
-			return;
-		case '}':
-			peek = OUTBRACE;
-			return;
-		case '<':
-			d = hgetc();
-			if (incmd && d == '(')
-				{
-				hungetc(d);
-				break;
-				}
-			else if (d == '<')
-				{
-				int e = hgetc();
-
-				hungetc(e);
-				if (e == '(')
-					{
-					hungetc(d);
-					peek = INANG;
-					}
-				else
-					peek = DINANG;
-				}
-			else if (d == '&')
-				peek = INANGAMP;
-			else
-				{
-				peek = INANG;
-				hungetc(d);
-				}
-			return;
-		case '>':
-			d = hgetc();
-			if (d == '(')
-				{
-				hungetc(d);
-				break;
-				}
-			else if (d == '&')
-				{
-				d = hgetc();
-				if (d == '!')
-					peek = OUTANGAMPBANG;
-				else
-					{
-					hungetc(d);
-					peek = OUTANGAMP;
-					}
-				}
-			else if (d == '!')
-				peek = OUTANGBANG;
-			else if (d == '>')
-				{
-				d = hgetc();
-				if (d == '&')
-					{
-					d = hgetc();
-					if (d == '!')
-						peek = DOUTANGAMPBANG;
-					else
-						{
-						hungetc(d);
-						peek = DOUTANGAMP;
-						}
-					}
-				else if (d == '!')
-					peek = DOUTANGBANG;
-				else if (d == '(')
-					{
-					hungetc(d);
-					hungetc('>');
-					peek = OUTANG;
-					}
-				else
-					{
-					hungetc(d);
-					peek = DOUTANG;
-					}
-				}
-			else
-				{
-				hungetc(d);
-				peek = OUTANG;
-				}
-			return;
-		case '#':
-#ifndef INTERACTIVE_COMMENTS
-			if (interact)
-				break;
-#endif
-			while ((c = hgetch()) != '\n' && !istok(c) && c != EOF);
-			if (c == '\n')
-				peek = NEWLIN;
-			else
-				errflag = 1;
-			return;
-		}
-
-	/* we've started a string, now get the rest of it, performing
-		tokenization */
-
-	peek = STRING;
-	len = 0;
-	bptr = tstr = zalloc(bsiz = 256);
-	for(;;)
-		{
-		if (c == ';' || c == '&' || c == EOF ||
-				c == HERR || c == '\03' || c == '\n' || 
-				c == ' ' || c == '\t' || znspace(c))
-			break;
-		if (c == '#')
-			c = Pound;
-		else if (c == ')')
-			{
-			if (!pct)
-				break;
-			pct--;
-			c = Outpar;
-			}
-		else if (c == ',')
-			c = Comma;
-		else if (c == '|')
-			{
-			if (!pct)
-				break;
-			c = Bar;
-			}
-		else if (c == '$')
-			{
-			d = hgetc();
-
-			c = String;
-			if (d == '[')
-				{
-				add(String);
-				add(Inbrack);
-				while ((c = hgetc()) != ']' && !istok(c) && c != EOF)
-					add(c);
-				c = Outbrack;
-				}
-			else if (d == '(')
-				{
-				add(String);
-				skipcomm();
-				c = Outpar;
-				}
-			else
-				hungetc(d);
-			}
-		else if (c == '^')
-			c = Hat;
-		else if (c == '[')
-			c = Inbrack;
-		else if (c == ']')
-			c = Outbrack;
-		else if (c == '*')
-			c = Star;
-		else if (intpos && c == '~')
-			c = Tilde;
-		else if (c == '?')
-			c = Quest;
-		else if (c == '(')
-			{
-			int d = hgetc();
-
-			hungetc(d);
-			if (!incmd)
-				break;
-#if 0
-			if (d != ')' && intpos)
-				{
-				add(Inang);
-				skipcomm();
-				c = Outpar;
-				}
-			else
-#endif
-				{
-				pct++;
-				c = Inpar;
-				}
-			}
-		else if (c == '{')
-			{
-			c = Inbrace;
-			bct++;
-			}
-		else if (c == '}')
-			{
-			if (!bct)
-				break;
-			c = Outbrace;
-			bct--;
-			}
-		else if (c == '>')
-			{
-			d = hgetc();
-			if (d != '(')
-				{
-				hungetc(d);
-				break;
-				}
-			add(Outang);
-			skipcomm();
-			c = Outpar;
-			}
-		else if (c == '<')
-			{
-			d = hgetc();
-			if (!(isdigit(d) || d == '-' || d == '>' || d == '(' || d == ')'))
-				{
-				hungetc(d);
-				break;
-				}
-			c = Inang;
-			if (d == '(')
-				{
-				add(c);
-				skipcomm();
-				c = Outpar;
-				}
-			else if (d == ')')
-				hungetc(d);
-			else
-				{
-				add(c);
-				c = d;
-				while (c != '>' && !istok(c) && c != EOF)
-					add(c),c = hgetc();
-				if (c == EOF)
-					{
-					errflag = 1;
-					peek = EOF;
-					return;
-					}
-				c = Outang;
-				}
-			}
-		else if (c == '=')
-			{
-			if (intpos)
-				{
-				d = hgetc();
-				if (d != '(')
-					{
-					hungetc(d);
-					c = Equals;
-					}
-				else
-					{
-					add(Equals);
-					skipcomm();
-					c = Outpar;
-					}
-				}
-			else if (peek != ENVSTRING)
-				{
-				peek = ENVSTRING;
-				intpos = 2;
-				}
-			}
-		else if (c == '\\')
-			{
-			c = hgetc();
-
-			if (c == '\n')
-				{
-				c = hgetc();
-				continue;
-				}
-			add(c);
-			c = hgetc();
-			continue;
-			}
-		else if (c == '\'')
-			{
-			add(Nularg);
-
-			/* we add the Nularg to prevent this:
-
-			echo $PA'TH'
-
-			from printing the path. */
-
-			while ((c = hgetc()) != '\'' && !istok(c) && c != EOF)
-				add(c);
-			if (c == EOF)
-				{
-				errflag = 1;
-				peek = EOF;
-				return;
-				}
-			c = Nularg;
-			}
-		else if (c == HQUOT)
-			{
-			add(Nularg);
-			while ((c = hgetc()) != HQUOT && !istok(c) && c != EOF)
-				add(c);
-			if (c == EOF)
-				{
-				errflag = 1;
-				peek = EOF;
-				return;
-				}
-			c = Nularg;
-			}
-		else if (c == '\"')
-			{
-			add(Nularg);
-			while ((c = hgetc()) != '\"' && !istok(c) && c != EOF)
-				if (c == '\\')
-					{
-					c = hgetc();
-					if (c != '\n')
-						{
-						if (c != '$' && c != '\\' && c != '\"' && c != '`')
-							add('\\');
-						add(c);
-						}
-					}
-				else
-					{
-					if (c == '$')
-						{
-						int d = hgetc();
-
-						if (d == '(')
-							{
-							add(Qstring);
-							skipcomm();
-							c = Outpar;
-							}
-						else if (d == '[')
-							{
-							add(String);
-							add(Inbrack);
-							while ((c = hgetc()) != ']' && c != EOF)
-								add(c);
-							c = Outbrack;
-							}
-						else
-							{
-							c = Qstring;
-							hungetc(d);
-							}
-						}
-					else if (c == '`')
-						c = Qtick;
-					add(c);
-					}
-			if (c == EOF)
-				{
-				errflag = 1;
-				peek = EOF;
-				return;
-				}
-			c = Nularg;
-			}
-		else if (c == '`')
-			{
-			add(Tick);
-			while ((c = hgetc()) != '`' && !istok(c) && c != EOF)
-				if (c == '\\')
-					{
-					c = hgetc();
-					if (c != '\n')
-						{
-						if (c != '`' && c != '\\' && c != '$')
-							add('\\');
-						add(c);
-						}
-					}
-				else
-					{
-					if (c == '$')
-						c = String;
-					add(c);
-					}
-			if (c == EOF)
-				{
-				errflag = 1;
-				peek = EOF;
-				return;
-				}
-			c = Tick;
-			}
-		add(c);
-		c = hgetc();
-		if (intpos)
-			intpos--;
-		}
-	if (c == HERR)
-		{
-		free(tstr);
-		peek = HERR;
-		return;
-		}
-	hungetc(c);
-	*bptr = '\0';
-}
-
-/* expand aliases, perhaps */
-
-int exalias(void)
-{
-struct anode *an;
-char *s;
-
-	s = hwadd();
-	if (alix != MAXAL && (an = gethnode(s,alhtab)) && !an->inuse &&
-			!(an->cmd && incmd && alstat != ALSTAT_MORE))
-		{
-		if (an->cmd < 0)
-			{
-			peek = DO-an->cmd-1;
-			return 0;
-			}
-		an->inuse = 1;
-		hungets(strdup(ALPOPS));
-		hungets(strdup((alstack[alix++] = an)->text));
-		alstat = 0;
-		if (tstr)
-			free(tstr);
-		return 1;
-		}
-	return 0;
-}
-
-/* != 0 if c is not a newline, but in IFS */
-
-int zspace(int c)
-{
-	if (c == '\n')
-		return 0;
-	return znspace(c);
-}
-
-/* != 0 if c is in IFS */
-
-int znspace(int c)
-{
-char *ptr = ifs;
-
-	while (*ptr)
-		if (*ptr++ == c)
-			return 1;
-	return 0;
-}
-
-/* skip (...) */
-
-void skipcomm(void)
-{
-int pct = 1,c;
-
-	c = Inpar;
-	do
-		{
-		add(c);
-reget:
-		c = hgetc();
-		if (istok(c) || c == EOF)
-			break;
-		else if (c == '(') pct++;
-		else if (c == ')') pct--;
-		else if (c == '\\')
-			{
-			add(c);
-			c = hgetc();
-			}
-		else if (c == '\'')
-			{
-			add(c);
-			while ((c = hgetc()) != '\'' && !istok(c) && c != EOF)
-				add(c);
-			}
-		else if (c == HQUOT)
-			{
-			while ((c = hgetc()) != HQUOT && !istok(c) && c != EOF)
-				add(c);
-			goto reget;
-			}
-		else if (c == '\"')
-			{
-			add(c);
-			while ((c = hgetc()) != '\"' && !istok(c) && c != EOF)
-				if (c == '\\')
-					{
-					add(c);
-					add(hgetc());
-					}
-				else add(c);
-			}
-		else if (c == '`')
-			{
-			add(c);
-			while ((c = hgetc()) != '`' && c != HERR && c != EOF)
-				if (c == '\\') add(c), add(hgetc());
-				else add(c);
-			}
-		}
-	while(pct);
-}
-
End of lex.c
echo lex.pro 1>&2
sed 's/^-//' >lex.pro <<'End of lex.pro'
-void matchit(void);
-void add(int c);
-void gettok(void);
-int exalias(void);
-int zspace(int c);
-int znspace(int c);
-void skipcomm(void);
End of lex.pro
echo loop.c 1>&2
sed 's/^-//' >loop.c <<'End of loop.c'
-/*
-
-	loop.c - parsing and executing loop constructs
-
-	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"
-
-/* parse a for/select loop */
-
-int parfor(comm comm,int isfor)
-{
-struct fornode *node = alloc(sizeof(struct fornode));
-char *comnam = (isfor) ? "for" : "select";
-
-	comm->type = (isfor) ? CFOR : CSELECT;
-	comm->info = node;
-	if (peek != STRING)
-		{
-		zerr("parse error in %s: identifier expected",comnam);
-		errflag = 1;
-		return 0;
-		}
-	node->name = tstr;
-	matchit();
-	node->list = NULL;
-	node->inflag = 0;
-	if (peek == STRING && !strcmp("in",tstr))
-	   {
-		node->inflag = 1;
-		free(tstr);
-		matchit();
-		while (peek == STRING)
-			{
-			addnode(comm->args,tstr);
-			matchit();
-			}
-		}
-	if (peek != NEWLIN && peek != SEMI)
-		{
-		zerr("parse error: bad token in '%s' list",comnam);
-		freecmd(comm);
-		return 1;
-		}
-	incmd = 0;
-	matchit();
-	while (peek == NEWLIN)
-		matchit();
-	if (peek != DO)
-		{
-		zerr("parse error: 'do' expected");
-		freecmd(comm);
-		return 1;
-		}
-	matchit();
-	if (!(node->list = parlist(1)))
-		{
-		freecmd(comm);
-		return 1;
-		}
-	if (peek != DONE)
-		{
-		zerr("parse error: 'done' expected");
-		freecmd(comm);
-		return 1;
-		}
-	matchit();
-	return 0;
-}
- 
-int parcase(comm comm)
-{
-struct casenode *node = alloc(sizeof(struct casenode)),*last = NULL;
-char *tok; /* add FREES to this function */
-
-	comm->type = CCASE;
-	comm->info = node;
-	if (peek != STRING)
-		{
-		zerr("parse error in case: identifier expected");
-		errflag = 1;
-		return 0;
-		}
-	addnode(comm->args,tstr);
-	matchit();
-	if (peek != STRING || strcmp(tstr,"in"))
-		{
-		zerr("parse error in case: `in' expected");
-		errflag = 1;
-		return 0;
-		}
-	while (tok = getcasepat())
-		{
-		node = alloc(sizeof(struct casenode));
-		node->pat = tok;
-		if (last)
-			last->next = node;
-		else
-			comm->info = node;
-		(last = node)->list = parlist(1);
-		if (peek != DSEMI)
-			{
-			zerr("parse error: ;; expected");
-			return 1;
-			}
-		}
-	if (!last)
-		{
-		zerr("null case construct");
-		return 1;
-		}
-	return 0;
-}
-
-/* get a case pattern: foo) */
-
-char *getcasepat(void)
-{
-int c,bsiz = 256,ct = 0,pct = 0,qt = 0;
-char *buf = zalloc(bsiz),*ptr,*s;
- 
-	peek = EMPTY;
-	while (znspace(c = hgetc()))
-		{
-		if (c == '\n')
-			{
-			hwbegin();
-			hwaddc('\n');
-			hwadd();
-			}
-		}
-	ptr = buf;
-	hwbegin();
-	hwaddc(c);
-	while (c != ')' || pct)
-		{
-		for (s = tokens; *s; s++)
-			if (*s == c)
-				{
-				c = (s-tokens)+Pound;
-				break;
-				}
-		if (qt)
-			{
-			if (c == '\'')
-				{
-				qt = 0;
-				c = hgetc();
-				continue;
-				}
-			if (c == EOF)
-				{
-				qt = 0;
-				continue;
-				}
-			}
-		else
-			{
-			if (c == '\\')
-				c = hgetc();
-			if (c == '\'')
-				{
-				qt = 1;
-				c = hgetc();
-				continue;
-				}
-			if (c == Inpar)
-				pct++;
-			if (c == Outpar)
-				pct--;
-			if (ct == 4 && (znspace(c)||c ==';'||c=='&') && !strncmp(buf,"esac",4))
-				{
-				hungetc(c);
-				hwadd();
-				free(buf);
-				matchit();
-				return NULL;
-				}
-			if (c == '\n' || c == EOF)
-				{
-				free(buf);
-				zerr("parse error: 'esac' expected");
-				return NULL;
-				}
-			}
-		if (c == HERR)
-			{
-			free(buf);
-			return NULL;
-			}
-		*ptr++ = c;
-		if (++ct == bsiz)
-			{
-			ptr = zalloc(bsiz *= 2);
-			memcpy(ptr,buf,ct);
-			free(buf);
-			buf = ptr;
-			ptr = buf+ct;
-			}
-		c = hgetc();
-		}
-	*ptr = 0;
-	hwadd();
-	return buf;
-}
- 
-int parif(comm comm)
-{
-struct ifnode *node = alloc(sizeof(struct ifnode));
- 
-	comm->type = CIF;
-	comm->info = node;
-do_then:
-	node->next = NULL;
-	if (!(node->ifl = parlist(1)))
-		{
-		freecmd(comm);
-		return 1;
-		}
-	if (peek != THEN)
-		{
-		zerr("parse error: 'then' expected");
-		freecmd(comm);
-		return 1;
-		}
-	matchit();
-	if (!(node->thenl = parlist(1)))
-		{
-		freecmd(comm);
-		return 1;
-		}
-	if (peek == ELIF)
-		{
-		matchit();
-		node = node->next = alloc(sizeof(struct ifnode));
-		goto do_then;
-		}
-	else if (peek == ELSE)
-		{
-		matchit();
-		node = node->next = alloc(sizeof(struct ifnode));
-		node->next = NULL;
-		node->ifl = NULL;
-		if (!(node->thenl = parlist(1)))
-			{
-			freecmd(comm);
-			return 1;
-			}
-		}
-	if (peek != FI)
-		{
-		zerr("parse error: 'fi' expected");
-		freecmd(comm);
-		return 1;
-		}
-	matchit();
-	return 0;
-}
-
-/* parse while or until */
-
-int parwhile(comm comm,int cond)
-{
-struct whilenode *node = alloc(sizeof (struct whilenode));
- 
-	comm->type = CWHILE;
-	comm->info = node;
-	node->cond = cond;
-	node->loop = node->cont = NULL;
-	if (!(node->cont = parlist(1)))
-		{
-		freecmd(comm);
-		return NULL;
-		}
-	if (peek != DO)
-		{
-		zerr("parse error: 'do' expected");
-		freecmd(comm);
-		return 1;
-		}
-	matchit();
-	node->loop = parlist(1);
-	if (peek != DONE)
-		{
-		zerr("parse error: 'done' expected");
-		freecmd(comm);
-		return 1;
-		}
-	matchit();
-	return 0;
-}
- 
-int parrepeat(comm comm)
-{
-struct repeatnode *node = alloc(sizeof (struct repeatnode));
-
-	comm->type = CREPEAT;
-	comm->info = node;
-	node->list = NULL;
-	if (peek != STRING || !isdigit(*tstr))
-		{
-		zerr("parse error: number expected");
-		freecmd(comm);
-		return 1;
-		}
-	node->count = atoi(tstr);
-	free(tstr);
-	incmd = 0;
-	do
-		matchit();
-	while (peek == NEWLIN);
-	if (peek != DO)
-		{
-		zerr("parse error: 'do' expected");
-		freecmd(comm);
-		return 1;
-		}
-	matchit();
-	node->list = parlist(1);
-	if (peek != DONE)
-		{
-		zerr("parse error: 'done' expected");
-		freecmd(comm);
-		return 1;
-		}
-	matchit();
-	return 0;
-}
-
-void execfor(comm comm)
-{
-list list;
-struct fornode *node;
-char *str;
-table args;
-int cj = curjob;
-
-	loops++;
-	exiting = 0;
-	node = comm->info;
-	args = comm->args;
-	if (!node->inflag)
-		{
-		args = duptable(pparms,dupstr);
-		freestr(getnode(args));
-		}
-	while (str = getnode(args))
-		{
-		setparm(strdup(node->name),str,0,0);
-		list = duplist(node->list);
-		execlist(list);
-		if (breaks)
-			{
-			breaks--;
-			if (breaks || !contflag)
-				break;
-			contflag = 0;
-			}
-		}
-	curjob = cj;
-}
-
-void execselect(comm comm)
-{
-list list;
-struct fornode *node;
-char *str,*s;
-table args;
-Node n;
-int cj = curjob,t0;
-
-	loops++;
-	node = comm->info;
-	args = comm->args;
-	exiting = 0;
-	for (;;)
-		{
-		do
-			{
-			for (t0 = 1,n = args->first; n; n=n->next,t0++)
-				fprintf(stderr,"%d %s\n",t0,n->dat);
-			if (interact && SHTTY != -1)
-				{
-				inittty();
-				str = readline(putprompt("PROMPT3"));
-				}
-			else
-				str = fgets(zalloc(256),256,bshin);
-			if (!str || errflag)
-				{
-				fprintf(stderr,"\n");
-				goto done;
-				}
-			if (s = strchr(str,'\n'))
-				*s = '\0';
-			}
-		while (!*str);
-		setparm(strdup("REPLY"),str,0,0);
-		t0 = atoi(str);
-		if (!t0)
-			str = "";
-		else
-			{
-			for (t0--,n = args->first; n && t0; n=n->next,t0--);
-			if (n)
-				str = n->dat;
-			else
-				str = "";
-			}
-		setparm(strdup(node->name),strdup(str),0,0);
-		list = duplist(node->list);
-		execlist(list);
-		if (breaks)
-			{
-			breaks--;
-			if (breaks || !contflag)
-				break;
-			contflag = 0;
-			}
-		if (errflag)
-			break;
-		}
-done:
-	curjob = cj;
-}
- 
-void execwhile(comm comm)
-{
-list list;
-struct whilenode *node;
-int cj = curjob; 
-
-	loops++;
-	node = comm->info;
-	exiting = 0;
-	FOREVER
-		{
-		list = duplist(node->cont);
-		execlist(list);
-		if (!((lastval == 0) ^ node->cond))
-			break;
-		if (breaks)
-			{
-			breaks--;
-			if (breaks || !contflag)
-				break;
-			contflag = 0;
-			}
-		list = duplist(node->loop);
-		execlist(list);
-		}
-	curjob = cj;
-}
- 
-void execrepeat(comm comm)
-{
-list list;
-struct repeatnode *node;
-int cj = curjob;
-
-	loops++;
-	node = comm->info;
-	exiting = 0;
-	while (node->count--)
-		{
-		list = duplist(node->list);
-		execlist(list);
-		if (breaks)
-			{
-			breaks--;
-			if (breaks || !contflag)
-				break;
-			contflag = 0;
-			}
-		if (lastval)
-			break;
-		}
-	curjob = cj;
-}
- 
-void execif(comm comm)
-{
-list list;
-struct ifnode *node;
-int cj = curjob;
-
-	node = comm->info;
-	exiting = 0;
-	while (node)
-		{
-		if (node->ifl)
-			{
-			list = duplist(node->ifl);
-			execlist(list);
-			if (lastval)
-				{
-				node = node->next;
-				continue;
-				}
-			}
-		list = duplist(node->thenl);
-		execlist(list);
-		break;
-		}
-	curjob = cj;
-}
- 
-void execcase(comm comm)
-{
-list list;
-struct casenode *node;
-char *word;
-table args;
-int cj = curjob;
-
-	node = comm->info;
-	args = comm->args;
-	exiting = 0;
-	if (!args->first || args->first->next)
-		{
-		zerr("bad case statement");
-		errflag = 1;
-		return;
-		}
-	word = args->first->dat;
-	while (node)
-		if (matchpat(word,node->pat))
-			break;
-		else
-			node = node->next;
-	if (node)
-		{
-		list = duplist(node->list);
-		execlist(list);
-		}
-	curjob = cj;
-}
- 
-list duplist(list xlist)
-{
-list nlist;
- 
-	if (!xlist)
-		return NULL;
-	nlist = alloc(sizeof(struct lnode));
-	nlist->left = duplist2(xlist->left);
-	nlist->right = duplist(xlist->right);
-	nlist->type = xlist->type;
-	return nlist;
-}
-
-void freelist(list xlist)
-{
-	if (xlist)
-		{
-		freelist2(xlist->left);
-		freelist(xlist->right);
-		free(xlist);
-		}
-}
-
-list2 duplist2(list2 x)
-{
-list2 y;
-
-	if (!x)
-		return NULL;
-	y = alloc(sizeof(struct l2node));
-	*y = *x;
-	y->left = duppline(x->left);
-	y->right = duplist2(x->right);
-	return y;
-}
-
-void freelist2(list2 x)
-{
-	if (x)
-		{
-		freepline(x->left);
-		freelist2(x->right);
-		free(x);
-		}
-}
-
-pline duppline(pline xpline)
-{
-pline npline;
- 
-	if (!xpline)
-		return NULL;
-	npline = alloc(sizeof(struct pnode));
-	npline->left = dupcomm(xpline->left);
-	npline->right = duppline(xpline->right);
-	npline->type = xpline->type;
-	return npline;
-}
-
-void freepline(pline x)
-{
-	if (x)
-		{
-		freecmd(x->left);
-		freepline(x->right);
-		free(x);
-		}
-}
-
-comm dupcomm(comm xcomm)
-{
-comm ncomm;
-void *(*duprs[])(void *) = {dupfor,dupwhile,duprepeat,dupif,dupcase};
-int type;
- 
-	if (!xcomm)
-		return NULL;
-	ncomm = alloc(sizeof(struct cnode));
-	ncomm->left = duplist(xcomm->left);
-	ncomm->cmd = dupstr(xcomm->cmd);
-	ncomm->args = duptable(xcomm->args,dupstr);
-	ncomm->redir = duptable(xcomm->redir,dupfnode);
-	ncomm->vars = (xcomm->vars) ? duptable(xcomm->vars,dupstr) : NULL;
-	ncomm->type = type = xcomm->type;
-	if (type >= CFOR && type <= CCASE)
-		ncomm->info = (duprs[type-CFOR])(xcomm->info);
-	return ncomm;
-}
-
-void freecmd(comm x)
-{
-	if (x)
-		{
-		freelist(x->left);
-		if (x->cmd)
-			free(x->cmd);
-		if (x->args)
-			freetable(x->args,freestr);
-		if (x->redir)
-			freetable(x->redir,freeredir);
-		if (x->vars)
-			freetable(x->vars,freestr);
-/*		if (x->info)
-			freeinfo(x->info);*/
-		free(x);
-		}
-}
-
-void *dupstr(void *str)
-{
-	if (!str)
-		return NULL;
-	return strdup(str);
-}
-
-void *dupfnode(void *i)
-{
-struct fnode *fn = i,*nfn = alloc(sizeof(struct fnode));
- 
-	if (!i)
-		return NULL;
-	*nfn = *fn;
-	if (nfn->type < HEREDOC)
-		nfn->u.name = strdup(fn->u.name);
-	return nfn;
-}
-
-void *dupfor(void *i)
-{
-struct fornode *nnode,*node = i;
- 
-	nnode = alloc(sizeof(struct fornode));
-	*nnode = *(struct fornode *) i;
-	nnode->name = strdup(node->name);
-	nnode->list = duplist(node->list);
-	return nnode;
-}
- 
-void *dupcase(void *i)
-{
-struct casenode *nnode,*node = i;
- 
-	if (!i)
-		return NULL;
-	nnode = alloc(sizeof(struct casenode));
-	nnode->next = dupcase(node->next);
-	nnode->list = duplist(node->list);
-	nnode->pat = strdup(node->pat);
-	return nnode;
-}
- 
-void *dupif(void *i)
-{
-struct ifnode *nnode,*node = i;
- 
-	if (!i)
-		return NULL;
-	nnode = alloc(sizeof(struct ifnode));
-	nnode->next = dupif(node->next);
-	nnode->ifl = duplist(node->ifl);
-	nnode->thenl = duplist(node->thenl);
-	return nnode;
-}
- 
-void *dupwhile(void *i)
-{
-struct whilenode *nnode,*node = i;
- 
-	if (!i)
-		return NULL;
-	nnode = alloc(sizeof(struct whilenode));
-	nnode->cond = node->cond;
-	nnode->cont = duplist(node->cont);
-	nnode->loop = duplist(node->loop);
-	return nnode;
-}
-
-void *duprepeat(void *i)
-{
-struct repeatnode *nnode,*node = i;
-
-	if (!i)
-		return NULL;
-	nnode = alloc(sizeof(struct repeatnode));
-	nnode->count = node->count;
-	nnode->list = duplist(node->list);
-	return nnode;
-}	
-
-table duptable(table tab,void *(*func)(void *))
-{
-table ret;
-Node node;
-
-	ret = newtable();
-	for (node = tab->first; node; node = node->next)
-		addnode(ret,func(node->dat));
-	return ret;
-}
End of loop.c
echo loop.pro 1>&2
sed 's/^-//' >loop.pro <<'End of loop.pro'
-int parfor(comm comm,int isfor);
-int parcase(comm comm);
-char *getcasepat(void);
-int parif(comm comm);
-int parwhile(comm comm,int cond);
-int parrepeat(comm comm);
-void execfor(comm comm);
-void execselect(comm comm);
-void execwhile(comm comm);
-void execrepeat(comm comm);
-void execif(comm comm);
-void execcase(comm comm);
-list duplist(list xlist);
-void freelist(list xlist);
-list2 duplist2(list2 x);
-void freelist2(list2 x);
-pline duppline(pline xpline);
-void freepline(pline x);
-comm dupcomm(comm xcomm);
-void freecmd(comm x);
-void *dupstr(void *str);
-void *dupfnode(void *i);
-void *dupfor(void *i);
-void *dupcase(void *i);
-void *dupif(void *i);
-void *dupwhile(void *i);
-void *duprepeat(void *i);
-table duptable(table tab,void *(*func)(void *));
End of loop.pro
echo math.c 1>&2
sed 's/^-//' >math.c <<'End of math.c'
-/*
-
-	math.c - evaluating arithmetic expressions
-
-	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 <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <math.h>
-#include <assert.h>
-
-extern int errflag;
-extern char *setiparm(char *,long,int);
-extern long getiparm(char *);
-extern void zerr(char *,...);
-extern char *strdup(char *);
-
-char *ptr;
-
-typedef int LV;
-
-long yyval;
-LV yylval;
-
-/* nonzero means we are not evaluating, just parsing */
-
-int noeval = 0;
-
-/* != 0 means recognize unary plus, minus, etc.
-	The parser was originally written in lex, hence the name. */
-
-int initial = 1;
-
-void mathparse(int);
-
-/* LR = left-to-right associativity
-	RL = right-to-left associativity
-	BOO = short-circuiting boolean */
-
-enum xtyp { LR,RL,BOO };
-
-enum xtok {
-INPAR, OUTPAR, NOT, COMP, POSTPLUS,
-POSTMINUS, UPLUS, UMINUS, AND, XOR,
-OR, MUL, DIV, MOD, PLUS,
-MINUS, SHLEFT, SHRIGHT, LES, LEQ,
-GRE, GEQ, DEQ, NEQ, DAND,
-DOR, DXOR, QUEST, COLON, EQ,
-PLUSEQ, MINUSEQ, MULEQ, DIVEQ, MODEQ,
-ANDEQ, XOREQ, OREQ, SHLEFTEQ, SHRIGHTEQ,
-DANDEQ, DOREQ, DXOREQ, COMMA, EOI,
-PREPLUS, PREMINUS, NUM, ID, TOKCOUNT
-};
-
-/* precedences */
-
-int prec[TOKCOUNT] = {
-1,200,2,2,2,
-2,2,2,3,4,
-5,6,6,6,7,
-7,8,8,9,9,
-9,9,10,10,11,
-12,12,13,13,14,
-14,14,14,14,14,
-14,14,14,14,14,
-14,14,14,15,200,
-2,2,0,0,
-};
-
-#define TOPPREC 15
-
-int type[TOKCOUNT] = {
-LR,LR,RL,RL,RL,
-RL,RL,RL,LR,LR,
-LR,LR,LR,LR,LR,
-LR,LR,LR,LR,LR,
-LR,LR,LR,LR,BOO,
-BOO,LR,RL,RL,RL,
-RL,RL,RL,RL,RL,
-RL,RL,RL,RL,RL,
-BOO,BOO,RL,RL,RL,
-RL,RL,LR,LR,
-};
-
-#define LVCOUNT 32
-
-/* table of lvalues (variables) */
-
-int lvc;
-char *lvals[LVCOUNT];
-
-int yylex(void)
-{
-	for(;;)
-		switch (*ptr++)
-			{
-			case '+':
-				if (*ptr == '+' && (initial || !isalnum(*ptr)))
-					{
-					ptr++;
-					return (initial) ? PREPLUS : POSTPLUS;
-					}
-				if (*ptr == '=') { initial = 1; ptr++; return PLUSEQ; }
-				return (initial) ? UPLUS : PLUS;
-			case '-':
-				if (*ptr == '-' && (initial || !isalnum(*ptr)))
-					{
-					ptr++;
-					return (initial) ? PREMINUS : POSTMINUS;
-					}
-				if (*ptr == '=') { initial = 1; ptr++; return MINUSEQ; }
-				return (initial) ? UMINUS : MINUS;
-			case '(': initial = 1; return INPAR;
-			case ')': return OUTPAR;
-			case '!': if (*ptr == '=')
-						{ initial = 1; ptr++; return NEQ; }
-						return NOT;
-			case '~': return COMP;
-			case '&': initial = 1;
-				if (*ptr == '&') { if (*++ptr == '=')
-				{ ptr++; return DANDEQ; } return DAND; }
-				else if (*ptr == '=') { ptr++; return ANDEQ; } return AND;
-			case '|': initial = 1;
-				if (*ptr == '|') { if (*++ptr == '=')
-				{ ptr++; return DOREQ; } return DOR; }
-				else if (*ptr == '=') { ptr++; return OREQ; } return OR;
-			case '^': initial = 1;
-				if (*ptr == '^') { if (*++ptr == '=')
-				{ ptr++; return DXOREQ; } return DXOR; }
-				else if (*ptr == '=') { ptr++; return XOREQ; } return XOR;
-			case '*': initial = 1;
-				if (*ptr == '=') { ptr++; return MULEQ; } return MUL;
-			case '/': initial = 1;
-				if (*ptr == '=') { ptr++; return DIVEQ; } return DIV;
-			case '%': initial = 1;
-				if (*ptr == '=') { ptr++; return MODEQ; } return MOD;
-			case '<': initial = 1; if (*ptr == '<')
-				{ if (*++ptr == '=') { ptr++; return SHLEFTEQ; } return SHLEFT; }
-				else if (*ptr == '=') { ptr++; return LEQ; } return LES;
-			case '>': initial = 1; if (*ptr == '>')
-				{ if (*++ptr == '=') { ptr++; return SHRIGHTEQ; } return SHRIGHT; }
-				else if (*ptr == '=') { ptr++; return GEQ; } return GRE;
-			case '=': initial = 1; if (*ptr == '=') { ptr++; return DEQ; }
-				return EQ;
-			case '?': initial = 1; return QUEST;
-			case ':': initial = 1; return COLON;
-			case ',': initial = 1; return COMMA;
-			case '\0': initial = 1; ptr--; return EOI;
-			case '[': initial = 0;
-				{ int base = strtol(ptr,&ptr,10);
-					yyval = strtol(ptr+1,&ptr,base); return NUM; }
-			case ' ': case '\t':
-				break;
-			default:
-				if (isdigit(*--ptr))
-					{ initial = 0; yyval = strtol(ptr,&ptr,10); return NUM; }
-				if (isalpha(*ptr) || *ptr == '$')
-					{
-					char *p,q;
-
-					if (*ptr == '$')
-						ptr++;
-					p = ptr;
-					if (lvc == LVCOUNT)
-						{
-						zerr("too many identifiers in expression");
-						errflag = 1;
-						return EOI;
-						}
-					initial = 0;
-					while(isalpha(*++ptr));
-					q = *ptr;
-					*ptr = '\0';
-					lvals[yylval = lvc++] = strdup(p);
-					*ptr = q;
-					return ID;
-					}
-				zerr("illegal character: %c",*ptr);
-				errflag = 1;
-				return EOI;
-			}
-}
-
-/* the value stack */
-
-#define STACKSZ 1000
-int tok;			/* last token */
-int sp = -1;	/* stack pointer */
-struct value {
-	LV lval;
-	long val;
-	} stack[STACKSZ];
-
-void push(long val,LV lval)
-{
-	sp++;
-	stack[sp].val = val;
-	stack[sp].lval = lval;
-}
-
-long getvar(LV s)
-{
-long t;
-
-	if (!(t = getiparm(lvals[s])))
-		return 0;
-	return t;
-}
-
-long setvar(LV s,long v)
-{
-	if (s == -1)
-		{
-		zerr("lvalue required");
-		errflag = 1;
-		return 0;
-		}
-	if (noeval)
-		return v;
-	setiparm(strdup(lvals[s]),v,0);
-	return v;
-}
-
-int notzero(int a)
-{
-	if (a == 0)
-		{
-		errflag = 1;
-		zerr("division by zero");
-		return 0;
-		}
-	return 1;
-}
-
-#define pop2() { b = stack[sp--].val; a = stack[sp--].val; }
-#define pop3() {c=stack[sp--].val;b=stack[sp--].val;a=stack[sp--].val;}
-#define nolval() {stack[sp].lval=-1;}
-#define pushv(X) { push(X,-1); }
-#define pop2lv() { pop2() lv = stack[sp+1].lval; }
-#define set(X) { push(setvar(lv,X),lv); }
-
-void op(int what)
-{
-long a,b,c;
-LV lv;
-
-	switch(what) {
-		case NOT: stack[sp].val = !stack[sp].val; nolval(); break;
-		case COMP: stack[sp].val = ~stack[sp].val; nolval(); break;
-		case POSTPLUS: (void) setvar(stack[sp].lval,stack[sp].val+1); break;
-		case POSTMINUS: (void) setvar(stack[sp].lval,stack[sp].val-1); break;
-		case UPLUS: nolval(); break;
-		case UMINUS: stack[sp].val = -stack[sp].val; nolval(); break;
-		case AND: pop2(); pushv(a&b); break;
-		case XOR: pop2(); pushv(a^b); break;
-		case OR: pop2(); pushv(a|b); break;
-		case MUL: pop2(); pushv(a*b); break;
-		case DIV: pop2(); if (notzero(b)) pushv(a/b); break;
-		case MOD: pop2(); if (notzero(b)) pushv(a%b); break;
-		case PLUS: pop2(); pushv(a+b); break;
-		case MINUS: pop2(); pushv(a-b); break;
-		case SHLEFT: pop2(); pushv(a<<b); break;
-		case SHRIGHT: pop2(); pushv(a>>b); break;
-		case LES: pop2(); pushv(a<b); break;
-		case LEQ: pop2(); pushv(a<=b); break;
-		case GRE: pop2(); pushv(a>b); break;
-		case GEQ: pop2(); pushv(a>=b); break;
-		case DEQ: pop2(); pushv(a==b); break;
-		case NEQ: pop2(); pushv(a!=b); break;
-		case DAND: pop2(); pushv(a&&b); break;
-		case DOR: pop2(); pushv(a||b); break;
-		case DXOR: pop2(); pushv(a&&!b||!a&&b); break;
-		case QUEST: pop3(); pushv((a)?b:c); break;
-		case COLON: break;
-		case EQ: pop2lv(); set(b); break;
-		case PLUSEQ: pop2lv(); set(a+b); break;
-		case MINUSEQ: pop2lv(); set(a-b); break;
-		case MULEQ: pop2lv(); set(a*b); break;
-		case DIVEQ: pop2lv(); if (notzero(b)) set(a/b); break;
-		case MODEQ: pop2lv(); if (notzero(b)) set(a%b); break;
-		case ANDEQ: pop2lv(); set(a&b); break;
-		case XOREQ: pop2lv(); set(a^b); break;
-		case OREQ: pop2lv(); set(a|b); break;
-		case SHLEFTEQ: pop2lv(); set(a<<b); break;
-		case SHRIGHTEQ: pop2lv(); set(a>>b); break;
-		case DANDEQ: pop2lv(); set(a&&b); break;
-		case DOREQ: pop2lv(); set(a||b); break;
-		case DXOREQ: pop2lv(); set(a&&!b||!a&&b); break;
-		case COMMA: pop2(); pushv(b); break;
-		case PREPLUS: stack[sp].val = setvar(stack[sp].lval,
-			stack[sp].val+1); break;
-		case PREMINUS: stack[sp].val = setvar(stack[sp].lval,
-			stack[sp].val-1); break;
-		default: fprintf(stderr,"whoops.\n"); exit(1);
-	}
-}
-
-void bop(int tok)
-{
-	switch (tok) {
-		case DAND: case DANDEQ: if (!stack[sp].val) noeval++; break;
-		case DOR: case DOREQ: if (stack[sp].val) noeval++; break;
-		};
-}
-
-long matheval(char *s)
-{
-int t0;
-
-	for (t0 = 0; t0 != LVCOUNT; t0++)
-		lvals[t0] = NULL;
-	lvc = 0;
-	ptr = s;
-	sp = -1;
-	mathparse(TOPPREC);
-	if (!errflag && sp)
-		zerr("arithmetic error: unbalanced stack");
-	for (t0 = 0; t0 != lvc; t0++)
-		free(lvals[t0]);
-	return stack[0].val;
-}
-
-/* operator-precedence parse the string and execute */
-
-void mathparse(int pc)
-{
-	if (errflag)
-		return;
-	tok = yylex();
-	while (prec[tok] <= pc)
-		{
-		if (errflag)
-			return;
-		if (tok == NUM)
-			push(yyval,-1);
-		else if (tok == ID)
-			push(getvar(yylval),yylval);
-		else if (tok == INPAR)
-			{
-			mathparse(TOPPREC);
-			if (tok != OUTPAR)
-				exit(1);
-			}
-		else if (tok == QUEST)
-			{
-			int q = stack[sp].val;
-			if (!q) noeval++;
-			mathparse(prec[QUEST]-1);
-			if (!q) noeval--; else noeval++;
-			mathparse(prec[QUEST]);
-			if (q) noeval--;
-			op(QUEST);
-			continue;
-			}
-		else
-			{
-			int otok = tok,onoeval = noeval;
-
-			if (type[otok] == BOO)
-				bop(otok);
-			mathparse(prec[otok]-(type[otok] != RL));
-			noeval = onoeval;
-			op(otok);
-			continue;
-			}
-		tok = yylex();
-		}
-}
-
End of math.c
echo math.pro 1>&2
sed 's/^-//' >math.pro <<'End of math.pro'
-INPAR, OUTPAR, NOT, COMP, POSTPLUS,;
-POSTMINUS, UPLUS, UMINUS, AND, XOR,;
-OR, MUL, DIV, MOD, PLUS,;
-MINUS, SHLEFT, SHRIGHT, LES, LEQ,;
-GRE, GEQ, DEQ, NEQ, DAND,;
-DOR, DXOR, QUEST, COLON, EQ,;
-PLUSEQ, MINUSEQ, MULEQ, DIVEQ, MODEQ,;
-ANDEQ, XOREQ, OREQ, SHLEFTEQ, SHRIGHTEQ,;
-DANDEQ, DOREQ, DXOREQ, COMMA, EOI,;
-PREPLUS, PREMINUS, NUM, ID, TOKCOUNT;
-LR,LR,RL,RL,RL,;
-RL,RL,RL,LR,LR,;
-LR,LR,LR,LR,LR,;
-LR,LR,LR,LR,LR,;
-LR,LR,LR,LR,BOO,;
-BOO,LR,RL,RL,RL,;
-RL,RL,RL,RL,RL,;
-RL,RL,RL,RL,RL,;
-BOO,BOO,RL,RL,RL,;
-RL,RL,LR,LR,;
-int yylex(void);
-void push(long val,LV lval);
-long getvar(LV s);
-long setvar(LV s,long v);
-int notzero(int a);
-void op(int what);
-void bop(int tok);
-long matheval(char *s);
-void mathparse(int pc);
End of math.pro
echo parse.c 1>&2
sed 's/^-//' >parse.c <<'End of parse.c'
-/*
-
-	parse.c - parsing
-
-	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"
-
-/* parse a list, but return : instead of NULL */
-
-list parlist(int nest)
-{
-list l1;
-list2 l2;
-pline p;
-comm c;
-
-	if (l1 = parlist1(nest))
-		return l1;
-	if (errflag)
-		return NULL;
-	c = alloc(sizeof *c);
-	c->cmd = strdup("");
-	c->args = newtable();
-	c->redir = newtable();
-	c->type = SIMPLE;
-	p = alloc(sizeof *p);
-	p->left = c;
-	p->type = END;
-	l2 = alloc(sizeof *l2);
-	l2->left = p;
-	l2->type = END;
-	l1 = alloc(sizeof *l1);
-	l1->left = l2;
-	l1->type = SYNC;
-	return l1;
-}
-
-/* parse a list */
-
-list parlist1(int nest)
-{
-list l1 = (list) alloc(sizeof *l1);
-int isnl;
-
-	incmd = 0;
-	if (peek == EMPTY)
-		matchit();
-	if (nest)
-		while (peek == NEWLIN || peek == SEMI)
-			matchit();
-	if (!(l1->left = parlist2()))
-		{
-		free(l1);
-		return NULL;
-		}
-	l1->type = (peek == AMPER) ? ASYNC : SYNC;
-	if ((isnl = peek == NEWLIN) || peek == SEMI || peek == AMPER)
-		peek = EMPTY;
-	if ((nest || !isnl) && peek == EMPTY)
-		{
-		if (!(l1->right = parlist1(nest)))
-			{
-			if (!errflag)
-				{
-				if (peek == NEWLIN)
-					peek = EMPTY;
-				return l1;
-				}
-			freelist2(l1->left);
-			free(l1);
-			return NULL;
-			}
-		}
-	else
-		l1->right = NULL;
-	return l1;
-}
-
-/* parse a sublist */
-
-list2 parlist2(void)
---cut here---cut here---cut here---

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

---cut here---cut here---cut here---
-{
-list2 l2 = (list2) alloc(sizeof *l2);
-int iter = 0;
-
-	for (;;)
-		{
-		if (peek == BANG)
-			{
-			l2->flags |= PFLAG_NOT;
-			matchit();
-			}
-		else if (peek == TIME)
-			{
-			l2->flags |= PFLAG_TIMED;
-			matchit();
-			}
-		else if (peek == COPROC)
-			{
-			l2->flags |= PFLAG_COPROC;
-			matchit();
-			}
-		else
-			break;
-		iter = 1;
-		}
-	if (!(l2->left = parpline()))
-		{
-		free(l2);
-		if (!errflag && iter)
-			{
-			zerr("parse error: pipeline expected");
-			errflag = 1;
-			}
-		return NULL;
-		}
-	if (peek == DAMPER || peek == DBAR)
-		{
-		l2->type = (peek == DAMPER) ? ANDNEXT : ORNEXT;
-		matchit();
-		while (peek == NEWLIN)
-			matchit();
-		if (!(l2->right = parlist2()))
-			{
-			if (!errflag)
-				{
-				zerr("invalid null command");
-				errflag = 1;
-				}
-			freepline(l2->left);
-			free(l2);
-			return NULL;
-			}
-		}
-	else
-		{
-		l2->type = END;
-		l2->right = NULL;
-		}
-	return l2;
-}
-
-/* parse a pipeline */
-
-pline parpline(void)
-{
-pline p = (pline) alloc(sizeof *p);
-
-	if (!(p->left = parcmd()))
-		{
-		free(p);
-		return NULL;
-		}
-	if (peek == HERR)
-		{
-		freecmd(p->left);
-		free(p);
-		return NULL;
-		}
-	if (peek == BAR || peek == BARAMP)
-		{
-		if (peek == BARAMP)
-			{
-			struct fnode *f;
-
-			f = alloc(sizeof *f);
-			f->type = MERGEOUT;
-			f->fd1 = 2;
-			f->u.fd2 = 1;
-			addnode(p->left->redir,f);
-			}
-		matchit();
-		while (peek == NEWLIN)
-			matchit();
-		p->type = PIPE;
-		if (!(p->right = parpline()))
-			{
-			if (!errflag)
-				{
-				zerr("invalid null command");
-				errflag = 1;
-				}
-			freecmd(p->left);
-			free(p);
-			return NULL;
-			}
-		}
-	else
-		{
-		p->type = END;
-		p->right = NULL;
-		}
-	return p;
-}
-
-/* parse a command */
-
-comm parcmd(void)
-{
-comm c = (comm) alloc(sizeof *c);
-list l;
-char *str;
-int flag,iter = 0;
-
-	incmd = 0;
-	c->left = NULL;
-	c->cmd = NULL;
-	c->args = newtable();
-	c->redir = newtable();
-	c->type = SIMPLE;
-	c->vars = NULL;
-	if (peek == EOF)
-		return NULL;
-foo:
-	switch (peek)
-		{
-		case HERR:
-			return NULL;
-		case ENVSTRING:
-			if (!c->vars)
-				c->vars = newtable(); /* FIX */
-			for (str = tstr; *str != '='; str++);
-			*str++ = '\0';
-			addnode(c->vars,tstr);
-			addnode(c->vars,strdup(str));
-			matchit();
-			goto foo;
-		case FOR:
-			incmd = 1;
-			matchit();
-			if (parfor(c,1))
-				return NULL;
-			break;
-		case SELECT:
-			incmd = 1;
-			matchit();
-			if (parfor(c,0))
-				return NULL;
-			break;
-		case CASE:
-			incmd = 1;
-			matchit();
-			if (parcase(c))
-				return NULL;
-			break;
-		case IF:
-			matchit();
-			if (parif(c))
-				return NULL;
-			break;
-		case WHILE:
-			matchit();
-			if (parwhile(c,0))
-				return NULL;
-			break;
-		case UNTIL:
-			matchit();
-			if (parwhile(c,1))
-				return NULL;
-			break;
-		case REPEAT:
-			incmd = 1;
-			matchit();
-			if (parrepeat(c))
-				return NULL;
-			break;
-		case INPAR:
-			matchit();
-			c->type = SUBSH;
-			if (!(c->left = parlist(1)))
-				{
-				freecmd(c);
-				return NULL;
-				}
-			if (peek != OUTPAR)
-				{
-				freecmd(c);
-				zerr("parse error: '}' expected");
-				return NULL;
-				}
-			matchit();
-			break;
-		case INBRACE:
-			matchit();
-			c->type = CURSH;
-			if (!(c->left = parlist(1)))
-				{
-				freecmd(c);
-				return NULL;
-				}
-			if (peek != OUTBRACE)
-				{
-				freecmd(c);
-				zerr("parse error: '}' expected");
-				return NULL;
-				}
-			matchit();
-			break;
-		case FUNC:
-			matchit();
-			str = tstr;
-			if (peek != STRING && peek != ENVSTRING)
-				{
-				c->cmd = strdup("function");
-				incmd = 1;
-				if (isredir())
-					goto jump1;
-				else
-					goto jump2;
-				}
-			do	
-				matchit();
-			while (peek == NEWLIN);
-			if (peek != INBRACE)
-				{
-				freecmd(c);
-				zerr("parse error: '{' expected");
-				return NULL;
-				}
-			matchit();
-			flag = peek == OUTBRACE;
-			if (!(l = parlist(1)))
-				{
-				freecmd(c);
-				return NULL;
-				}
-			if (peek != OUTBRACE)
-				{
-				freelist(l);
-				freecmd(c);
-				zerr("parse error: '}' expected");
-				return NULL;
-				}
-			matchit();
-			settrap(str,flag);
-			addhnode(str,l,shfunchtab,freeshfunc);
-			c->cmd = strdup("");
-			c->type = SIMPLE;
-			break;
-		case EXEC:
-			c->flags |= CFLAG_EXEC;
-			matchit();
-			iter = 1;
-			goto foo;
-		case COMMAND:
-			c->flags |= CFLAG_COMMAND;
-			matchit();
-			iter = 1;
-			goto foo;
-		default:
-jump1:
-			if (isredir())
-				{
-				if (parredir(c))
-					{
-					freecmd(c);
-					return NULL;
-					}
-				goto foo;
-				}
-			if (!(peek == STRING || peek == ENVSTRING))
-				{
-				if (full(c->redir))
-					{
-					c->cmd = strdup("cat");
-					return c;
-					}
-				if (c->vars)
-					{
-					c->cmd = strdup("");
-					return c;
-					}
-				free(c->args);
-				free(c->redir);
-				free(c);
-				if (iter && !errflag)
-					{
-					errflag = 1;
-					zerr("parse error: command expected");
-					}
-				return NULL;
-				}
-jump2:
-			while (peek == STRING || peek == ENVSTRING || isredir())
-				if (isredir())
-					{
-					if (parredir(c))
-						{
-						freecmd(c);
-						return NULL;
-						}
-					}
-				else
-					{
-					if (tstr[0] == Inpar && tstr[1] == Outpar && !tstr[2])
-						{
-						free(tstr);
-						incmd = 0;
-						matchit();
-						if (full(c->args))
-							{
-							zerr("illegal function definition");
-							freecmd(c);
-							return NULL;
-							}
-						while (peek == NEWLIN)
-							matchit();
-						if (peek != INBRACE)
-							{
-							freecmd(c);
-							zerr("parse error: '{' expected");
-							return NULL;
-							}
-						matchit();
-						flag = peek == OUTBRACE;
-						if (!(l = parlist(1)))
-							{
-							freecmd(c);
-							return NULL;
-							}
-						if (peek != OUTBRACE)
-							{
-							freelist(l);
-							freecmd(c);
-							zerr("parse error: '}' expected");
-							return NULL;
-							}
-						matchit();
-						settrap(c->cmd,flag);
-						addhnode(c->cmd,l,shfunchtab,freeshfunc);
-						c->cmd = strdup("");
-						c->type = SIMPLE;
-						incmd = 0;
-						return c;
-						}
-					if (peek == ENVSTRING && (!incmd || opts[KEYWORD] == OPT_SET))
-						{
-						if (!c->vars)
-							c->vars = newtable(); /* FIX */
-						for (str = tstr; *str != '='; str++);
-						*str++ = '\0';
-						addnode(c->vars,tstr);
-						addnode(c->vars,strdup(str));
-						}
-					else if (c->cmd)
-						addnode(c->args,tstr);
-					else
-						{
-						c->cmd = tstr;
-						incmd = 1;
-						}
-					matchit();
-					}
-			break;
-		}
-	while (isredir())
-		if (parredir(c))
-			{
-			freecmd(c);
-			return NULL;
-			}
-	incmd = 0;
-	if (peek == HERR)
-		{
-		freecmd(c);
-		return NULL;
-		}
-	return c;
-}
-
-/* != 0 if peek is a redirection operator */
-
-int isredir(void)
-{
-	return (peek >= OUTANG && peek <= DOUTANGAMPBANG);
-}
-
-/* get fd associated with str */
-
-int getfdstr(char *s)
-{
-	if (s[1])
-		return -1;
-	if (isdigit(*s))
-		return *s-'0';
-	if (*s == 'p')
-		return -2;
-	return -1;
-}
-
-int parredir(comm c)
-{
-struct fnode *fn = (struct fnode *) alloc(sizeof *fn);
-int pk = peek,ic = incmd,mrg2 = 0;
-
-	fn->type = peek-OUTANG+WRITE;
-	if (peek == OUTANGAMP)
-		fn->type = MERGEOUT;
-	if (peekfd != -1)
-		fn->fd1 = peekfd;
-	else if (peek <= DOUTANGBANG || peek >= OUTANGAMP)
-		fn->fd1 = 1;
-	else
-		fn->fd1 = 0;
-	incmd = 1;
-	matchit();
-	incmd = ic;
-	if (peek != STRING)
-		{
-		zerr("parse error: filename expected");
-		return 1;
-		}
-	
-	if ((*tstr == Inang || *tstr == Outang) && tstr[1] == Inpar)
-		{
-		if (fn->type == WRITE)
-			fn->type = OUTPIPE;
-		else if (fn->type == READ)
-			fn->type = INPIPE;
-		else
-			{
-			zerr("parse error: bad process redirection");
-			return 1;
-			}
-		fn->u.name = tstr;
-		}
-	else if (fn->type == HEREDOC)
-		fn->u.fd2 = gethere(tstr);
-	else if (pk >= OUTANGAMP && getfdstr(tstr) == -1)
-		{
-		mrg2 = 1;
-		fn->u.name = tstr;
-		fn->type = pk-OUTANGAMP;
-		}
-	else if (pk > OUTANGAMPBANG)
-		{
-		zerr("parse error: filename expected");
-		return 1;
-		}
-	else if (pk == OUTANGAMPBANG)
-		{
-		struct fnode *fe = alloc(sizeof *fe);
-
-		fe->fd1 = fn->fd1;
-		fe->type = CLOSE;
-		addnode(c->redir,fe);
-		fn->u.fd2 = getfdstr(tstr);
-		if (fn->u.fd2 == -2)
-			fn->u.fd2 = spout;
-		fn->type = MERGEOUT;
-		}
-	else if (fn->type == MERGE || fn->type == MERGEOUT)
-		{
-		if (*tstr == '-')
-			fn->type = CLOSE;
-		else
-			{
-			fn->u.fd2 = getfdstr(tstr);
-			if (fn->u.fd2 == -2)
-				fn->u.fd2 = (pk == OUTANGAMP) ? spout : spin;
-			}
-		}
-	else
-		fn->u.name = tstr;
-	addnode(c->redir,fn);
-	if (mrg2)
-		{
-		struct fnode *fe = alloc(sizeof *fe);
-
-		fe->fd1 = 2;
-		fe->u.fd2 = fn->fd1;
-		fe->type = MERGEOUT;
-		addnode(c->redir,fe);
-		}
-	matchit();
-	return 0;
-}
-
End of parse.c
echo parse.pro 1>&2
sed 's/^-//' >parse.pro <<'End of parse.pro'
-list parlist(int nest);
-list parlist1(int nest);
-list2 parlist2(void);
-pline parpline(void);
-comm parcmd(void);
-int isredir(void);
-int getfdstr(char *s);
-int parredir(comm c);
End of parse.pro
echo subst.c 1>&2
sed 's/^-//' >subst.c <<'End of subst.c'
-/*
-
-	subst.c - various substitution
-
-	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"
-#include <pwd.h>
-#define MAXPATHLEN 1024
-
-#define magicerr() { if (magic) putc('\n',stderr); }
-
-/* do substitutions before fork */
-
-void prefork(table list)
-{
-Node node = list->first;
-
-	while (node)
-		{
-		char *str,*str3;
-		
-		str = str3 = node->dat;
-		if (!magic && str[1] == Inpar && (*str == Inang ||
-				*str == Outang || *str == Equals))
-			{
-			if (*str == Inang)
-				node->dat = getoutproc(str+2);		/* <(...) */
-			else if (*str == Equals)
-				node->dat = getoutputfile(str+2);	/* =(...) */
-			else
-				node->dat = getinproc(str+2);			/* >(...) */
-			free(str);
-			if (!node->dat)
-				{
-				zerr("parse error in process substitution");
-				errflag = 1;
-				return;
-				}
-			}
-		else while (*str)
-			{
-			if (*str == String || *str == Qstring)
-				if (str[1] != Inpar)
-					if (str[1] == '*' || str[1] == Star)
-						parminsall(list,&node,&str,&str3);	/* $* */
-					else if (str[1] == Inbrack)
-						{
-						arithsuber((void **) &str,&str3);	/* $[...] */
-						if (magic)
-							magic = 2;
-						node->dat = str3;
-						}
-					else
-						{
-						parmsuber(str,&str3);		/* $foo */
-						node->dat = str = str3;
-						if (errflag)
-							return;
-						continue;
-						}
-			str++;
-			if (errflag)
-				return;
-			}
-		node = node->next;
-		}
-}
-
-void postfork(table list,int globstat)
-{
-Node node = list->first;
-int glb = 1;
-
-	if (isset(NOGLOBOPT) || globstat != GLOB)
-		glb = 0;
-	while (node)
-		{
-		char *str,*str3;
-		
-		str = str3 = node->dat;
-		while (*str)
-			{
-			if (((*str == String || *str == Qstring) && str[1] == Inpar) ||
-					*str == Tick || *str == Qtick)
-				comminsall(list,&node,&str,&str3);	/* `...`,$(...) */
-			str++;
-			if (errflag)
-				return;
-			}
-		
-		/* now we remove the Nulargs tokens if this is not a null
-			arguments.  The lexical analyzer throws these in so that
-			zsh will not look at this:
-
-			$PA"TH"
-
-			and expand it to $PATH.  But after parameter substitution
-			these are only a nuisance, so we remove them. */
-
-		if (*(char *) node->dat)
-			remnulargs(node->dat);
-		
-		if (unset(IGNOREBRACES))
-			while (hasbraces(node->dat))
-				xpandbraces(list,&node);
-		filesub(&node->dat);
-		if (errflag)
-			return;
-		if (glb)
-			{
-			if (haswilds(node->dat))
-				glob(list,&node);
-			if (errflag)
-				return;
-			}
-		else if (globstat == MOSTGLOB && *(char *) node->dat != '-')
-			glb = 1;
-		node = node->next;
-		}
-}
-
-/* strdup, but returns "Nularg" if this is a null string */
-
-void *nstrdup(void *s)
-{
-char *t = s,u[] = {Nularg,'\0'};
-
-	if (!*t)
-		return strdup(u);
-	return strdup(t);
-}
-
-/* $* */
-
-void parminsall(table l,Node *nn,char **aptr,char **bptr)
-{
-char *str3 = *aptr,*str = *bptr;
-Node n = *nn,where = n->last;
-table pl;
-
-	if (magic)
-		magic = 2;
-	*str3 = '\0';
-	str3 += 2;
-	remnode(l,n);
-	pl = duptable(pparms,nstrdup);
-	free(getnode(pl));
-	if (pl->first)	/* if $# > 1 */
-		{
-		char *ptr;
-		Node tmp;
-
-		ptr = pl->first->dat;
-		pl->first->dat = dyncat(str,ptr);
-		free(ptr);
-		ptr = pl->last->dat;
-		*bptr = pl->last->dat = dyncat(ptr,str3);
-		*aptr = *bptr+strlen(str)+strlen(ptr)-1;
-		free(ptr);
-		tmp = where->next;
-		where->next = pl->first;
-		pl->last->next = tmp;
-		pl->first->last = where;
-		if (tmp)
-			tmp->last = pl->last;
-		else
-			l->last = pl->last;
-		*nn = pl->last;
-		}
-	else	/* just remove the $* */
-		{
-		insnode(l,where,*bptr = dyncat(str,str3));
-		*nn = where->next;
-		*aptr = *bptr+strlen(str)-1;
-		}
-}
-
-char *dynread(char stop)
-{
-int bsiz = 256,ct = 0,c;
-char *buf = zalloc(bsiz),*ptr;
- 
-	ptr = buf;
-	while ((c = hgetc()) != stop)
-		{
-		*ptr++ = c;
-		if (++ct == bsiz)
-			{
-			buf = realloc(buf,bsiz *= 2);
-			ptr = buf+ct;
-			}
-		}
-	*ptr = 0;
-	return buf;
-}
-
-int filesub(void **namptr)
-{
-char *str = *namptr,*cnam;
-
-	if (*str == Tilde && str[1] != '=')
-		{
-		if (str[1] == '+')
-			{
-			char *foo = strdup(cwd),*t = str;	/* ~+ */
-
-			str+=2;
-			modify((void **) &foo,&str);
-			*namptr = dyncat(cwd,str);
-			free(foo);
-			free(t);
-			return 1;
-			}
-		else if (str[1] == '-')			/* ~- */
-			{
-			char *foo,*t = str;
-
-			if (cnam = getparm("OLDPWD"))
-				foo = cnam;
-			else
-				foo = cwd;
-			str += 2;
-			foo = strdup(foo);
-			modify((void **) &foo,&str);
-			*namptr = dyncat(foo,str);
-			free(t);
-			free(foo);
-			return 1;
-			}
-		if (isalpha(str[1]))		/* ~foo */
-			{
-			char *ptr,*home;
- 
-			for (ptr = ++str; *ptr && !istok(*ptr) && (isalnum(*ptr) || *ptr == '-'); ptr++)
-				if (*ptr == '-')
-					*ptr = '-';
-			if (!(home = gethome(str,ptr-str)))
-				{
-				if (magic)
-					home = completehome(str,ptr-str);
-				if (!home)
-					{
-					magicerr();
-					zerr("user not found: %l",ptr-str,str);
-					errflag = 1;
-					return 0;
-					}
-				}
-			modify((void **) &home,&ptr);
-			*namptr = dyncat(home,ptr);
-			free(home);
-			free(str-1);
-			return 1;
-			}
-		else if (str[1] == '/')	/* ~/foo */
-			{
-			*namptr = dyncat(home,str+1);
-			free(str);
-			return 1;
-			}
-		else if (!str[1])		/* ~ by itself */
-			{
-			free(str);
-			*namptr = strdup(home);
-			return 1;
-			}
-		}
-	if (*str == Equals && !istok(str[1]) && (isalnum(str[1]) || str[1] == '-'))
-		{
-		char *ptr,*s,*ds;
-		int val;
-		
-		untokenize(str);
-		if (isalpha(str[1]))		/* =foo */
-			{
-			struct chnode *chn;
-			struct anode *t;
-			char sav,*pp;
- 
-			for (pp = str+1; *pp && *pp != ':'; pp++);
-			sav = *pp;
-			*pp = '\0';
-			if ((t = gethnode(str+1,alhtab)) && t->cmd)
-				if (t->cmd >= 0)
-					cnam = strdup(t->text);
-				else
-					{
-					magicerr();
-					zerr("%s: shell reserved word",str+1);
-					errflag = 1;
-					return 0;
-					}
-		 	else if (chn = gethnode(str+1,chtab))
-				if (chn->type != BUILTIN)
-					cnam = strdup(chn->u.nam);
-				else
-					{
-					magicerr();
-					zerr("%s: shell built-in command",str+1);
-					errflag = 1;
-					return 0;
-					}
-			else if (!(cnam = findcmd(str+1)))
-				{
-				magicerr();
-				zerr("%s not found",str+1);
-				errflag = 1;
-				return 0;
-				}
-			*namptr = cnam;
-			if ((*pp = sav) == ':')
-				{
-				modify(namptr,&pp);
-				s = *namptr;
-				*namptr = dyncat(*namptr,pp);
-				free(s);
-				}
-			free(str);
-			return 1;
-			}
-		if (str[1] == '-') 	/* =- */
-			{
-			val = -1;
-			ptr = str+2;
-			}
-		else
-			val = strtol(str+1,&ptr,10);	/* =# */
-		ds = dstackent(val);
-		if (!ds)
-			return 1;
-		s = strdup(ds);
-		modify((void **) &s,&ptr);
-		*namptr = dyncat(s,ptr);
-		free(s);
-		free(str);
-		return 1;
-		}
-	return 0;
-}
-
-/* get a user's directory */
-
-char *gethome(char *user,int len)
-{
-char sav,*str;
-struct passwd *pw;
- 
-	sav = user[len];
-	user[len] = '\0';
-	if (!(pw = getpwnam(user)))
-		{
-		user[len] = sav;
-		return NULL;
-		}
-	str = xsymlink(pw->pw_dir);
-	user[len] = sav;
-	return str;
-}
-
-/* complete a user and try to get his home directory */
-
-char *completehome(char *user,int len)
-{
-FILE *in;
-char buf[MAXPATHLEN],*str;
-
-	sprintf(buf,"%s/.zfriends",getparm("HOME"));
-	if (!(in = fopen(buf,"r")))
-		return NULL;
-	while (fgetline(buf,MAXPATHLEN,in))
-		if (!strncmp(user,buf,len))
-			if (str = gethome(buf,strlen(buf)))
-				{
-				fclose(in);
-				return str;
-				}
-	fclose(in);
-	return NULL;
-}
-
-/* get the value of the parameter specified by the first len
-	characters of s */
-
-char *getsparmval(char *s,int len)
-{
-char sav = s[len];
-char *val;
-char buf[50];
-int t0;
-
-	if (len == 1 && (istok(*s) || !isalnum(*s)))
-		switch(*s)
-			{
-			case Pound:
-			case '#':
-				sprintf(buf,"%d",ppcount());
-				return strdup(buf);
-			case '-':
-				for (val = buf, t0 = ' '; t0 <= 'z'; t0++)
-					if (opts[t0] == OPT_SET)
-						*val++ = t0;
-				*val = '\0';
-				return strdup(buf);
-			case '?':
-			case Quest:
-				sprintf(buf,"%d",lastval);
-				return strdup(buf);
-			case '$':
-			case String:
-				sprintf(buf,"%d",procnum);
-				return strdup(buf);
-			case '!':
-				sprintf(buf,"%d",proclast);
-				return strdup(buf);
-			default:
-				return NULL;
-			}
-	s[len] = '\0';
-	if (isdigit(*s))
-		{
-		int num;
-		Node node;
-		
-		num = atoi(s);
-		s[len] = sav;
-		for (node = pparms->first; node && num; num--,node = node->next);
-		return (node) ? strdup(node->dat) : NULL;
-		}
-	val = getparm(s);
-	s[len] = sav;
-	return (val) ? strdup(val) : NULL;
-}
-
-/* set the parameter associated with the first len characters of s
-	to v. */
-
-void setparml(char *s,int len,char *v)
-{
-char c;
- 
-	c = s[len];
-	s[len] = 0;
-	if (isdigit(*s))
-		{
-		int num;
-		Node node;
-		
-		num = atoi(s);
-		for (node = pparms->first; node && num; num--,node = node->next);
-		if (node)
-			{
-			free(node->dat);
-			node->dat = v;
-			}
-		else
-			{
-			while (num--)
-				addnode(pparms,strdup(""));
-			addnode(pparms,v);
-			}
-		}
-	else
-		setparm(strdup(s),v,0,0);
-	s[len] = c;
-}
-
-/* `...`, $(...) */
-
-void comminsall(table l,Node *nn,char **aptr,char **bptr)
-{
-char *str3 = *aptr,*str = *bptr,*str2;
-Node n = *nn,where = n->last;
-table pl;
-int s31 = (*str3 == Qtick || *str3 == Qstring);
-
-	if (magic) magic = 2;
-	if (*str3 == Tick || *str3 == Qtick)
-		{
-		*str3 = '\0';
-		for (str2 = ++str3; *str3 != Tick && *str3 != Qtick; str3++);
-		*str3++ = '\0';
-		}
-	else
-		{
-		*str3++ = '\0';
-		for (str2 = ++str3; *str3 != Outpar; str3++);
-		*str3++ = '\0';
-		}
-	remnode(l,n);
-	if (!(pl = getoutput(str2,s31)))
-		{
-		magicerr();
-		zerr("parse error in command substitution");
-		errflag = 1;
-		return;
-		}
-	if (pl->first)
-		{
-		char *ptr;
-		Node tmp;
-
-		ptr = pl->first->dat;
-		pl->first->dat = dyncat(str,ptr);
-		free(ptr);
-		ptr = pl->last->dat;
-		*bptr = pl->last->dat = dyncat(ptr,str3);
-		*aptr = *bptr+strlen(str)+strlen(ptr)-1;
-		free(ptr);
-		tmp = where->next;
-		where->next = pl->first;
-		pl->last->next = tmp;
-		pl->first->last = where;
-		if (tmp)
-			tmp->last = pl->last;
-		else
-			l->last = pl->last;
-		/* free(tmp); */
-		*nn = pl->last;
-		free(pl);
-		}
-	else
-		{
-		insnode(l,where,*bptr = dyncat(str,str3));
-		*nn = where->next;
-		*aptr = *bptr+strlen(str)-1;
-		}
-}
-
-/* do simple parameter substitution */
-
-/*
-	consider an argument like this:
-
-	abcde${fgh:-ijk}lmnop
-
-	aptr will point to the $.
-	*bptr,ostr will point to the a.
-	t will point to the f.
-	u will point to the i.
-	s will point to the l (eventually).
-*/
-
-void parmsuber(char *aptr,char **bptr)
-{
-char *s = aptr,*t,*u,*val,*ostr = *bptr;
-int brs;			/* != 0 means ${...}, otherwise $... */
-int vlen;		/* the length of the name of the parameter */
-int colf;		/* != 0 means we found a colon after the name */
-int doub = 0;	/* != 0 means we have %%, not %, or ##, not # */
-
-	/* first, remove the $ so *bptr is pointing to a null-terminated
-		string containing the stuff before the $.  Then check for braces,
-		and get the parameter name and value, if any. */
-
-	*s++ = '\0';
-	if (brs = (*s == '{' || *s == Inbrace))
-		s++;
-	t = s;
-	if (istok(*s) || !isalnum(*s))
-		{
-		val = getsparmval(t,vlen = 1);
-		if (!val)
-			{
-			*(char *) aptr = '$';
-			if (brs)
-				s[-1] = '{';
-			return;
-			}
-		s++;
-		}
-	else
-		{
-		while (!istok(*s) && (isalnum(*s) || *s == '_'))
-			s++;
-		val = getsparmval(t,vlen = s-t);
-		}
-
-	/* val can still be NULL at this point. */
-
-	if (colf = *s == ':')
-		s++;
-	
-	/* check for ${..?...} or ${..=..} or one of those.  Only works
-		if the name is in braces. */
-
-	if (brs && (*s == '-' || *s == '=' || *s == '?' || *s == '+' || *s == '#' ||
-			*s == '%' || *s == Quest || *s == Pound))
-		{
-		if (*s == s[1])
-			{
-			s++;
-			doub = 1;
-			}
-		u = ++s;
-		if (brs)
-			while (*s != '}' && *s != Outbrace)
-				s++;
-		else
-			{
-			while (*s++);
-			s--;
-			}
-		*s = '\0';
-		switch (u[-1])
-			{
-			case '-':
-				if (!val || (colf && !*val))
-					val = strdup(u);
-				break;
-			case '=':
-				if (!val || (colf && !*val))
-					setparml(t,vlen,val = strdup(u));
-				break;
-			case '?':
-			case Quest:
-				if (!val || (colf && !*val))
-					{
-					magicerr();
-					zerr("%s",(*u) ? u : "parameter not set");
-					if (!interact)
-						exit(1);
-					else
-						errflag = 1;
-					return;
-					}
-				break;
-			case '+':
-				if (!val || (colf && !*val))
-					val = strdup("");
-				else
-					val = strdup(u);
-				break;
-			case '#':
-			case Pound:
-				if (!val)
-					val = strdup("");
-				getmatch(&val,u,doub);
-				break;
-			case '%':
-				if (!val)
-					val = strdup("");
-				getmatch(&val,u,doub+2);
-				break;
-			}
-		}
-	else		/* no ${...=...} or anything, but possible modifiers. */
-		{
-		if (!val)
-			{
-			if (isset(NOUNSET))
-				{
-				zerr("parameter not set: %l",vlen,t);
-				errflag = 1;
-				return;
-				}
-			val = strdup("");
-			}
-		if (colf)
-			{
-			s--;
-			modify((void **) &val,&s);		/* do modifiers */
-			}
-		if (brs)
-			{
-			if (*s != '}' && *s != Outbrace)
-				{
-				zerr("closing brace expected");
-				errflag = 1;
-				return;
-				}
-			s++;
-			}
-		}
-	if (errflag)
-		{
-		free(ostr);
-		return;
-		}
-	*bptr = zalloc((char *) aptr-(*bptr)+strlen(val)+strlen(s)+1);
-	strcpy(*bptr,ostr);
-	strcat(*bptr,val);
-	strcat(*bptr,s);
-	free(ostr);
-	if (magic)
-		magic = 2;
-}
-
-/* arithmetic substitution */
-
-void arithsuber(void **aptr,char **bptr)
-{
-char *s = *aptr,*t,buf[16];
-long v;
-
-	*s = '\0';
-	for (; *s != Outbrack; s++);
-	*s++ = '\0';
-	v = matheval(*aptr+2);
-	sprintf(buf,"%ld",v);
-	t = zalloc(strlen(*bptr)+strlen(buf)+strlen(s)+1);
-	strcpy(t,*bptr);
-	strcat(t,buf);
-	strcat(t,s);
-	free(*bptr);
-	*bptr = t;
-}
-
-void modify(void **str,char **ptr)
-{
-char *ptr1,*ptr2,*ptr3,del,*lptr;
-int gbal;
- 
-	while (**ptr == ':')
-		{
-		lptr = *ptr;
-		(*ptr)++;
-		gbal = 0;
-here:
-		switch(*(*ptr)++)
-			{
-			case 'h':
-				while (remtpath(str) && gbal);
-				break;
-			case 'r':
-				while (remtext(str) && gbal);
-				break;
-			case 'e':
-				while (rembutext(str) && gbal);
-				break;
-			case 't':
-				while (remlpaths(str) && gbal);
-				break;
-			case 's':
-				if (last)
-					free(last);
-				if (rast)
-					free(rast);
-				ptr1 = *ptr;
-				del = *ptr1++;
-				for (ptr2 = ptr1; *ptr2 != del && *ptr2; ptr2++);
-				if (!*ptr2)
-					{
-					magicerr();
-					zerr("bad subtitution");
-					errflag = 1;
-					return;
-					}
-				*ptr2++ = '\0';
-				for (ptr3 = ptr2; *ptr3 != del && *ptr3; ptr3++);
-				if (*ptr3)
-					*ptr3++ = '\0';
-				last = strdup(ptr1);
-				rast = strdup(ptr2);
-				*ptr = ptr3;
-			case '&':
-				if (last && rast)
-					subststr(str,last,rast,gbal);
-				break;
-			case 'g':
-				gbal = 1;
-				goto here;
-			default:
-				*ptr = lptr;
-				return;
-			}
-		}
-}
-
-/* get a directory stack entry */
-
-char *dstackent(int val)
-{
-Node node;
- 
-	if ((val < 0 && !dirstack->first) || !val--)
-		return cwd;
-	if (val < 0)
-		node = dirstack->last;
-	else
-		for (node = dirstack->first; node && val; val--,node = node->next);
-	if (!node)
-		{
-		magicerr();
-		zerr("not enough dir stack entries.");
-		errflag = 1;
-		return NULL;
-		}
-	return node->dat;
-}
- 
-void execshfunc(comm comm)
-{
-table tab,oldlocals;
-Node n;
-char *s;
-
-	tab = pparms;
-	oldlocals = locallist;
-	locallist = newtable();
-	for (n = tab->first; n; n = n->next);
-	pparms = comm->args;
-	runlist(comm->left);
-	retflag = 0;
-	comm->left = NULL;
-	pparms = tab;
-	while (s = getnode(locallist))
-		{
-		void *z = remhnode(s,parmhtab);
-		if (z)
-			freepm(z);
-		}
-	free(locallist);
-	locallist = oldlocals;
-}
-
-/* make an alias hash table node */
-
-struct anode *mkanode(char *txt,int cmflag)
-{
-struct anode *ptr = (void *) alloc(sizeof(struct anode));
-
-	ptr->text  = txt;
-	ptr->cmd = cmflag;
-	ptr->inuse = 0;
-	return ptr;
-}
-
-/* perform TAB substitution */
-
-char *docompsubs(char *str,int *i)
-{
-table fake,curt = curtab;
-char *s,*t;
-int ct = 0;
-
-	for (s = str; *s; s++)
-		for (t = tokens; *t; t++)
-			if (*s == *t)
-				{
-				*s = (t-tokens)+Pound;
-				break;
-				}
-	curtab = NULL;
-	magic = 1;
-	fake = newtable();
-	addnode(fake,str);
-	prefork(fake);
-	if (!errflag)
-		postfork(fake,GLOB);
-	if (fake->first && fake->first->next)
-		ct = 1;
-	t = s = buildline(fake);
-	free(fake);
-	rl_prep_terminal();
-	if (errflag)
-		{
-		rl_on_new_line();
-		rl_redisplay();
-		errflag = 0;
-		magic = 0;
-		curtab = curt;
-		*i = 0;
-		return NULL;
-		}
-	*i = (magic == 2) + ct;
-	magic = 0;
-	curtab = curt;
-	untokenize(s);
-	return s;
-}
-
-/* perform substitution on the command name */
-
-void docmdsubs(char **str)
-{
-table fake;
-char *s = strdup(*str);
-
-	fake = newtable();
-	addnode(fake,*str);
-	prefork(fake);
-	if (!errflag) postfork(fake,GLOB);
-	if (errflag)
-		{
-		free(fake);
-		free(s);
-		return;
-		}
-	if (fake->first && fake->first->next)
-		{
-		zerr("%s: ambiguous",s);
-		errflag = 1;
-		free(fake);
-		free(s);
-		return;
-		}
-	*str = getnode(fake);
-	free(s);
-	free(fake);
-}
-
-/* perform substitution on the variables */
-
-void dovarsubs(char **str)
-{
-table fake;
-char *s;
-
-	fake = newtable();
-	addnode(fake,*str);
-	prefork(fake);
-	if (!errflag) postfork(fake,GLOB);
-	if (errflag)
-		return;
-	s = buildline(fake);
-	untokenize(s);
-	*str = s;
-	free(fake);
-}
-
End of subst.c
echo subst.pro 1>&2
sed 's/^-//' >subst.pro <<'End of subst.pro'
-void prefork(table list);
-void postfork(table list,int globstat);
-void *nstrdup(void *s);
-void parminsall(table l,Node *nn,char **aptr,char **bptr);
-char *dynread(char stop);
-int filesub(void **namptr);
-char *gethome(char *user,int len);
-char *completehome(char *user,int len);
-char *getsparmval(char *s,int len);
-void setparml(char *s,int len,char *v);
-void comminsall(table l,Node *nn,char **aptr,char **bptr);
-void parmsuber(char *aptr,char **bptr);
-void arithsuber(void **aptr,char **bptr);
-void modify(void **str,char **ptr);
-char *dstackent(int val);
-void execshfunc(comm comm);
-struct anode *mkanode(char *txt,int cmflag);
-char *docompsubs(char *str,int *i);
-void docmdsubs(char **str);
-void dovarsubs(char **str);
End of subst.pro
echo table.c 1>&2
sed 's/^-//' >table.c <<'End of table.c'
-/*
-
-	table.c - linked list and hash table management
-
-	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"
-
-/* get an empty linked list header */
-
-table newtable()
-{
-table list;
- 
-	list = alloc(sizeof(*list));
-	list->first = 0;
-	list->last = (Node) list;
-	return list;
-}
-
-/* get an empty hash table */
-
-htable newhtable(int size)
-{
-htable ret;
- 
-	ret = alloc(sizeof(struct xhtab));
-	ret->hsize = size;
-	ret->nodes = alloc(size*sizeof(struct hnode *));
-	return ret;
-}
- 
-/* Peter Weinberger's hash function */
-
-int hasher(char *s)
-{
-unsigned hash = 0,g;
- 
-	for (; *s; s++)
-		{
-		hash = (hash << 4) + *s;
-		if (g = hash & 0xf0000000)
-			{
-			hash ^= g;
-			hash ^= g >> 24;
-			}
-		}
-	return hash;
-}
-
-/* add a node to a hash table */
-
-void addhnode(char *nam,void *dat,htable ht,void (*freefunc)(void *))
-{
-int hval = hasher(nam) % ht->hsize;
-struct hnode *hp = ht->nodes[hval],*hn;
- 
-	for (; hp; hp = hp->hchain)
-		if (!strcmp(hp->nam,nam))
-			{
-			freefunc(hp->dat);
-			hp->dat = dat;
-			free(nam);
-			return;
-			}
-	hn = (void *) alloc(sizeof(struct hnode));
-	hn->nam = nam;
-	hn->dat = dat;
-	hn->hchain = ht->nodes[hval];
-	ht->nodes[hval] = hn;
-	if (++ht->ct == ht->hsize*4)
-		expandhtab(ht);
-}
-
-/* expand hash tables when they get too many entries */
-
-void expandhtab(htable ht)
-{
-struct hnode *hp,**arr,**ha,*hn;
-int osize = ht->hsize,nsize = osize*8;
-
-	ht->hsize = nsize;
-	arr = ht->nodes;
-	ht->nodes = alloc(nsize*sizeof(struct hnode *));
-	for (ha = arr; osize; osize--,ha++)
-		for (hn = *ha; hn; )
-			{
-			addhnode(hn->nam,hn->dat,ht,NULL);
-			hp = hn->hchain;
-			free(hn);
-			hn = hp;
-			}
-	free(arr);
-}
-
-/* get an entry in a hash table */
-
-void *gethnode(char *nam,htable ht)
-{
-int hval = hasher(nam) % ht->hsize;
-struct hnode *hn = ht->nodes[hval];
- 
-	for (; hn; hn = hn->hchain)
-		if (!strcmp(hn->nam,nam))
-			return hn->dat;
-	return NULL;
-}
- 
-void freehtab(htable ht,void (*freefunc)(void *))
-{
-int val;
-struct hnode *hn,**hptr = &ht->nodes[0],*next;
- 
-	for (val = ht->hsize; val; val--,hptr++)
-		for (hn = *hptr; hn; )
-			{
-			next = hn->hchain;
-			freefunc(hn);
-			hn = next;
-			}
-}
-
-/* remove a hash table entry and return a pointer to it */
-
-void *remhnode(char *nam,htable ht)
-{
-int hval = hasher(nam) % ht->hsize;
-struct hnode *hn = ht->nodes[hval],*hp;
-void *dat;
-
-	if (!hn)
-		return NULL;
-	if (!strcmp(hn->nam,nam))
-		{
-		ht->nodes[hval] = hn->hchain;
-		dat = hn->dat;
-		free(hn->nam);
-		free(hn);
-		ht->ct--;
-		return dat;
-		}
-	for (hp = hn, hn = hn->hchain; hn; hn = (hp = hn)->hchain)
-		if (!strcmp(hn->nam,nam))
-			{
-			hp->hchain = hn->hchain;
-			dat = hn->dat;
-			free(hn->nam);
-			free(hn);
-			ht->ct--;
-			return dat;
-			}
-	return NULL;
-}
- 
-void *zalloc(int l)
-{
-void *z;
- 
-	if (!(z = malloc(l)))
-		{
-		zerr("fatal error: out of memory: restarting");
-		execl(MYSELF,"zsh","-f",(void *) 0);
-		exit(1);
-		}
-	return z;
-}
-
-void *alloc(int l)
-{
-void *z;
- 
-	if (!(z = calloc(l,1)))
-		{
-		zerr("fatal error: out of memory: restarting");
-		execl(MYSELF,"zsh","-f",(void *) 0);
-		exit(1);
-		}
-	return z;
-}
-
-/* add a node to the end of a linked list */
-
-void addnode(table list,void *str)
-{
-	insnode(list,list->last,str);
-}
-
-/* insert a node in a linked list after 'last' */
-
-void insnode(table list,Node last,void *dat)
-{
-Node tmp;
- 
-	tmp = last->next;
-	last->next = alloc(sizeof(*tmp));
-	last->next->last = last;
-	last->next->dat = dat;
-	last->next->next = tmp;
-	if (tmp)
-		tmp->last = last->next;
-	else
-		list->last = last->next;
-}
-
-/* remove a node from a linked list */
-
-void *remnode(table list,Node nd)
-{
-void *dat;
-
-	nd->last->next = nd->next;
-	if (nd->next)
-		nd->next->last = nd->last;
-	else
-		list->last = nd->last;
-	free(nd);
-	dat = nd->dat;
-	return dat;
-}
-
-/* delete a character in a string */
-
-void chuck(char *str)
-{
-	while (str[0] = str[1])
-		str++;
-}
-
-/* get a node in a linked list */
-
-void *getnode(table list)
-{
-void *dat;
-Node node = list->first;
- 
-	if (!node)
-		return NULL;
-	dat = node->dat;
-	list->first = node->next;
-	if (node->next)
-		node->next->last = (Node) list;
-	else
-		list->last = (Node) list;
-	free(node);
-	return dat;
-}
-
-/* != 0 if the linked list has at least one entry */
-
-int full(table list)
-{
-	return list->first != NULL;
-}
- 
-void freetable(table tab,void (*freefunc)(void *))
-{
-Node node = tab->first,next;
- 
-	while (node)
-		{
-		next = node->next;
-		freefunc(node);
-		node = next;
-		}
-	free(tab);
-}
- 
-char *strdup(char *str)
-{
-char *ret = zalloc(strlen(str)+1);
- 
-	strcpy(ret,str);
-	return ret;
-}
-
-#ifndef STRSTR
-const char *strstr(const char *s,const char *t)
-{
-const char *p1,*p2;
- 
-	for (; *s; s++)
-		{
-		for (p1 = s, p2 = t; *p2; p1++,p2++)
-			if (*p1 != *p2)
-				break;
-		if (!*p2)
-			 return (char *) s;
-		}
-	return NULL;
-}
-#endif
-
End of table.c
echo table.pro 1>&2
sed 's/^-//' >table.pro <<'End of table.pro'
-table newtable();
-htable newhtable(int size);
-int hasher(char *s) /* copied from Programming in C++, p14 */;
-void addhnode(char *nam,void *dat,htable ht,void (*freefunc)(void *));
-void expandhtab(htable ht);
-void *gethnode(char *nam,htable ht);
-void freehtab(htable ht,void (*freefunc)(void *));
-void *remhnode(char *nam,htable ht);
-void *zalloc(int l);
-void *alloc(int l);
-void addnode(table list,void *str);
-void insnode(table list,Node last,void *dat);
-void *remnode(table list,Node nd);
-void chuck(char *str);
-void *getnode(table list);
-int full(table list);
-void freetable(table tab,void (*freefunc)(void *));
-char *strdup(char *str);
-/*const char *strstr(const char *s,const char *t); */
End of table.pro
echo test.c 1>&2
sed 's/^-//' >test.c <<'End of test.c'
-/*
-
-	test.c - the test builtin
-
-	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"
-
-#ifndef F_OK
-#define F_OK 00
-#define R_OK 04
-#define W_OK 02
-#define X_OK 01
-#endif
-
-#include "test.pro"
-#include "table.pro"
-
-static char **arg;
-static int efg;
-
-void die(char *str)
-{
-	if (!efg)
-		zerrnam("test",str);
-	efg = 1;
-}
-
-int test(comm comm)
-{
-Node n;
-int t0;
-char **av,**ap;
-
-	for (n = comm->args->first, t0 = 0; n; n = n->next,t0++);
-	ap = av = (char **) zalloc((sizeof(char *))*(t0+1));
-	for (n = comm->args->first; n; n = n->next)
-		*ap++ = n->dat;
-	*ap = NULL;
-	t0 = testmain(av);
-	free(av);
-	return t0;
-}
-
-int testmain(char **argv)
-{
-int ret,isbrack;
-	
-	efg = 0;
-	arg = argv+1;
-	ret = testexpr();
-	if (efg)
-		return 1;
-	isbrack = !strcmp(*argv,"[");
-	if (isbrack)
-		{
-		if (*arg && !strcmp(*arg,"]") && !arg[1])
-			return !ret;
-		}
-	else
-		if (!*arg)
-			return !ret;
-	die("bad test format");
-	return 1;
-}
-
-int testexpr(void)
-{
-int ret = testexpr2(),ret2;
-
-	if (*arg && !strcmp(*arg,"-o"))
-		{
-		arg++;
-		ret2 = testexpr2();
-		if (efg)
-			return 0;
-		ret = ret || ret2;
-		}
-	return ret;
-}
-
-int testexpr2(void)
-{
-int ret = testexpr3(),ret2;
-
-	if (*arg && !strcmp(*arg,"-a"))
-		{
-		arg++;
-		ret2 = testexpr2();
-		if (efg)
-			return 0;
-		ret = ret && ret2;
-		}
-	return ret;
-}
-
-int testexpr3(void)
-{
-	if (*arg && !strcmp(*arg,"!"))
-		{
-		arg++;
-		return !testexpr3();
-		}
-	return testexpr4();
-}
-
-int testexpr4(void)
-{
-int ret,t0,t1;
-struct stat *st;
-char buf[16],*op;
-
-	if (!*arg)
-		{
-		die("expression expected");
-		return 0;
-		}
-	if (!strcmp(*arg,"("))
-		{
-		arg++;
-		ret = testexpr();
-		if (!*arg || strcmp(*arg,")"))
-			{
-			die("')' expected");
-			return 0;
-			}
-		arg++;
-		return ret;
-		}
-	if (**arg == '-' && !(*arg)[2])
-		{
-		switch((*arg++)[1])
-			{
-			case 'a': return(doaccess(F_OK));
-			case 'b': return(S_ISBLK(dostat()));
-			case 'c': return(S_ISCHR(dostat()));
-			case 'd': return(S_ISDIR(dostat()));
-			case 'f': return(S_ISREG(dostat()));
-			case 'g': return(!!(dostat() & S_ISGID));
-			case 'k': return(!!(dostat() & S_ISVTX));
-			case 'L': return(S_ISLNK(dostat()));
-			case 'p': return(S_ISFIFO(dostat()));
-			case 'r': return(doaccess(R_OK));
-			case 's': return((st = getstat()) && !!(st->st_size));
-			case 'S': return(S_ISSOCK(dostat()));
-			case 'u': return(!!(dostat() & S_ISUID));
-			case 'w': return(doaccess(W_OK));
-			case 'x': return(doaccess(X_OK));
-			case 'O': return((st = getstat()) && st->st_uid == geteuid());
-			case 'G': return((st = getstat()) && st->st_gid == getegid());
-			case 't': {
-				int t0 = 1;
-
-				if (*arg && isdigit(**arg))
-					t0 = atoi(*arg++);
-				return isatty(t0);
-				}
-			case 'z':
-				if (!*arg)
-					{
-					die("string expected");
-					return 0;
-					}
-				return !strlen(*arg++);
-			case 'n':
-				if (!*arg)
-					{
-					die("string expected");
-					return 0;
-					}
-				return !!strlen(*arg++);
-			case 'l':
-				sprintf(buf,"%d",strlen(*arg));
-				*arg = buf;
-				break;
-			}
-		}
-	if (!arg[1] || !strcmp(arg[1],"-o") || !strcmp(arg[1],"-a") ||
-			!strcmp(arg[1],"]") || !strcmp(arg[1],")"))
-		return(!!strlen(*arg++));
-	if (!arg[2])
-		{
-		die("bad expression");
-		return 0;
-		}
-	if (!strcmp(arg[1],"-nt"))
-		{
-		time_t a;
-
-		if (!(st = getstat()))
-			{
-			arg += 2;
-			return 0;
-			}
-		a = st->st_mtime;
-		arg++;
-		if (!(st = getstat()))
-			{
-			arg += 2;
-			return 0;
-			}
-		return a > st->st_mtime;
-		}
-	if (!strcmp(arg[1],"-ot"))
-		{
-		time_t a;
-
-		if (!(st = getstat()))
-			{
-			arg += 2;
-			return 0;
-			}
-		a = st->st_mtime;
-		arg++;
-		if (!(st = getstat()))
-			{
-			arg += 2;
-			return 0;
-			}
-		return a < st->st_mtime;
-		}
-	if (!strcmp(arg[1],"-ef"))
-		{
-		dev_t d;
-		ino_t i;
-
-		if (!(st = getstat()))
-			{
-			arg += 2;
-			return 0;
-			}
-		d = st->st_dev;
-		i = st->st_ino;
-		arg++;
-		if (!(st = getstat()))
-			{
-			arg += 2;
-			return 0;
-			}
-		return d == st->st_dev && i == st->st_ino;
-		}
-	if (!strcmp(arg[1],"~="))
-		{
-		arg += 3;
-		return patmatch(arg[-3],arg[-1]);
-		}
-	if (!strcmp(arg[1],"="))
-		{
-		arg += 3;
-		return !strcmp(arg[-3],arg[-1]);
-		}
-	if (!strcmp(arg[1],"!="))
-		{
-		arg += 3;
-		return !!strcmp(arg[-3],arg[-1]);
-		}
-	t0 = atoi(arg[0]);
-	op = arg[1];
-	arg += 2;
-	if (!strcmp(*arg,"-l"))
-		{
-		if (!arg[1])
-			{
-			die("string expected");
-			return 0;
-			}
-		t1 = strlen(arg[1]);
-		arg += 2;
-		}
-	else
-		t1 = atoi(*arg++);
-	if (!strcmp(op,"-eq"))
-		return t0 == t1;
-	if (!strcmp(op,"-ne"))
-		return t0 != t1;
-	if (!strcmp(op,"-lt"))
-		return t0 < t1;
-	if (!strcmp(op,"-le"))
-		return t0 <= t1;
-	if (!strcmp(op,"-gt"))
-		return t0 > t1;
-	if (!strcmp(op,"-ge"))
-		return t0 >= t1;
-	if (!efg)
-		zerrnam("test","unrecognized operator: %s",op);
-	efg = 1;
-	return 0;
-}
-
-int doaccess(int c)
-{
-	if (!*arg)
-		{
-		die("filename expected");
-		return 0;
-		}
-	return !access(*arg++,c);
-}
-
-struct stat *getstat(void)
-{
-static struct stat st;
-
-	if (!*arg)
-		{
-		die("filename expected");
-		return NULL;
-		}
-	if (!strncmp(*arg,"/dev/fd/",8))
-		{
-		if (fstat(atoi((*arg++)+8),&st))
-			return NULL;
-		}
-	else if (lstat(*arg++,&st))
-		return NULL;
-	return &st;
-}
-
-unsigned short dostat(void)
-{
-struct stat *st;
-
-	if (!(st = getstat()))
-		return 0;
-	return st->st_mode;
-}
-
End of test.c
echo test.pro 1>&2
sed 's/^-//' >test.pro <<'End of test.pro'
-void die(char *str);
-int test(comm comm);
-int testmain(char **argv);
-int testexpr(void);
-int testexpr2(void);
-int testexpr3(void);
-int testexpr4(void);
-int doaccess(int c);
-struct stat *getstat(void);
-unsigned short dostat(void);
End of test.pro
echo utils.c 1>&2
sed 's/^-//' >utils.c <<'End of utils.c'
-/*
-
-	utils.c - miscellaneous utilities
-
-	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"
-#include <pwd.h>
-#include <stdarg.h> /* had to change this to stdarg.h.old on one machine */
-#include <errno.h>
-#include <sys/dir.h>
-#include <fcntl.h>
-
-/* add vars to the parm hash table */
-
-void addvars(table vars)
-{
-char *s1,*s2;
-Node node;
-
-	for (node = vars->first; node; node = node->next)
-		{
-		s1 = node->dat;
-		untokenize(s1);
-		node = node->next;
-		s2 = node->dat;
-		dovarsubs(&s2);
-		if (errflag)
-			break;
-		untokenize(s2);
-		setparm(s1,s2,0,0);
-		}
-	free(vars);
-}
-
-/* set a parameter to an integer value */
-
-void setiparm(char *s,long v,int isint)
-{
-struct pmnode *pmn,*pmo;
-
-	if (!strcmp(s,"RANDOM"))
-		{
-		srand((unsigned long) v);
-		return;
-		}
-	if (!strcmp(s,"SECONDS"))
-		{
-		shtimer = v+time(NULL);
-		return;
-		}
-	if (pmo = gethnode(s,parmhtab))
-		{
-		char buf[12];
-
-		pmn = alloc(sizeof *pmn);
-		if (pmn->isint = pmo->isint | isint)
-			pmn->u.val = v;
-		else
-			{
-			sprintf(buf,"%ld",v);
-			pmn->u.str = strdup(buf);
-			}
-		addhnode(s,pmn,parmhtab,freepm);
-		}
-	else if (getenv(s) || (opts[ALLEXPORT] == OPT_SET))
-		{
-		char buf[12];
-
-		sprintf(buf,"%ld",v);
-		putenv(tricat(s,"=",buf));
-		}
-	else
-		{
-		char buf[12];
-
-		pmn = alloc(sizeof *pmn);
-		if (pmn->isint = isint)
-			pmn->u.val = v;
-		else
-			{
-			sprintf(buf,"%ld",v);
-			pmn->u.str = strdup(buf);
-			}
-		addhnode(s,pmn,parmhtab,freepm);
-		addlocal(s);
-		}
-	if (!strcmp(s,"PERIOD"))
-		{
-		period = v*60;
-		lastperiod = time(NULL)+period;
-		}
-	if (!strcmp(s,"HISTSIZE"))
-		{
-		tevs = v;
-		if (tevs <= 2)
-			tevs = 2;
-		}
-}
-
-/* set a parameter to a string value */
-
-void setparm(char *s,char *t,int ex,int isint)
-{
-struct pmnode *pmn,*pmo;
-
-	if (!strcmp(s,"RANDOM"))
-		{
-		srand((unsigned long) atol(t));
-		return;
-		}
-	if (!strcmp(s,"SECONDS"))
-		{
-		shtimer = atol(t)+time(NULL);
-		return;
-		}
-	if (ex && gethnode(s,parmhtab))
-		freepm(remhnode(s,parmhtab));
-	if (pmo = gethnode(s,parmhtab))
-		{
-		pmn = alloc(sizeof *pmn);
-		if (pmn->isint = pmo->isint | isint)
-			{
-			pmn->u.val = matheval(t);
-			free(t);
-			t = NULL;
-			}
-		else
-			pmn->u.str = t;
-		addhnode(s,pmn,parmhtab,freepm);
-		}
-	else if (ex || getenv(s) || (opts[ALLEXPORT] == OPT_SET))
-		putenv(tricat(s,"=",t));
-	else
-		{
-		pmn = alloc(sizeof *pmn);
-		if (pmn->isint = isint)
-			{
-			pmn->u.val = matheval(t);
-			free(t);
-			t = NULL;
-			}
-		else
-			pmn->u.str = t;
-		addhnode(s,pmn,parmhtab,freepm);
-#if 0
-		addlocal(s);
-#endif
-		}
-	if (!t)
-		return;
-	if (!strcmp(s,"PATH"))
-		parsepath();
-	if (!strcmp(s,"CDPATH"))
-		parsecdpath();
-	if (!strcmp(s,"IFS"))
-		{
-		free(ifs);
-		ifs = strdup(t);
-		}
-	if (!strcmp(s,"PERIOD"))
-		{
-		period = atoi(t)*60;
-		lastperiod = time(NULL)+period;
-		}
-	if (!strcmp(s,"HISTSIZE"))
-		{
-		tevs = atoi(t);
-		if (tevs <= 2)
-			tevs = 2;
-		}
-	if (!strcmp(s,"HOME"))
-		{
-		free(home);
-		home = xsymlink(t);
-		}
-	if (!strcmp(s,"MAIL") || !strcmp(s,"MAILCHECK") || !strcmp(s,"MAILPATH"))
-		lastmailcheck = 0;
-}
-
-void unsetparm(char *s)
-{
-char **pp;
-
-	if (!strcmp(s,"HOME"))
-		return;
-	if (!strcmp(s,"PERIOD"))
-		period = 0;
-	if (!strcmp(s,"HISTSIZE"))
-		tevs = 1;
-	if (gethnode(s,parmhtab))
-		{
-		freepm(remhnode(s,parmhtab));
-		return;
-		}
-	for (pp = environ; *pp; pp++)
-		if (!strncmp(*pp,s,strlen(s)) && (*pp)[strlen(s)] == '=')
-			{
-			while (pp[0] = pp[1])
-				pp++;
-			return;
-			}
-}
-
-/* get the integer value of a parameter */
-
-long getiparm(char *s)
-{
-struct pmnode *pmn;
-char *t;
-
-	if (!isalpha(*s) && !s[1])
-		{
-		t = getsparmval(s,1);
-		return (t) ? atoi(t) : 0;
-		}
-	if (s[0] == 'T' && s[1] == 'C' && !s[4])	/* TCxx */
-		return tgetnum(s+2);
-	if (!strcmp(s,"RANDOM"))
-		return rand() & 0x7fff;
-	if (!strcmp(s,"LINENO"))
-		return lineno;
-	if (!strcmp(s,"SECONDS"))
-		return time(NULL)-shtimer;
-	if (pmn = gethnode(s,parmhtab))
-		{
-		if (pmn->isint)
-			return pmn->u.val;
-		return atol(pmn->u.str);
-		}
-	return atol(getenv(s));
-}
-
-/* get the string value of a parameter */
-
-char *getparm(char *s)
-{
-struct pmnode *pmn;
-
-	if (!isalpha(*s) && !s[1])
-		return getsparmval(s,1);
-	if (s[0] == 'T' && s[1] == 'C' && !s[4])	/* TCxx */
-		{
-		static char buf[1024];
-		char *ss = buf;
-		int t0;
-
-		if (tgetstr(s+2,&ss))
-			return buf;
-		if ((t0 = tgetnum(s+2)) != -1)
-			{
-			sprintf(buf,"%d",t0);
-			return buf;
-			}
-		return NULL;
-		}
-	if (!strcmp(s,"LINENO"))
-		{
-		static char buf[8];
-
-		sprintf(buf,"%d",lineno);
-		return buf;
-		}
-	if (!strcmp(s,"RANDOM"))
-		{
-		static char buf[8];
-
-		sprintf(buf,"%d",rand() & 0x7fff);
-		return buf;
-		}
-	if (!strcmp(s,"SECONDS"))
-		{
-		static char buf[12];
-
-		sprintf(buf,"%ld",time(NULL)-shtimer);
-		return buf;
-		}
-	if (pmn = gethnode(s,parmhtab))
-		{
-		static char buf[12];
-
-		if (pmn->isint)
-			{
-			sprintf(buf,"%ld",pmn->u.val);
-			return buf;
-			}
-		return pmn->u.str;
-		}
-	return getenv(s);
-}
-
-/* parse the PATH parameter into directory names in a array of
-	strings and create the command hash table */
-
-void parsepath(void)
-{
-char *pptr = getparm("PATH"),*ptr;
-
-	if (path)
-		{
-		while(pathct)
-			free(path[--pathct]);
-		free(path);
-		}
-	for (pathct = 1, ptr = pptr; *ptr; ptr++)
-		if (*ptr == ':')
-			pathct++;
-	path = (char **) zalloc(pathct*sizeof(char *));
-	pathct = 0;
-	ptr = pptr;
-	while(pptr)
-		{
-		ptr = strchr(pptr,':');
-		if (ptr)
-			*ptr = '\0';
-		path[pathct] = strdup(pptr);
-		if (ptr)
-			{
-			*ptr = ':';
-			pptr = ptr+1;
-			}
-		else
-			pptr = NULL;
-		if (!*path[pathct])
-			{
-			free(path[pathct]);
-			path[pathct] = strdup(".");
-			}
-		pathsub(&path[pathct]);
-		if (*path[pathct] != '/' && strcmp(path[pathct],"."))
-			{
-#ifdef PATH_WARNINGS
-			zerr("PATH component not absolute pathname: %s",path[pathct]);
-#endif
-			free(path[pathct--]);
-			}
-		pathct++;
-		}
-	createchtab();
-}
-
-void parsecdpath(void)
-{
-char *pptr = getparm("CDPATH"),*ptr;
-
-	if (cdpath)
-		{
-		while(cdpathct)
-			free(cdpath[--cdpathct]);
-		free(cdpath);
-		}
-	if (pptr == NULL)
-		{
-		cdpath = (char **) zalloc(sizeof(char *));
-		cdpath[0] = strdup(".");
-		cdpathct = 1;
-		return;
-		}
-	for (cdpathct = 2, ptr = pptr; *ptr; ptr++)
-		if (*ptr == ':')
-			cdpathct++;
-	cdpath = (char **) zalloc(cdpathct*sizeof(char *));
-	cdpath[0] = strdup(".");
-	cdpathct = 1;
-	ptr = pptr;
-	while (pptr)
-		{
-		ptr = strchr(pptr,':');
-		if (ptr)
-			*ptr = '\0';
-		cdpath[cdpathct] = strdup(pptr);
-		if (ptr)
-			{
-			*ptr = ':';
-			pptr = ptr+1;
-			}
-		else
-			pptr = NULL;
-		pathsub(&cdpath[cdpathct]);
-		if (*cdpath[cdpathct] != '/')
-			{
-#ifdef PATH_WARNINGS
-			zerr("CDPATH component not absolute pathname: %s",cdpath[cdpathct]);
-#endif
-			free(cdpath[cdpathct--]);
-			}
-		cdpathct++;
-		}
-}
-
-/* source a file */
-
-int source(char *s)
-{
-int fd,cj = curjob,iact = opts[INTERACTIVE];
-FILE *obshin = bshin;
-
-	fd = SHIN;
-	opts[INTERACTIVE] = OPT_UNSET;
-	if ((SHIN = movefd(open(s,O_RDONLY))) == -1)
-		{
-		SHIN = fd;
-		curjob = cj;
-		opts[INTERACTIVE] = iact;
-		return 1;
-		}
-	bshin = fdopen(SHIN,"r");
-	loop();
-	fclose(bshin);
-	opts[INTERACTIVE] = iact;
-	bshin = obshin;
-	SHIN = fd;
-	peek = EMPTY;
-	curjob = cj;
-	errflag = 0;
-	retflag = 0;
-	return 0;
-}
-
-/* try to source a file in our home directory */
-
-void sourcehome(char *s)
-{
-char buf[MAXPATHLEN];
-
-	sprintf(buf,"%s/%s",getparm("HOME"),s);
-	(void) source(buf);
-}
-
-/* print an error */
-
-void zerrnam(char *cmd, char *fmt, ...)
-{
-va_list ap;
-char *str;
-int num;
-
-	va_start(ap,fmt);
-	fputs(cmd,stderr);
-	putc(':',stderr);
-	putc(' ',stderr);
-	while (*fmt)
-		if (*fmt == '%')
-			{
-			fmt++;
-			switch(*fmt++)
-				{
-				case 's':	/* string */
-					str = va_arg(ap,char *);
-					while (*str)
-						niceputc(*str++,stderr);
-					break;
-				case 'l':	/* string with a length */
-					num = va_arg(ap,int);
-					str = va_arg(ap,char *);
-					while (num--)
-						niceputc(*str++,stderr);
-					break;
-				case 'd':	/* number */
-					num = va_arg(ap,int);
-					fprintf(stderr,"%d",num);
-					break;
-				case '%':
-					putc('%',stderr);
-					break;
-				case 'c':	/* char */
-					num = va_arg(ap,int);
-					niceputc(num,stderr);
-					break;
-				case 'e':	/* system error */
-					num = va_arg(ap,int);
-					if (num == EINTR)
-						{
-						fputs("interrupt\n",stderr);
-						errflag = 1;
-						return;
-						}
-					fputc(tolower(sys_errlist[num][0]),stderr);
-					fputs(sys_errlist[num]+1,stderr);
-					break;
-				}
-			}
-		else
-			putc(*fmt++,stderr);
-	putc('\n',stderr);
-	va_end(ap);
-}
-
-void zerr(char *fmt,...)
-{
-va_list ap;
-char *str;
-int num;
-
-	va_start(ap,fmt);
-	fputs("zsh: ",stderr);
-	while (*fmt)
-		if (*fmt == '%')
-			{
-			fmt++;
-			switch(*fmt++)
-				{
-				case 's':
-					str = va_arg(ap,char *);
-					while (*str)
-						niceputc(*str++,stderr);
-					break;
-				case 'l':
-					num = va_arg(ap,int);
-					str = va_arg(ap,char *);
-					while (num--)
-						niceputc(*str++,stderr);
-					break;
-				case 'd':
-					num = va_arg(ap,int);
-					fprintf(stderr,"%d",num);
-					break;
-				case '%':
-					putc('%',stderr);
-					break;
-				case 'c':
-					num = va_arg(ap,int);
-					niceputc(num,stderr);
-					break;
-				case 'e':
-					num = va_arg(ap,int);
-					if (num == EINTR)
-						{
-						fputs("interrupt\n",stderr);
-						errflag = 1;
-						return;
-						}
-					fputc(tolower(sys_errlist[num][0]),stderr);
-					fputs(sys_errlist[num]+1,stderr);
-					break;
-				}
-			}
-		else
-			putc(*fmt++,stderr);
-	putc('\n',stderr);
-	va_end(ap);
-}
-
-void niceputc(int c,FILE *f)
-{
-	if (istok(c))
-		{
-		if (c >= Pound && c <= Qtick)
-			putc(tokens[c-Pound],f);
-		return;
-		}
-	c &= 0x7f;
-	if (c >= ' ' && c < '\x7f')
-		putc(c,f);
-	else if (c == '\n')
-		{
-		putc('\\',f);
-		putc('n',f);
-		}
-	else
-		{
-		putc('^',f);
-		putc(c|'A',f);
-		}
-}
-
-/* enable ^C interrupts */
-
-void intr(void)
-{
-struct sigvec vec = { handler,sigmask(SIGINT),SV_INTERRUPT };
-	
-	if (interact)
-		sigvec(SIGINT,&vec,NULL);
-	sigsetmask(0);
-}
-
-void noholdintr(void)
-{
-	intr();
-}
-
-void holdintr(void)
-{
-struct sigvec vec = { handler,sigmask(SIGINT),0 };
-
-	if (interact)
-		{
-		sigvec(SIGINT,&vec,NULL);
-		sigsetmask(0);
-		}
-}
-
-char *fgetline(char *buf,int len,FILE *in)
-{
-	if (!fgets(buf,len,in))
-		return NULL;
-	buf[len] = '\0';
-	buf[strlen(buf)-1] = '\0';
-	return buf;
-}
-
-/* get a symlink-free pathname for s relative to PWD */
-
-char *findcwd(char *s)
-{
-char *t;
-
-	if (*s == '/')
-		return xsymlink(s);
-	s = tricat((cwd[1]) ? cwd : "","/",s);
-	t = xsymlink(s);
-	free(s);
-	return t;
-}
-
-static char xbuf[MAXPATHLEN];
-
-/* expand symlinks in s, and remove other weird things */
-
-char *xsymlink(char *s)
-{
-	if (*s != '/')
-		return NULL;
-	strcpy(xbuf,"");
-	if (xsymlinks(s+1))
-		return strdup(s);
-	if (!*xbuf)
-		return strdup("/");
-	return strdup(xbuf);
-}
-
-char **slashsplit(char *s)
-{
-char *t,**r,**q;
-int t0;
-
-	if (!*s)
-		return (char **) calloc(sizeof(char **),1);
-	for (t = s, t0 = 0; *t; t++)
-		if (*t == '/')
-			t0++;
-	q  = r = (char **) zalloc(sizeof(char **)*(t0+2));
-	while (t = strchr(s,'/'))
-		{
-		*t = '\0';
-		*q++ = strdup(s);
-		*t = '/';
-		while (*t == '/')
-			t++;
-		if (!*t)
-			{
-			*q = NULL;
-			return r;
-			}
-		s = t;
-		}
-	*q++ = strdup(s);
-	*q = NULL;
-	return r;
-}
-
-int islink(char *s)
-{
-char xbuf[MAXPATHLEN];
-
-	if (readlink(s,xbuf,1) == -1 && errno == EINVAL)
-		return 0;
-	return 1;
-}
-
-int xsymlinks(char *s)
-{
-char **pp,**opp;
-char xbuf2[MAXPATHLEN],xbuf3[MAXPATHLEN];
-int t0;
-
-	opp = pp = slashsplit(s);
-	for (; *pp; pp++)
-		{
-		if (!strcmp(*pp,"."))
-			{
-			free(*pp);
-			continue;
-			}
-		if (!strcmp(*pp,".."))
-			{
-			char *p;
-
-			free(*pp);
-			if (!strcmp(xbuf,"/"))
-				continue;
-			p = xbuf+strlen(xbuf);
-			while (*--p != '/');
-			*p = '\0';
-			continue;
-			}
-		sprintf(xbuf2,"%s/%s",xbuf,*pp);
-		t0 = readlink(xbuf2,xbuf3,MAXPATHLEN);
-		if (t0 == -1)
-			{
-			if (errno != EINVAL)
-				{
-				while (*pp)
-					free(*pp++);
-				free(opp);
-				return 1;
-				}
-			strcat(xbuf,"/");
-			strcat(xbuf,*pp);
-			free(*pp);
-			}
-		else
-			{
-			xbuf3[t0] = '\0'; /* STUPID */
-			if (*xbuf3 == '/')
-				{
-				strcpy(xbuf,"");
-				if (xsymlinks(xbuf3+1))
-					return 1;
-				}
-			else
-				if (xsymlinks(xbuf3))
-					return 1;
-			free(*pp);
-			}
-		}
-	free(opp);
-	return 0;
-}
-
-void printdir(char *s)
-{
-int t0;
-
-	if (!strncmp(s,home,t0 = strlen(home)))
-		{
-		putchar('~');
-		fputs(s+t0,stdout);
-		}
-	else
-		fputs(s,stdout);
-}
-
-
-int ddifftime(time_t t1,time_t t2)
-{
-	return ((long) t2-(long) t1);
-}
-
-/* see if jobs need printing */
-
-void scanjobs(void)
-{
-int t0;
-
-	for (t0 = 1; t0 != MAXJOB; t0++)
-		if (jobtab[t0].stat & STAT_CHANGED)
-			printjob(jobtab+t0,0);
-}
-
-/* do pre-prompt stuff */
-
-void preprompt(void)
-{
-int diff;
-list list;
-char *mc = getparm("MAILCHECK"),*wc = getparm("LOGCHECK");
-struct schnode *sch,*schl;
-
-	if (unset(NOTIFY))
-		scanjobs();
-	if (errflag)
-		return;
-	if (list = gethnode("precmd",shfunchtab))
-		newrunlist(list);
-	if (errflag)
-		return;
-	if (period && (time(NULL) > lastperiod+period) &&
-			(list = gethnode("periodic",shfunchtab)))
-		{
-		newrunlist(list);
-		lastperiod = time(NULL);
-		}
-	if (errflag)
-		return;
-	if (getparm("WATCH"))
-		{
-		diff = (int) ddifftime(lastwatch,time(NULL));
-		if (diff > ((wc) ? atoi(wc)*60 : 300))
-			{
-			lastwatch = time(NULL);
-			watch();
-			}
-		}
-	if (errflag)
-		return;
-	diff = (int) ddifftime(lastmailcheck,time(NULL));
-	if (diff > ((mc) ? atoi(mc) : 60))
-		{
-		lastmailcheck = time(NULL);
-		if (getparm("MAILPATH"))
-			checkmailpath();
-		else
-			checkmail();
-		}
-	for (schl = (struct schnode *) &scheds, sch = scheds; sch;
-			sch = (schl = sch)->next)
-		{
-		if (sch->time < time(NULL))
-			{
-			execstring(sch->cmd);
-			schl->next = sch->next;
-			free(sch);
-			}
-		if (errflag)
-			return;
-		}
-}
- 
-void checkmail(void)
-{
-struct stat st;
-char *s;
-
-	if (!(s = getparm("MAIL")))
-		return;
-	if (stat(s,&st) == -1)
-		{
-		if (errno != ENOENT)
-			zerr("%e: %s",errno,getparm("MAIL"));
-		lastmailval = 0;
-		lastmailsize = 0;
-		return;
-		}
-	else
-		if (lastmailval != -1 && lastmailval < st.st_mtime &&
-				lastmailsize < st.st_size)
-			zerr("you have new mail.");
-	lastmailval = st.st_mtime;
-	lastmailsize = st.st_size;
-}
-
-void checkfirstmail(void)
-{
-struct stat st;
-char *s;
-
-	if (!(s = getparm("MAIL")))
-		return;
-	if (stat(s,&st) == -1)
-		{
-		if (errno != ENOENT)
-			zerr("%e: %s",errno,getparm("MAIL"));
-		lastmailval = 0;
-		lastmailsize = 0;
-		return;
-		}
-	lastmailval = st.st_mtime;
-	lastmailsize = st.st_size;
-	zerr("you have mail.");
-}
- 
-void checkmailpath(void)
-{
-struct stat st;
-char *s = getparm("MAILPATH"),*v,*u,c,d;
-
-	for (;;)
-		{
-		for (v = s; *v && *v != '?' && *v != ':'; v++);
-		c = *v;
-		*v = '\0';
-		if (c != '?')
-			u = NULL;
-		else
-			{
-			for (u = v+1; *u && *u != ':'; u++);
-			d = *u;
-			*u = '\0';
-			}
-		if (stat(s,&st) == -1)
-			{
-			if (errno != ENOENT)
-				zerr("%e: %s",errno,getparm("MAIL"));
-			}
-		else
-			if (lastmailval != -1 && lastmailval < st.st_mtime &&
-					lastmailsize < st.st_size)
-				if (!u)
-					fprintf(stderr,"You have new mail.\n");
-				else
-					{
-					char *z = u;
-
-					while (*z)
-						if (*z == '$' && z[1] == '_')
-							{
-							fprintf(stderr,"%s",s);
-							z += 2;
-							}
-						else
-							fputc(*z++,stderr);
-					fputc('\n',stderr);
-					}
-		lastmailval = st.st_mtime;
-		lastmailsize = st.st_size;
-		*v = c;
-		if (u)
-			*u = d;
-		if (!c || (u && !d))
-			break;
-		v = (u) ? u+1 : v+1;
-		}
-}
-
-/* create command hash table */
-
-void createchtab(void)
-{
-int t0,dot = 0;
-struct direct *de;
-DIR *dir;
-struct chnode *cc;
-
-	holdintr();
-	if (chtab)
-		freehtab(chtab,freechnode);
-	chtab = newhtable(101);
-	for (t0 = 0; t0 != pathct; t0++)
-		if (!strcmp(".",path[t0]))
-			{
-			dot = 1;
-			break;
-			}
-	for (t0 = pathct-1; t0 >= 0; t0--)
-		if (!strcmp(".",path[t0]))
-			dot = 0;
-		else
-			{
-			dir = opendir(path[t0]);
-			if (!dir)
-				{
-				zerr("%e: %s",errno,path[t0]);
-				continue;
-				}
-			readdir(dir); readdir(dir);
-			while (de = readdir(dir))
-				{
-				cc = alloc(sizeof(struct chnode));
-				cc->type = (dot) ? EXCMD_POSTDOT : EXCMD_PREDOT;
-				cc->globstat = GLOB;
-				cc->u.nam = tricat(path[t0],"/",de->d_name);
-				addhnode(strdup(de->d_name),cc,chtab,freechnode);
-				}
-			closedir(dir);
-			}
-	addintern(chtab);
-	noholdintr();
-}
-
-void freechnode(void *a)
-{
-struct chnode *c = (struct chnode *) a;
-
-	if (c->type != BUILTIN)
-		free(c->u.nam);
-	free(c);
-}
-
-void freestr(void *a)
-{
-	free(a);
-}
-
-void freeanode(void *a)
-{
-struct anode *c = (struct anode *) a;
-
-	free(c->text);
-	free(c);
-}
-
-void freeredir(void *a)
-{
-struct fnode *f = (struct fnode *) a;
-
-	if (f)
-		{
-		if (f->type == HEREDOC)
-			close(f->u.fd2);
-		else
-			free(f->u.name);
-		free(f);
-		}
-}
-
-void freeshfunc(void *a)
-{
-	freelist((list) a);
-}
-
-void freepm(void *a)
-{
-struct pmnode *pm = a;
-
-	if (!pm->isint)
-		free(pm->u.str);
-	free(pm);
-}
-
-void restoretty(void)
-{
-	settyinfo(&shttyinfo);
-}
-
-void gettyinfo(struct ttyinfo *ti)
-{
-	if (jobbing)
-		{
-#ifndef BUGGY_GCC
-#ifdef TERMIOS
-		ioctl(SHTTY,TCGETS,&ti->termios);
-#else
-		ioctl(SHTTY,TIOCGETP,&ti->sgttyb);
-		ioctl(SHTTY,TIOCGETC,&ti->tchars);
-		ioctl(SHTTY,TIOCGLTC,&ti->ltchars);
-#endif
-		ioctl(SHTTY,TIOCGWINSZ,&ti->winsize);
-#else
-#ifdef TERMIOS
-		ioctl(SHTTY,	(	0x40000000	|((sizeof( struct termios)&0xff		)<<16)|('T'<<8)| 8)  ,&ti->termios);
-#else
-		ioctl(SHTTY,(0x40000000|((sizeof(struct sgttyb)&0x1fff)<<16)|
-			('t'<<8)|8),&ti->sgttyb);
-		ioctl(SHTTY,(0x40000000|((sizeof(struct tchars)&0x1fff)<<16)|
-			('t'<<8)|18),&ti->tchars);
-		ioctl(SHTTY,(0x40000000|((sizeof(struct ltchars)&0x1fff)<<16)|
-			('t'<<8)|116),&ti->ltchars);
-#endif
-		ioctl(SHTTY,(	0x40000000	|((sizeof( struct winsize)&0xff		)<<16)|('t'<<8)| 104) 	,&ti->winsize);
-#endif
-		}
-}
-
-void settyinfo(struct ttyinfo *ti)
-{
-	if (jobbing)
-		{
-#ifndef BUGGY_GCC
-#ifdef TERMIOS
-		ioctl(SHTTY,TCSETS,&ti->termios);
-#else
-		ioctl(SHTTY,TIOCSETP,&ti->sgttyb);
-		ioctl(SHTTY,TIOCSETC,&ti->tchars);
-		ioctl(SHTTY,TIOCSLTC,&ti->ltchars);
-#endif
-		ioctl(SHTTY,TIOCSWINSZ,&ti->winsize);
-#else
-#ifdef TERMIOS
-		ioctl(SHTTY,	(	0x80000000	|((sizeof( struct termios)&0xff		)<<16)|('T'<<8)| 9)  ,&ti->termios);
-#else
-		ioctl(SHTTY,(0x80000000|((sizeof( struct sgttyb)&0x1fff)<<16)|
-			('t'<<8)|9),&ti->sgttyb);
-		ioctl(SHTTY,(0x80000000|((sizeof(struct tchars)&0x1fff)<<16)|
-			('t'<<8)|17),&ti->tchars);
-		ioctl(SHTTY,(0x80000000|((sizeof(struct ltchars)&0x1fff)<<16)|
-			('t'<<8)|117),&ti->ltchars);
-#endif
-		ioctl(SHTTY,(	0x80000000	|((sizeof( struct winsize)&0xff		)<<16)|('t'<<8)| 103) 	,&ti->winsize);
-#endif
-		}
-}
-
-int zyztem(char *s,char *t)
-{
-#ifdef WAITPID
-int pid,statusp;
-
-	if (!(pid = fork()))
-		{
-		s = tricat(s," ",t);
-		execl("/bin/sh","sh","-c",s,(char *) 0);
-		_exit(1);
-		}
-	waitpid(pid,&statusp,WUNTRACED);
-	if (WIFEXITED(SP(statusp)))
-		return WEXITSTATUS(SP(statusp));
-	return 1;
-#else
-	if (!waitfork())
-		{
-		s = tricat(s," ",t);
-		execl("/bin/sh","sh","-c",s,(char *) 0);
-		_exit(1);
-		}
-	return 0;
-#endif
-}
-
-#ifndef WAITPID
-
-/* fork a process and wait for it to complete without confusing
-	the SIGCHLD handler */
-
-int waitfork(void)
-{
-int pipes[2];
-char x;
-
-	pipe(pipes);
-	if (!fork())
-		{
-		close(pipes[0]);
-		signal(SIGCHLD,SIG_DFL);
-		if (!fork())
-			return 0;
-		wait(NULL);
-		_exit(0);
-		}
-	close(pipes[1]);
-	read(pipes[0],&x,1);
-	close(pipes[0]);
-	return 1;
-}
-
-#endif
-
-/* move a fd to a place >= 10 */
-
-int movefd(int fd)
-{
-int fe;
-
-	if (fd == -1)
-		return fd;
-	if ((fe = dup(fd)) < 10)
-		fe = movefd(fe);
-	close(fd);
-	return fe;
-}
-
-/* move fd x to y */
-
-void redup(int x,int y)
-{
-	if (x != y)
-		{
-		dup2(x,y);
-		close(x);
-		}
-}
-
-void settrap(char *s,int empty)
-{
-int t0;
-
-	if (strncmp(s,"TRAP",4))
-		return;
-	for (t0 = 0; t0 != SIGCOUNT+2; t0++)
-		if (!strcmp(s+4,sigs[t0]))
-			{
-			if (jobbing && (t0 == SIGTTOU || t0 == SIGTSTP || t0 == SIGTTIN
-					|| t0 == SIGPIPE))
-				{
-				zerr("can't trap SIG%s in interactive shells",s);
-				return;
-				}
-			if (empty)
-				{
-				sigtrapped[t0] = 2;
-				if (t0 && t0 < SIGCOUNT && t0 != SIGCHLD)
-					{
-					signal(t0,SIG_IGN);
-					sigtrapped[t0] = 2;
-					}
-				}
-			else
-				{
-				if (t0 && t0 < SIGCOUNT && t0 != SIGCHLD)
-					signal(t0,handler);
-				sigtrapped[t0] = 1;
-				}
-			return;
---cut here---cut here---cut here---

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

---cut here---cut here---cut here---
-			}
-	zerr("warning: undefined signal name: SIG%s",s+4);
-}
-
-void unsettrap(char *s)
-{
-int t0;
-
-	if (strncmp(s,"TRAP",4))
-		return;
-	for (t0 = 0; t0 != SIGCOUNT+2; t0++)
-		if (!strcmp(s+4,sigs[t0]))
-			{
-			if (jobbing && (t0 == SIGTTOU || t0 == SIGTSTP || t0 == SIGTTIN
-					|| t0 == SIGPIPE))
-				{
-				zerr("can't trap SIG%s in interactive shells",s);
-				return;
-				}
-			sigtrapped[t0] = 0;
-			if (t0 == SIGINT)
-				intr();
-			else if (t0 && t0 < SIGCOUNT && t0 != SIGCHLD)
-				signal(t0,SIG_DFL);
-			return;
-			}
-	zerr("warning: undefined signal name: SIG%s",s+4);
-}
-
-void dotrap(int sig)
-{
-char buf[16];
-list l;
-int sav;
-
-	sav = sigtrapped[sig];
-	if (sav == 2)
-		return;
-	sigtrapped[sig] = 2;
-	sprintf(buf,"TRAP%s",sigs[sig]);
-	if (l = gethnode(buf,shfunchtab))
-		newrunlist(l);
-	sigtrapped[sig] = sav;
-}
-
-/* get the text corresponding to a command */
-
-char *gettext(comm comm)
-{
-char *s,*t;
-
-	switch(comm->type)
-		{
-		case SIMPLE:
-			return getsimptext(comm);
-		case SUBSH:
-			t = getltext(comm->left);
-			s = tricat("(",t,")");
-			free(t);
-			return s;
-		case CURSH:
-		case SHFUNC:
-			t = getltext(comm->left);
-			s = tricat("{",t,"}");
-			free(t);
-			return s;
-		case CFOR:
-			return getfortext((struct fornode *) comm->info,comm);
-		case CWHILE:
-			return getwhiletext((struct whilenode *) comm->info);
-		case CREPEAT:
-			return getrepeattext((struct repeatnode *) comm->info);
-		case CIF:
-			return getiftext((struct ifnode *) comm->info);
-		case CCASE:
-			return getcasetext((struct casenode *) comm->info,comm->args);
-		case CSELECT:
-			return getfortext((struct fornode *) comm->info,comm);
-		default:
-			return strdup("(...)");
-		}
-	return NULL;
-}
-
-char *getltext(list l)
-{
-char *s,*t,*u;
-
-	s = getl2text(l->left);
-	if (l->type == ASYNC)
-		{
-		t = dyncat(s," &");
-		free(s);
-		s = t;
-		}
-	if (!l->right)
-		return s;
-	t = getltext(l->right);
-	u = tricat(s,(l->type == SYNC) ? "\n" : "",t);
-	free(s);
-	free(t);
-	return u;
-}
-
-char *getl2text(list2 l)
-{
-char *s,*t,*u;
-
-	s = getptext(l->left);
-	if (!l->right)
-		return s;
-	t = getl2text(l->right);
-	u = tricat(s,(l->type == ORNEXT) ? " || " : " && ",t);
-	free(s);
-	free(t);
-	return u;
-}
-
-char *getptext(pline p)
-{
-char *s,*t,*u;
-
-	s = gettext(p->left);
-	if (!p->right)
-		return s;
-	t = getptext(p->right);
-	u = tricat(s," | ",t);
-	free(s);
-	free(t);
-	return u;
-}
-
-char *getsimptext(comm comm)
-{
-int len = 0;
-Node n;
-char *fstr[] = {
-	">",">!",">>",">>!","<","<<","<&",">&",">&-"
-	};
-struct fnode *f;
-char *s,*t,u = '=';
-
-	for (n = comm->args->first; n; n = n->next)
-		len += strlen(n->dat)+1;
-	if (comm->vars)
-		for (n = comm->vars->first; n; n = n->next)
-			len += strlen(n->dat)+1;
-	for (n = comm->redir->first; n; n = n->next)
-		{
-		f = n->dat;
-		switch(f->type)
-			{
-			case WRITE: case WRITENOW: case APP: case APPNOW: case READ:
-				len += strlen(fstr[f->type])+strlen(f->u.name)+8;
-				break;
-			case HEREDOC: case MERGE: case MERGEOUT:
-				len += strlen(fstr[f->type])+10;
-				break;
-			case CLOSE:
-				len += 10;
-				break;
-			case INPIPE:
-			case OUTPIPE:
-				len += strlen(f->u.name)+10;
-				break;
-			}
-		}
-	len += strlen(comm->cmd);
-	s = t = zalloc(len+5);
-	if (comm->vars)
-		for (n = comm->vars->first; n; n = n->next)
-			{
-			strucpy(&t,n->dat);
-			*t++ = u;
-			u = ('='+' ')-u;
-			}
-	strucpy(&t,comm->cmd);
-	*t++ = ' ';
-	for (n = comm->args->first; n; n = n->next)
-		{
-		strucpy(&t,n->dat);
-		*t++ = ' ';
-		}
-	for (n = comm->redir->first; n; n = n->next)
-		{
-		f = n->dat;
-		switch(f->type)
-			{
-			case WRITE: case WRITENOW: case APP: case APPNOW: case READ:
-				if (f->fd1 != ((f->type == READ) ? 0 : 1))
-					*t++ = '0'+f->fd1;
-				strucpy(&t,fstr[f->type]);
-				*t++ = ' ';
-				strucpy(&t,f->u.name);
-				*t++ = ' ';
-				break;
-			case HEREDOC: case MERGE: case MERGEOUT:
-				if (f->fd1 != ((f->type == MERGEOUT) ? 1 : 0))
-					*t++ = '0'+f->fd1;
-				strucpy(&t,fstr[f->type]);
-				*t++ = ' ';
-				sprintf(t,"%d ",f->u.fd2);
-				t += strlen(t);
-				break;
-			case CLOSE:
-				*t++ = '0'+f->fd1;
-				strucpy(&t,">&- ");
-				break;
-			case INPIPE:
-			case OUTPIPE:
-				if (f->fd1 != ((f->type == INPIPE) ? 0 : 1))
-					*t++ = '0'+f->fd1;
-				strucpy(&t,(f->type == INPIPE) ? "< " : "> ");
-				strucpy(&t,f->u.name);
-				strucpy(&t," ");
-				len += strlen(f->u.name)+6;
-				break;
-			}
-		}
-	t[-1] = '\0';
-	return s;
-}
-
-char *getfortext(struct fornode *n,comm comm)
-{
-char *s,*t,*u,*v;
-
-	s = getltext(n->list);
-	u = dyncat((comm->type == CFOR) ? "for " : "select ",n->name);
-	if (comm->args)
-		{
-		t = makehlist(comm->args,0);
-		v = tricat(u," in ",t);
-		free(u);
-		free(t);
-		u = v;
-		}
-	v = dyncat(u,"\n do ");
-	free(u);
-	u = tricat(v,s,"\n done");
-	free(v);
-	free(s);
-	return u;
-}
-
-char *getwhiletext(struct whilenode *n)
-{
-char *s,*t,*u,*v;
-
-	t = getltext(n->cont);
-	v = getltext(n->loop);
-	s = tricat((!n->cond) ? "while " : "until ",t,"\n do ");
-	u = tricat(s,v,"\n done");
-	free(s);
-	free(t);
-	free(v);
-	return u;
-}
-
-char *getrepeattext(struct repeatnode *n)
-{
-char buf[100];
-char *s,*t,*u;
-
-	s = getltext(n->list);
-	sprintf(buf,"%d",n->count);
-	t = tricat("repeat ",buf," do ");
-	u = tricat(t,s,"\n done");
-	free(s);
-	free(t);
-	return u;
-}
-
-char *getiftext(struct ifnode *n)
-{
-int fst = 1;
-char *v = strdup("");
-char *s,*t,*u,*w;
-
-	while (n && n->ifl)
-		{
-		s = getltext(n->ifl);
-		t = getltext(n->thenl);
-		u = tricat((fst) ? "if " : "elif ",s,"\n then ");
-		w = tricat(u,t,"\n ");
-		free(s);
-		free(t);
-		free(u);
-		s = dyncat(v,w);
-		free(v);
-		free(w);
-		v = s;
-		fst = 0;
-		n = n->next;
-		}
-	if (n)
-		{
-		s = getltext(n->thenl);
-		t = tricat(v,"else ",s);
-		u = dyncat(t,"\n fi");
-		free(s);
-		free(t);
-		free(v);
-		return u;
-		}
-	u = dyncat(v,"\n fi");
-	free(v);
-	return u;
-}
-
-char *getcasetext(struct casenode *n,table l)
-{
-char *s,*t,*u,*v;
-
-	s = tricat("case ",l->first->dat," in ");
-	while (n)
-		{
-		u = getltext(n->list);
-		t = tricat(n->pat,") ",u);
-		v = tricat(s,t," ;;\n");
-		free(s);
-		free(t);
-		free(u);
-		s = v;
-		n = n->next;
-		}
-	t = dyncat(s,"esac\n");
-	free(s);
-	return t;
-}
-
-/* copy t into *s and update s */
-
-void strucpy(char **s,char *t)
-{
-char *u = *s;
-
-	while (*u++ = *t++);
-	*s = u-1;
-}
-
-void checkrmall(void)
-{
-	fflush(stdin);
-	fprintf(stderr,"zsh: are you sure you want to delete "
-		"all the files? ");
-	fflush(stderr);
-	ding();
-	errflag |= !getquery();
-}
-
-int getquery(void)
-{
-char c;
-int yes = 0;
-
-	setcbreak();
-	if (read(SHTTY,&c,1) == 1 && (c == 'y' || c == 'Y'))
-		yes = 1;
-	unsetcbreak();
-	if (c != '\n')
-		write(2,"\n",1);
-	return yes;
-}
-
-static int d;
-static char *guess,*best;
-
-void spscan(char *s,char *junk)
-{
-int nd;
-
-	nd = spdist(s,guess);
-	if (nd <= d && nd != 3)
-		{
-		best = s;
-		d = nd;
-		}
-}
-
-/* spellcheck a command */
-
-void spckcmd(char **s)
-{
-char *t;
-
-	if (gethnode(*s,chtab) || gethnode(*s,shfunchtab))
-		return;
-	for (t = *s; *t; t++)
-		if (*t == '/')
-			return;
-	if (access(*s,F_OK) == 0)
-		return;
-	best = NULL;
-	guess = *s;
-	d = 3;
-	listhtable(chtab,spscan);
-	listhtable(shfunchtab,spscan);
-	if (best)
-		{
-		fprintf(stderr,"zsh: correct to `%s' (y/n)? ",best);
-		fflush(stderr);
-		ding();
-		if (getquery())
-			{
-			free(*s);
-			*s = strdup(best);
-			}
-		}
-}
-
-void addlocal(char *s)
-{
-	if (locallist)
-		addnode(locallist,strdup(s));
-}
-
-/* perform pathname substitution on a PATH or CDPATH component */
-
-void pathsub(char **s)
-{
-	if (**s == '=')
-		**s = Equals;
-	if (**s == '~')
-		**s = Tilde;
-	filesub((void **) s);
-}
-
-#ifndef STRFTIME
-int strftime(char *buf,int bufsize,char *fmt,struct tm *tm)
-{
-char *astr[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
-char *estr[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul",
-	"Aug","Sep","Oct","Nov","Dec"};
-char *lstr[] = {"12"," 1"," 2"," 3"," 4"," 5"," 6"," 7"," 8"," 9","10","11"};
-
-	while (*fmt)
-		if (*fmt == '%')
-			{
-			fmt++;
-			switch(*fmt++)
-				{
-				case 'a':
-					strucpy(&buf,astr[tm->tm_wday]);
-					break;
-				case 'b':
-					strucpy(&buf,estr[tm->tm_mon]);
-					break;
-				case 'd':
-					*buf++ = '0'+tm->tm_mday/10;
-					*buf++ = '0'+tm->tm_mday%10;
-					break;
-				case 'e':
-					*buf++ = (tm->tm_mday > 9) ? '0'+tm->tm_mday/10 : ' ';
-					*buf++ = '0'+tm->tm_mday%10;
-					break;
-				case 'k':
-					*buf++ = (tm->tm_hour > 9) ? '0'+tm->tm_hour/10 : ' ';
-					*buf++ = '0'+tm->tm_hour%10;
-					break;
-				case 'l':
-					strucpy(&buf,lstr[tm->tm_hour%12]);
-					break;
-				case 'm':
-					*buf++ = '0'+tm->tm_mon/10;
-					*buf++ = '0'+tm->tm_mon%10;
-					break;
-				case 'M':
-					*buf++ = '0'+tm->tm_min/10;
-					*buf++ = '0'+tm->tm_min%10;
-					break;
-				case 'p':
-					*buf++ = (tm->tm_hour > 11) ? 'P' : 'A';
-					*buf++ = 'M';
-					break;
-				case 'S':
-					*buf++ = '0'+tm->tm_sec/10;
-					*buf++ = '0'+tm->tm_sec%10;
-					break;
-				case 'y':
-					*buf++ = '0'+tm->tm_year/10;
-					*buf++ = '0'+tm->tm_year%10;
-					break;
-				default:
-					exit(20);
-				}
-			}
-		else
-			*buf++ = *fmt++;
-	*buf = '\0';
-	return 0;
-}
-#endif
-
-#ifndef PUTENV
-int putenv(char *a)
-{
-char *b = a;
-
-	while (*a++ != '=');
-	a[-1] = '\0';
-	setenv(strdup(b),strdup(a));
-	free(b);
-	return 0;
-}
-#endif
-
-int ppcount(void)
-{
-Node n;
-int val = -1;
-
-	for (n = pparms->first; n; n = n->next,val++);
-	return val;
-}
-
End of utils.c
echo utils.pro 1>&2
sed 's/^-//' >utils.pro <<'End of utils.pro'
-void addvars(table vars);
-void setiparm(char *s,long v,int isint);
-void setparm(char *s,char *t,int ex,int isint);
-void unsetparm(char *s);
-long getiparm(char *s);
-char *getparm(char *s);
-void parsepath(void);
-void parsecdpath(void);
-int source(char *s);
-void sourcehome(char *s);
-void zerrnam(char *cmd, char *fmt, ...);
-void zerr(char *fmt,...);
-void niceputc(int c,FILE *f);
-void intr(void);
-void noholdintr(void);
-void holdintr(void);
-char *fgetline(char *buf,int len,FILE *in);
-char *findcwd(char *s);
-char *xsymlink(char *s);
-char **slashsplit(char *s);
-int islink(char *s);
-int xsymlinks(char *s);
-void printdir(char *s);
-int ddifftime(time_t t1,time_t t2);
-void scanjobs(void);
-void preprompt(void);
-void checkmail(void);
-void checkfirstmail(void);
-void checkmailpath(void);
-void createchtab(void);
-void freechnode(void *a);
-void freestr(void *a);
-void freeanode(void *a);
-void freeredir(void *a);
-void freeshfunc(void *a);
-void freepm(void *a);
-void restoretty(void);
-void gettyinfo(struct ttyinfo *ti);
-void settyinfo(struct ttyinfo *ti);
-int zyztem(char *s,char *t);
-int waitfork(void);
-int movefd(int fd);
-void redup(int x,int y);
-void settrap(char *s,int empty);
-void unsettrap(char *s);
-void dotrap(int sig);
-char *gettext(comm comm);
-char *getltext(list l);
-char *getl2text(list2 l);
-char *getptext(pline p);
-char *getsimptext(comm comm);
-char *getfortext(struct fornode *n,comm comm);
-char *getwhiletext(struct whilenode *n);
-char *getrepeattext(struct repeatnode *n);
-char *getiftext(struct ifnode *n);
-char *getcasetext(struct casenode *n,table l);
-void strucpy(char **s,char *t);
-void checkrmall(void);
-int getquery(void);
-void spscan(char *s,char *junk);
-void spckcmd(char **s);
-void addlocal(char *s);
-void pathsub(char **s);
-int strftime(char *buf,int bufsize,char *fmt,struct tm *tm);
End of utils.pro
echo vars.c 1>&2
sed 's/^-//' >vars.c <<'End of vars.c'
-/*
-
-	vars.c - variable declarations
-
-	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"
-
-/* buffered shell input for non-interactive shells */
-
-FILE *bshin;
-
-/* null-terminated array of pointers to strings containing elements
-	of PATH and CDPATH */
-
-char **path,**cdpath;
-
-/* number of elements in aforementioned array */
-
-int pathct,cdpathct;
-
-/* error/break flag */
-
-int errflag = 0;
-
-/* current history event number */
-
-int cev = 0;
-
-/* if != 0, this is the first line of the command */
-
-int firstln;
-
-/* if != 0, this is the first char of the command (not including
-	white space */
-
-int firstch;
-
-/* first event number in the history table */
-
-int tfev = 1;
-
-/* capacity of history table */
-
-int tevs = 20;
-
-/* if = 1, we have performed history substitution on the current line
-	if = 2, we have used the 'p' modifier */
-
-int hflag;
-
-/* default event (usually cev-1, that is, "!!") */
-
-int dev = 0;
-
-/* != 0 if we are in the middle of parsing a command (== 0 if we
-	have not yet parsed the command word */
-
-int incmd = 0;
-
-/* the list of history events */
-
-table histlist;
-
-/* the current history event (can be NULL) */
-
-table curtab;
-
-/* the directory stack */
-
-table dirstack;
-
-/* a string containing all the ungot characters (hungetch()) */
-
-char *ungots;
-
-/* the pointer to the next character to read from ungots */
-
-char *ungotptr;
-
-/* the contents of the IFS parameter */
-
-char *ifs;
-
-/* != 0 if this is a subshell */
-
-int subsh;
-
-/* # of break levels (break builtin) */
-
-int breaks;
-
-/* != 0 if we have a return pending (return builtin) */
-
-int retflag;
-
-/* # of nested loops we are in */
-
-int loops;
-
-/* # of continue levels */
-
-int contflag;
-
-/* the job currently being created/waited for (not current job in the sense
-	of '+' and '-', that's topjob */
-
-int curjob;
-
-/* the current job (+) */
-
-int topjob = -1;
-
-/* the previous job (-) */
-
-int prevjob = -1;
-
-/* hash table containing the aliases and reserved words */
-
-htable alhtab;
-
-/* hash table containing the parameters */
-
-htable parmhtab;
-
-/* hash table containing the builtins/hashed commands */
-
-htable chtab;
-
-/* hash table containing the shell functions */
-
-htable shfunchtab;
-
-/* the job table */
-
-struct jobnode jobtab[MAXJOB];
-
-/* the list of sched jobs pending */
-
-struct schnode *scheds = NULL;
-
-/* the last l for s/l/r/ history substitution */
-
-char *last;
-
-/* the last r for s/l/r/ history substitution */
-
-char *rast;
-
-/* if peek == STRING or ENVSTRING, the next token */
-
-char *tstr;
-
-/* who am i */
-
-char *username;
-
-/* the return code of the last command */
-
-int lastval;
-
-/* != 0 if this is a login shell */
-
-int islogin;
-
-/* the next token (enum xtok) */
-
-int peek;
-
-/* the file descriptor associated with the next token, if it
-	is something like '<' or '>>', etc. */
-
-int peekfd;
-
-/* input fd from the coprocess */
-
-int spin = -1;
-
-/* output fd from the coprocess */
-
-int spout = -1;
-
-/* the last time we checked mail */
-
-time_t lastmailcheck;
-
-/* the last modified date on the mail file last time we checked */
-
-time_t lastmailval;
-
-/* the last time we checked the people in the WATCH variable */
-
-time_t lastwatch;
-
-/* the last time we did the periodic() shell function */
-
-time_t lastperiod;
-
-/* $SECONDS = time(NULL) - shtimer */
-
-time_t shtimer;
-
-/* the size of the mail file last time we checked */
-
-off_t lastmailsize;
-
-/* $$ */
-
-long procnum;
-
-/* $! (the pid of the last background command invoked */
-
-long proclast;
-
-/* the process group of the shell */
-
-long shpgrp;
-
-/* the current working directory */
-
-char *cwd;
-
-/* the hostname, truncated after the '.' */
-
-char *hostM;
-
-/* the hostname */
-
-char *hostm;
-
-/* the home directory */
-
-char *home;
-
-/* the positional parameters */
-
-table pparms;
-
-/* the list of local variables we have to destroy */
-
-table locallist;
-
-/* the shell input fd */
-
-int SHIN;
-
-/* the shell tty fd */
-
-int SHTTY;
-
-/* the stack of aliases we are expanding */
-
-struct anode *alstack[MAXAL];
-
-/* the alias stack pointer; also, the number of aliases currently
-	being expanded */
-
-int alix = 0;
-
-/* != 0 means we are reading input from a string */
-
-int strin = 0;
-
-/* == 1 means we are doing TAB expansion
-	== 2 means expansion has occurred during TAB expansion */
-
-int magic = 0;
-
-/* period between periodic() commands, in seconds */
-
-int period = 0;
-
-/* != 0 means history is turned off (through !" or setopt nobanghist) */
-
-int stophist = 0;
-
-/* != 0 means we have removed the current event from the history list */
-
-int histremmed = 0;
-
-/* the options; e.g. if opts['a'] is nonzero, -a is turned on */
-
-int opts[128];
-
-/* LINENO */
-
-int lineno;
-
-/* != 0 means we have called execlist() and then intend to exit(),
-	so don't fork if not necessary */
-
-int exiting = 0;
-
-/* the limits for child processes */
-
-struct rlimit limits[RLIM_NLIMITS];
-
-/* the tokens */
-
-char *tokens = "#$^*()$=|{}[]`<>?~`,";
-
-/* the current word in the history list */
-
-char *hlastw;
-
-/* the pointer to the current character in the current word
-	in the history list */
-
-char *hlastp;
-
-/* the size of the current word in the history list */
-
-int hlastsz;
-
-/* the alias expansion status - if == ALSTAT_MORE, we just finished
-	expanding an alias ending with a space */
-
-int alstat;
-
-/* we have printed a 'you have stopped (running) jobs.' message */
-
-int stopmsg;
-
-/* the default tty state */
-
-struct ttyinfo shttyinfo;
-
-/* signal names */
-
-char *sigs[] = { "EXIT",
- "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", "EMT", "FPE", "KILL",
- "BUS", "SEGV", "SYS", "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP",
- "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", "XFSZ", "VTALRM", "PROF",
- "WINCH", "LOST", "USR1", "USR2", "ERR", "DEBUG"
-};
-
-/* signals that are trapped = 1, signals ignored =2 */
-
-int sigtrapped[SIGCOUNT+2];
-
End of vars.c
echo vars.pro 1>&2
sed 's/^-//' >vars.pro <<'End of vars.pro'
End of vars.pro
echo zhistory.c 1>&2
sed 's/^-//' >zhistory.c <<'End of zhistory.c'
-/*
-
-	zhistory.c - interface between readline an zsh's ideas of 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"
-#include "readline/history.h"
-
-/* bindings to make zsh and readline get along */
-
-static int histline;
-
-void using_history(void)
-{
-	histline = cev;
-}
-
-int where_history(void)
-{
-	return histline;
-}
-
-int history_set_pos(int pos)
-{
-	histline = pos;
-	return 0;
-}
-
-HIST_ENTRY *current_history(void)
-{
-table tab;
-char *str;
-HIST_ENTRY *he;
-
-	tab = quietgetevent(histline);
-	if (!tab)
-		return NULL;
-	str = makehlist(tab,0);
-	he = (HIST_ENTRY *) malloc(sizeof *he);
-	he->line = str;
-	he->data = NULL;
-	return he;
-}
-
-HIST_ENTRY *previous_history(void)
-{
-	if (histline == tfev)
-		return NULL;
-	histline--;
-	return current_history();
-}
-
-HIST_ENTRY *next_history(void)
-{
-	if (histline == cev)
-		return NULL;
-	histline++;
-	return current_history();
-}
-
-char *extracthistarg(int num)
-{
-Node n;
-
-	if (histlist->last == (Node) histlist ||
-			histlist->last->last == (Node) histlist)
-		return NULL;
-	n = ((table) (histlist->last->last))->first;
-	for (; n && num; num--,n = n->next);
-	if (!n)
-		return NULL;
-	return strdup(n->dat);
-}
-
End of zhistory.c
echo readline/chardefs.h 1>&2
sed 's/^-//' >readline/chardefs.h <<'End of readline/chardefs.h'
-/* chardefs.h -- Character definitions for readline. */
-#ifndef _CHARDEFS_
-
-#ifndef savestring
-#define savestring(x) (char *)strcpy (xmalloc (1 + strlen (x)), (x))
-#endif
-
-#ifndef whitespace
-#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
-#endif
-
-#ifdef CTRL
-#undef CTRL
-#endif
-
-/* Some character stuff. */
-#define control_character_threshold 0x020   /* smaller than this is control */
-#define meta_character_threshold 0x07f	    /* larger than this is Meta. */
-#define control_character_bit 0x40	    /* 0x000000, must be off. */
-#define meta_character_bit 0x080	    /* x0000000, must be on. */
-
-#define CTRL(c) ((c) & (~control_character_bit))
-#define META(c) ((c) | meta_character_bit)
-
-#define UNMETA(c) ((c) & (~meta_character_bit))
-#define UNCTRL(c) to_upper(((c)|control_character_bit))
-
-#define lowercase_p(c) (((c) > ('a' - 1) && (c) < ('z' + 1)))
-#define uppercase_p(c) (((c) > ('A' - 1) && (c) < ('Z' + 1)))
-
-#define pure_alphabetic(c) (lowercase_p(c) || uppercase_p(c))
-
-#ifndef to_upper
-#define to_upper(c) (lowercase_p(c) ? ((c) - 32) : (c))
-#define to_lower(c) (uppercase_p(c) ? ((c) + 32) : (c))
-#endif
-
-#define CTRL_P(c) ((c) < control_character_threshold)
-#define META_P(c) ((c) > meta_character_threshold)
-
-#define NEWLINE '\n'
-#define RETURN CTRL('M')
-#define RUBOUT 0x07f
-#define TAB '\t'
-#define ABORT_CHAR CTRL('G')
-#define PAGE CTRL('L')
-#define SPACE 0x020
-#define ESC CTRL('[')
-
-#endif  /* _CHARDEFS_ */
End of readline/chardefs.h
echo readline/emacs_keymap.c 1>&2
sed 's/^-//' >readline/emacs_keymap.c <<'End of readline/emacs_keymap.c'
-/* emacs_keymap.c -- the keymap for emacs_mode in readline (). */
-
-/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
-
-   This file is part of GNU Readline, a library for reading lines
-   of text with interactive input and history editing.
-
-   Readline is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 1, or (at your option) any
-   later version.
-
-   Readline is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline; see the file COPYING.  If not, write to the Free
-   Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifndef FILE
-#include <stdio.h>
-#endif /* FILE */
-
-#include "readline.h"
-
-/* An array of function pointers, one for each possible key.
-   If the type byte is ISKMAP, then the pointer is the address of
-   a keymap. */
-
-KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
-
-  /* Control keys. */
-  { ISFUNC, (Function *)0x0 },		/* Control-@ */
-  { ISFUNC, rl_beg_of_line },		/* Control-a */
-  { ISFUNC, rl_backward },		/* Control-b */
-  { ISFUNC, (Function *)0x0 },	/* Control-c */
-  { ISFUNC, rl_delete },		/* Control-d */
-  { ISFUNC, rl_end_of_line },		/* Control-e */
-  { ISFUNC, rl_forward },		/* Control-f */
-  { ISFUNC, rl_abort },			/* Control-g */
-  { ISFUNC, rl_rubout },		/* Control-h */  /* pjf */
-  { ISFUNC, rl_complete },		/* Control-i */
-  { ISFUNC, rl_newline },		/* Control-j */
-  { ISFUNC, rl_kill_line },		/* Control-k */
-  { ISFUNC, rl_clear_screen },		/* Control-l */
-  { ISFUNC, rl_newline },		/* Control-m */
-  { ISFUNC, rl_get_next_history },	/* Control-n */
-  { ISFUNC, (Function *)0x0 },		/* Control-o */
-  { ISFUNC, rl_get_previous_history },	/* Control-p */
-  { ISFUNC, rl_quoted_insert },		/* Control-q */
-  { ISFUNC, (Function *)0x0 }, /* Control-r */
-  { ISFUNC, (Function *)0x0 }, /* Control-s */
-  { ISFUNC, rl_transpose_chars },	/* Control-t */
-  { ISFUNC, rl_unix_line_discard },	/* Control-u */
-  { ISFUNC, rl_quoted_insert },		/* Control-v */
-  { ISFUNC, rl_unix_word_rubout },	/* Control-w */
-  { ISKMAP, (Function *)emacs_ctlx_keymap },	/* Control-x */
-  { ISFUNC, rl_yank },			/* Control-y */
-  { ISFUNC, (Function *)0x0 },		/* Control-z */
-  { ISKMAP, (Function *)emacs_meta_keymap }, /* Control-[ */
-  { ISFUNC, (Function *)0x0 },		/* Control-\ */
-  { ISFUNC, (Function *)0x0 },		/* Control-] */
-  { ISFUNC, (Function *)0x0 },		/* Control-^ */
-  { ISFUNC, rl_undo_command },		/* Control-_ */
-
-  /* The start of printing characters. */
-  { ISFUNC, rl_insert },	/* SPACE */
-  { ISFUNC, rl_insert },	/* ! */
-  { ISFUNC, rl_insert },	/* " */
-  { ISFUNC, rl_insert },	/* # */
-  { ISFUNC, rl_insert },	/* $ */
-  { ISFUNC, rl_insert },	/* % */
-  { ISFUNC, rl_insert },	/* & */
-  { ISFUNC, rl_insert },	/* ' */
-  { ISFUNC, rl_insert },	/* ( */
-  { ISFUNC, rl_insert },	/* ) */
-  { ISFUNC, rl_insert },	/* * */
-  { ISFUNC, rl_insert },	/* + */
-  { ISFUNC, rl_insert },	/* , */
-  { ISFUNC, rl_insert },	/* - */
-  { ISFUNC, rl_insert },	/* . */
-  { ISFUNC, rl_insert },	/* / */
-
-  /* Regular digits. */
-  { ISFUNC, rl_insert },	/* 0 */
-  { ISFUNC, rl_insert },	/* 1 */
-  { ISFUNC, rl_insert },	/* 2 */
-  { ISFUNC, rl_insert },	/* 3 */
-  { ISFUNC, rl_insert },	/* 4 */
-  { ISFUNC, rl_insert },	/* 5 */
-  { ISFUNC, rl_insert },	/* 6 */
-  { ISFUNC, rl_insert },	/* 7 */
-  { ISFUNC, rl_insert },	/* 8 */
-  { ISFUNC, rl_insert },	/* 9 */
-
-  /* A little more punctuation. */
-  { ISFUNC, rl_insert },	/* : */
-  { ISFUNC, rl_insert },	/* ; */
-  { ISFUNC, rl_insert },	/* < */
-  { ISFUNC, rl_insert },	/* = */
-  { ISFUNC, rl_insert },	/* > */
-  { ISFUNC, rl_insert },	/* ? */
-  { ISFUNC, rl_insert },	/* @ */
-
-  /* Uppercase alphabet. */
-  { ISFUNC, rl_insert },	/* A */
-  { ISFUNC, rl_insert },	/* B */
-  { ISFUNC, rl_insert },	/* C */
-  { ISFUNC, rl_insert },	/* D */
-  { ISFUNC, rl_insert },	/* E */
-  { ISFUNC, rl_insert },	/* F */
-  { ISFUNC, rl_insert },	/* G */
-  { ISFUNC, rl_insert },	/* H */
-  { ISFUNC, rl_insert },	/* I */
-  { ISFUNC, rl_insert },	/* J */
-  { ISFUNC, rl_insert },	/* K */
-  { ISFUNC, rl_insert },	/* L */
-  { ISFUNC, rl_insert },	/* M */
-  { ISFUNC, rl_insert },	/* N */
-  { ISFUNC, rl_insert },	/* O */
-  { ISFUNC, rl_insert },	/* P */
-  { ISFUNC, rl_insert },	/* Q */
-  { ISFUNC, rl_insert },	/* R */
-  { ISFUNC, rl_insert },	/* S */
-  { ISFUNC, rl_insert },	/* T */
-  { ISFUNC, rl_insert },	/* U */
-  { ISFUNC, rl_insert },	/* V */
-  { ISFUNC, rl_insert },	/* W */
-  { ISFUNC, rl_insert },	/* X */
-  { ISFUNC, rl_insert },	/* Y */
-  { ISFUNC, rl_insert },	/* Z */
-
-  /* Some more punctuation. */
-  { ISFUNC, rl_insert },	/* [ */
-  { ISFUNC, rl_insert },	/* \ */
-  { ISFUNC, rl_insert },	/* ] */
-  { ISFUNC, rl_insert },	/* ^ */
-  { ISFUNC, rl_insert },	/* _ */
-  { ISFUNC, rl_insert },	/* ` */
-
-  /* Lowercase alphabet. */
-  { ISFUNC, rl_insert },	/* a */
-  { ISFUNC, rl_insert },	/* b */
-  { ISFUNC, rl_insert },	/* c */
-  { ISFUNC, rl_insert },	/* d */
-  { ISFUNC, rl_insert },	/* e */
-  { ISFUNC, rl_insert },	/* f */
-  { ISFUNC, rl_insert },	/* g */
-  { ISFUNC, rl_insert },	/* h */
-  { ISFUNC, rl_insert },	/* i */
-  { ISFUNC, rl_insert },	/* j */
-  { ISFUNC, rl_insert },	/* k */
-  { ISFUNC, rl_insert },	/* l */
-  { ISFUNC, rl_insert },	/* m */
-  { ISFUNC, rl_insert },	/* n */
-  { ISFUNC, rl_insert },	/* o */
-  { ISFUNC, rl_insert },	/* p */
-  { ISFUNC, rl_insert },	/* q */
-  { ISFUNC, rl_insert },	/* r */
-  { ISFUNC, rl_insert },	/* s */
-  { ISFUNC, rl_insert },	/* t */
-  { ISFUNC, rl_insert },	/* u */
-  { ISFUNC, rl_insert },	/* v */
-  { ISFUNC, rl_insert },	/* w */
-  { ISFUNC, rl_insert },	/* x */
-  { ISFUNC, rl_insert },	/* y */
-  { ISFUNC, rl_insert },	/* z */
-
-  /* Final punctuation. */
-  { ISFUNC, rl_insert },	/* { */
-  { ISFUNC, rl_insert },	/* | */
-  { ISFUNC, rl_insert },	/* } */
-  { ISFUNC, rl_insert },	/* ~ */
-  { ISFUNC, rl_rubout }		/* RUBOUT */
-};
-
-KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
-
-  /* Meta keys.  Just like above, but the high bit is set. */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-@ */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-a */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-b */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-c */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-d */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-e */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-f */
-  { ISFUNC, rl_abort },		/* Meta-Control-g */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-h */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-i */
-  { ISFUNC, rl_vi_editing_mode }, /* Meta-Control-j */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-k */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-l */
-  { ISFUNC, rl_vi_editing_mode }, /* Meta-Control-m */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-n */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-o */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-p */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-q */
-  { ISFUNC, rl_revert_line },	/* Meta-Control-r */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-s */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-t */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-u */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-v */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-w */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-x */
-  { ISFUNC, rl_yank_nth_arg },	/* Meta-Control-y */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-z */
-
-  { ISFUNC, (Function *)0x0 },   /* Meta-Control-[ */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-\ */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-] */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-^ */
-  { ISFUNC, (Function *)0x0 },	/* Meta-Control-_ */
-
-  /* The start of printing characters. */
-  { ISFUNC, (Function *)rl_magic_space },	/* Meta-SPACE */
-  { ISFUNC, (Function *)0x0 },	/* Meta-! */
-  { ISFUNC, (Function *)0x0 },	/* Meta-" */
-  { ISFUNC, (Function *)0x0 },	/* Meta-# */
-  { ISFUNC, rl_check_spelling },	/* Meta-$ */
-  { ISFUNC, (Function *)0x0 },	/* Meta-% */
-  { ISFUNC, (Function *)0x0 },	/* Meta-& */
-  { ISFUNC, (Function *)0x0 },	/* Meta-' */
-  { ISFUNC, (Function *)0x0 },	/* Meta-( */
-  { ISFUNC, (Function *)0x0 },	/* Meta-) */
-  { ISFUNC, (Function *)0x0 },	/* Meta-* */
-  { ISFUNC, (Function *)0x0 },	/* Meta-+ */
-  { ISFUNC, (Function *)0x0 },	/* Meta-, */
-  { ISFUNC, rl_digit_argument }, /* Meta-- */
-  { ISFUNC, (Function *)0x0 },	/* Meta-. */
-  { ISFUNC, (Function *)0x0 },	/* Meta-/ */
-
-  /* Regular digits. */
-  { ISFUNC, rl_digit_argument }, /* Meta-0 */
-  { ISFUNC, rl_digit_argument }, /* Meta-1 */
-  { ISFUNC, rl_digit_argument }, /* Meta-2 */
-  { ISFUNC, rl_digit_argument }, /* Meta-3 */
-  { ISFUNC, rl_digit_argument }, /* Meta-4 */
-  { ISFUNC, rl_digit_argument }, /* Meta-5 */
-  { ISFUNC, rl_digit_argument }, /* Meta-6 */
-  { ISFUNC, rl_digit_argument }, /* Meta-7 */
-  { ISFUNC, rl_digit_argument }, /* Meta-8 */
-  { ISFUNC, rl_digit_argument }, /* Meta-9 */
-
-  /* A little more punctuation. */
-  { ISFUNC, (Function *)0x0 },		/* Meta-: */
-  { ISFUNC, (Function *)0x0 },		/* Meta-; */
-  { ISFUNC, rl_beginning_of_history },	/* Meta-< */
-  { ISFUNC, (Function *)0x0 },		/* Meta-= */
-  { ISFUNC, rl_end_of_history },	/* Meta-> */
-  { ISFUNC, rl_possible_completions },	/* Meta-? */
-  { ISFUNC, (Function *)0x0 },		/* Meta-@ */
-
-  /* Uppercase alphabet. */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-A */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-B */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-C */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-D */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-E */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-F */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-G */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-H */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-I */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-J */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-K */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-L */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-M */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-N */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-O */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-P */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-Q */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-R */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-S */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-T */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-U */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-V */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-W */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-X */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-Y */
-  { ISFUNC, rl_do_lowercase_version },	/* Meta-Z */
-
-  /* Some more punctuation. */
-  { ISFUNC, rl_function_key },	/* Meta-[ */
-  { ISFUNC, (Function *)0x0 },	/* Meta-\ */
-  { ISFUNC, (Function *)0x0 },	/* Meta-] */
-  { ISFUNC, (Function *)0x0 },	/* Meta-^ */
-  { ISFUNC, (Function *)0x0 },	/* Meta-_ */
-  { ISFUNC, (Function *)0x0 },	/* Meta-` */
-
-  /* Lowercase alphabet. */
-  { ISFUNC, (Function *)0x0 },	/* Meta-a */
-  { ISFUNC, rl_backward_word },	/* Meta-b */
-  { ISFUNC, rl_capitalize_word }, /* Meta-c */
-  { ISFUNC, rl_kill_word },	/* Meta-d */
-  { ISFUNC, (Function *)0x0 },	/* Meta-e */
-  { ISFUNC, rl_forward_word },	/* Meta-f */
-  { ISFUNC, (Function *)0x0 },	/* Meta-g */
-  { ISFUNC, (Function *)0x0 },	/* Meta-h */
-  { ISFUNC, (Function *)0x0 },	/* Meta-i */
-  { ISFUNC, (Function *)0x0 },	/* Meta-j */
-  { ISFUNC, (Function *)0x0 },	/* Meta-k */
-  { ISFUNC, rl_downcase_word },	/* Meta-l */
-  { ISFUNC, (Function *)0x0 },	/* Meta-m */
-  { ISFUNC, (Function *)0x0 },	/* Meta-n */
-  { ISFUNC, (Function *)0x0 },	/* Meta-o */
-  { ISFUNC, (Function *)0x0 },	/* Meta-p */
-  { ISFUNC, (Function *)0x0 },	/* Meta-q */
-  { ISFUNC, rl_revert_line },	/* Meta-r */
-  { ISFUNC, (Function *)0x0 },	/* Meta-s */
-  { ISFUNC, rl_transpose_words }, /* Meta-t */
-  { ISFUNC, rl_upcase_word },	/* Meta-u */
-  { ISFUNC, (Function *)0x0 },	/* Meta-v */
-  { ISFUNC, (Function *)0x0 },	/* Meta-w */
-  { ISFUNC, (Function *)0x0 },	/* Meta-x */
-  { ISFUNC, rl_yank_pop },	/* Meta-y */
-  { ISFUNC, (Function *)0x0 },	/* Meta-z */
-
-  /* Final punctuation. */
-  { ISFUNC, (Function *)0x0 },	/* Meta-{ */
-  { ISFUNC, (Function *)0x0 },	/* Meta-| */
-  { ISFUNC, (Function *)0x0 },	/* Meta-} */
-  { ISFUNC, (Function *)0x0 },	/* Meta-~ */
-  { ISFUNC, rl_backward_kill_word } /* Meta-rubout */
-};
-
-KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = {
-
-  /* Control keys. */
-  { ISFUNC, (Function *)0x0 },		/* Control-@ */
-  { ISFUNC, (Function *)0x0 },		/* Control-a */
-  { ISFUNC, (Function *)0x0 },		/* Control-b */
-  { ISFUNC, (Function *)0x0 },		/* Control-c */
-  { ISFUNC, (Function *)0x0 },		/* Control-d */
-  { ISFUNC, (Function *)0x0 },		/* Control-e */
-  { ISFUNC, (Function *)0x0 },		/* Control-f */
-  { ISFUNC, rl_abort },			/* Control-g */
-  { ISFUNC, (Function *)0x0 },		/* Control-h */
-  { ISFUNC, (Function *)0x0 },		/* Control-i */
-  { ISFUNC, (Function *)0x0 },		/* Control-j */
-  { ISFUNC, (Function *)0x0 },		/* Control-k */
-  { ISFUNC, (Function *)0x0 },		/* Control-l */
-  { ISFUNC, (Function *)0x0 },		/* Control-m */
-  { ISFUNC, (Function *)0x0 },		/* Control-n */
-  { ISFUNC, (Function *)0x0 },		/* Control-o */
-  { ISFUNC, (Function *)0x0 },		/* Control-p */
-  { ISFUNC, (Function *)0x0 },		/* Control-q */
-  { ISFUNC, rl_re_read_init_file },	/* Control-r */
-  { ISFUNC, (Function *)0x0 },		/* Control-s */
-  { ISFUNC, (Function *)0x0 },		/* Control-t */
-  { ISFUNC, rl_undo_command },		/* Control-u */
-  { ISFUNC, (Function *)0x0 },		/* Control-v */
-  { ISFUNC, (Function *)0x0 },		/* Control-w */
-  { ISFUNC, (Function *)0x0 },		/* Control-x */
-  { ISFUNC, (Function *)0x0 },		/* Control-y */
-  { ISFUNC, (Function *)0x0 },		/* Control-z */
-  { ISFUNC, (Function *)0x0 },		/* Control-[ */
-  { ISFUNC, (Function *)0x0 },		/* Control-\ */
-  { ISFUNC, (Function *)0x0 },		/* Control-] */
-  { ISFUNC, (Function *)0x0 },		/* Control-^ */
-  { ISFUNC, (Function *)0x0 },		/* Control-_ */
-
-  /* The start of printing characters. */
-  { ISFUNC, (Function *)0x0 },		/* SPACE */
-  { ISFUNC, (Function *)0x0 },		/* ! */
-  { ISFUNC, (Function *)0x0 },		/* " */
-  { ISFUNC, (Function *)0x0 },		/* # */
-  { ISFUNC, (Function *)0x0 },		/* $ */
-  { ISFUNC, (Function *)0x0 },		/* % */
-  { ISFUNC, (Function *)0x0 },		/* & */
-  { ISFUNC, (Function *)0x0 },		/* ' */
-  { ISFUNC, rl_start_kbd_macro },	/* ( */
-  { ISFUNC, rl_end_kbd_macro  },	/* ) */
-  { ISFUNC, (Function *)0x0 },		/* * */
-  { ISFUNC, (Function *)0x0 },		/* + */
-  { ISFUNC, (Function *)0x0 },		/* , */
-  { ISFUNC, (Function *)0x0 },		/* - */
-  { ISFUNC, (Function *)0x0 },		/* . */
-  { ISFUNC, (Function *)0x0 },		/* / */
-
-  /* Regular digits. */
-  { ISFUNC, (Function *)0x0 },		/* 0 */
-  { ISFUNC, (Function *)0x0 },		/* 1 */
-  { ISFUNC, (Function *)0x0 },		/* 2 */
-  { ISFUNC, (Function *)0x0 },		/* 3 */
-  { ISFUNC, (Function *)0x0 },		/* 4 */
-  { ISFUNC, (Function *)0x0 },		/* 5 */
-  { ISFUNC, (Function *)0x0 },		/* 6 */
-  { ISFUNC, (Function *)0x0 },		/* 7 */
-  { ISFUNC, (Function *)0x0 },		/* 8 */
-  { ISFUNC, (Function *)0x0 },		/* 9 */
-
-  /* A little more punctuation. */
-  { ISFUNC, (Function *)0x0 },	/* : */
-  { ISFUNC, (Function *)0x0 },	/* ; */
-  { ISFUNC, (Function *)0x0 },	/* < */
-  { ISFUNC, (Function *)0x0 },	/* = */
-  { ISFUNC, (Function *)0x0 },	/* > */
-  { ISFUNC, (Function *)0x0 },	/* ? */
-  { ISFUNC, (Function *)0x0 },	/* @ */
-
-  /* Uppercase alphabet. */
-  { ISFUNC, rl_do_lowercase_version },	/* A */
-  { ISFUNC, rl_do_lowercase_version },	/* B */
-  { ISFUNC, rl_do_lowercase_version },	/* C */
-  { ISFUNC, rl_do_lowercase_version },	/* D */
-  { ISFUNC, rl_do_lowercase_version },	/* E */
-  { ISFUNC, rl_do_lowercase_version },	/* F */
-  { ISFUNC, rl_do_lowercase_version },	/* G */
-  { ISFUNC, rl_do_lowercase_version },	/* H */
-  { ISFUNC, rl_do_lowercase_version },	/* I */
-  { ISFUNC, rl_do_lowercase_version },	/* J */
-  { ISFUNC, rl_do_lowercase_version },	/* K */
-  { ISFUNC, rl_do_lowercase_version },	/* L */
-  { ISFUNC, rl_do_lowercase_version },	/* M */
-  { ISFUNC, rl_do_lowercase_version },	/* N */
-  { ISFUNC, rl_do_lowercase_version },	/* O */
-  { ISFUNC, rl_do_lowercase_version },	/* P */
-  { ISFUNC, rl_do_lowercase_version },	/* Q */
-  { ISFUNC, rl_do_lowercase_version },	/* R */
-  { ISFUNC, rl_do_lowercase_version },	/* S */
-  { ISFUNC, rl_do_lowercase_version },	/* T */
-  { ISFUNC, rl_do_lowercase_version },	/* U */
-  { ISFUNC, rl_do_lowercase_version },	/* V */
-  { ISFUNC, rl_do_lowercase_version },	/* W */
-  { ISFUNC, rl_do_lowercase_version },	/* X */
-  { ISFUNC, rl_do_lowercase_version },	/* Y */
-  { ISFUNC, rl_do_lowercase_version },	/* Z */
-
-  /* Some more punctuation. */
-  { ISFUNC, (Function *)0x0 },		/* [ */
-  { ISFUNC, (Function *)0x0 },		/* \ */
-  { ISFUNC, (Function *)0x0 },		/* ] */
-  { ISFUNC, (Function *)0x0 },		/* ^ */
-  { ISFUNC, (Function *)0x0 },		/* _ */
-  { ISFUNC, (Function *)0x0 },		/* ` */
-
-  /* Lowercase alphabet. */
-  { ISFUNC, (Function *)0x0 },		/* a */
-  { ISFUNC, (Function *)0x0 },		/* b */
-  { ISFUNC, (Function *)0x0 },		/* c */
-  { ISFUNC, (Function *)0x0 },		/* d */
-  { ISFUNC, rl_call_last_kbd_macro },	/* e */
-  { ISFUNC, (Function *)0x0 },		/* f */
-  { ISFUNC, (Function *)0x0 },		/* g */
-  { ISFUNC, (Function *)0x0 },		/* h */
-  { ISFUNC, (Function *)0x0 },		/* i */
-  { ISFUNC, (Function *)0x0 },		/* j */
-  { ISFUNC, (Function *)0x0 },		/* k */
-  { ISFUNC, (Function *)0x0 },		/* l */
-  { ISFUNC, (Function *)0x0 },		/* m */
-  { ISFUNC, (Function *)0x0 },		/* n */
-  { ISFUNC, (Function *)0x0 },		/* o */
-  { ISFUNC, (Function *)0x0 },		/* p */
-  { ISFUNC, (Function *)0x0 },		/* q */
-  { ISFUNC, (Function *)0x0 },		/* r */
-  { ISFUNC, (Function *)0x0 },		/* s */
-  { ISFUNC, (Function *)0x0 },		/* t */
-  { ISFUNC, (Function *)0x0 },		/* u */
-  { ISFUNC, (Function *)0x0 },		/* v */
-  { ISFUNC, (Function *)0x0 },		/* w */
-  { ISFUNC, (Function *)0x0 },		/* x */
-  { ISFUNC, (Function *)0x0 },		/* y */
-  { ISFUNC, (Function *)0x0 },		/* z */
-
-  /* Final punctuation. */
-  { ISFUNC, (Function *)0x0 },		/* { */
-  { ISFUNC, (Function *)0x0 },		/* | */
-  { ISFUNC, (Function *)0x0 },		/* } */
-  { ISFUNC, (Function *)0x0 },		/* ~ */
-  { ISFUNC, rl_backward_kill_line }	/* RUBOUT */
-};
End of readline/emacs_keymap.c
echo readline/funmap.c 1>&2
sed 's/^-//' >readline/funmap.c <<'End of readline/funmap.c'
-/* funmap.c -- attach names to functions. */
-
-/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
-
-   This file is part of GNU Readline, a library for reading lines
-   of text with interactive input and history editing.
-
-   Readline is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 1, or (at your option) any
-   later version.
-
-   Readline is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline; see the file COPYING.  If not, write to the Free
-   Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#define STATIC_MALLOC
-#ifndef STATIC_MALLOC
-extern char *xmalloc (), *xrealloc ();
-#else
-static char *xmalloc (), *xrealloc ();
-#endif
-
-#ifndef FILE
-#include <stdio.h>
-#endif /* FILE */
-
-#include "readline.h"
-
-FUNMAP **funmap = (FUNMAP **)NULL;
-static int funmap_size = 0;
-static int funmap_entry = 0;
-
-static FUNMAP default_funmap[] = {
-  { "beginning-of-line", rl_beg_of_line },
-  { "backward-char", rl_backward },
-  { "delete-char", rl_delete },
-  { "end-of-line", rl_end_of_line },
-  { "forward-char", rl_forward },
-  { "accept-line", rl_newline },
-  { "kill-line", rl_kill_line },
-  { "clear-screen", rl_clear_screen },
-  { "next-history", rl_get_next_history },
-  { "previous-history", rl_get_previous_history },
-  { "quoted-insert", rl_quoted_insert },
-  { "transpose-chars", rl_transpose_chars },
-  { "unix-line-discard", rl_unix_line_discard },
-  { "unix-word-rubout", rl_unix_word_rubout },
-  { "yank", rl_yank },
-  { "yank-pop", rl_yank_pop },
-  { "yank-nth-arg", rl_yank_nth_arg },
-  { "backward-delete-char", rl_rubout },
-  { "backward-word", rl_backward_word },
-  { "kill-word", rl_kill_word },
-  { "forward-word", rl_forward_word },
-  { "tab-insert", rl_tab_insert },
-  { "backward-kill-word", rl_backward_kill_word },
-  { "backward-kill-line", rl_backward_kill_line },
-  { "transpose-words", rl_transpose_words },
-  { "digit-argument", rl_digit_argument },
-  { "complete", rl_complete },
-  { "possible-completions", rl_possible_completions },
-  { "do-lowercase-version", rl_do_lowercase_version },
-  { "digit-argument", rl_digit_argument },
-  { "universal-argument", rl_universal_argument },
-  { "abort", rl_abort },
-  { "undo", rl_undo_command },
-  { "upcase-word", rl_upcase_word },
-  { "downcase-word", rl_downcase_word },
-  { "capitalize-word", rl_capitalize_word },
-  { "revert-line", rl_revert_line },
-  { "beginning-of-history", rl_beginning_of_history },
-  { "end-of-history", rl_end_of_history },
-  { "self-insert", rl_insert },
-  { "start-kbd-macro", rl_start_kbd_macro },
-  { "end-kbd-macro", rl_end_kbd_macro },
-  { "re-read-init-file", rl_re_read_init_file },
-  { "history-expand", rl_magic_space },
-  { "check-spelling", rl_check_spelling },
-#ifdef VI_MODE
-  { "vi-movement-mode", rl_vi_movement_mode },
-  { "vi-insertion-mode", rl_vi_insertion_mode },
-  { "vi-arg-digit", rl_vi_arg_digit },
-  { "vi-prev-word", rl_vi_prev_word },
-  { "vi-next-word", rl_vi_next_word },
-  { "vi-char-search", rl_vi_char_search },
-  { "vi-editing-mode", rl_vi_editing_mode },
-  { "vi-eof-maybe", rl_vi_eof_maybe },
-  { "vi-append-mode", rl_vi_append_mode },
-  { "vi-put", rl_vi_put },
-  { "vi-append-eol", rl_vi_append_eol },
-  { "vi-insert-beg", rl_vi_insert_beg },
-  { "vi-delete", rl_vi_delete },
-  { "vi-comment", rl_vi_comment },
-  { "vi-first-print", rl_vi_first_print },
-  { "vi-fword", rl_vi_fword },
-  { "vi-fWord", rl_vi_fWord },
-  { "vi-bword", rl_vi_bword },
-  { "vi-bWord", rl_vi_bWord },
-  { "vi-eword", rl_vi_eword },
-  { "vi-eWord", rl_vi_eWord },
-  { "vi-end-word", rl_vi_end_word },
-  { "vi-change-case", rl_vi_change_case },
-  { "vi-match", rl_vi_match },
-  { "vi-bracktype", rl_vi_bracktype },
-  { "vi-change-char", rl_vi_change_char },
-  { "vi-yank-arg", rl_vi_yank_arg },
-  { "vi-search", rl_vi_search },
-  { "vi-search-again", rl_vi_search_again },
-  { "vi-dosearch", rl_vi_dosearch },
-  { "vi-subst", rl_vi_subst },
-  { "vi-overstrike", rl_vi_overstrike },
-  { "vi-overstrike-delete", rl_vi_overstrike_delete },
-  { "vi-replace, ", rl_vi_replace },
-  { "vi-column", rl_vi_column },
-  { "vi-delete-to", rl_vi_delete_to },
-  { "vi-change-to", rl_vi_change_to },
-  { "vi-yank-to", rl_vi_yank_to },
-  { "vi-complete", rl_vi_complete },
-#endif /* VI_MODE */
-
- {(char *)NULL, (Function *)NULL }
-};
-
-rl_add_funmap_entry (name, function)
-     char *name;
-     Function *function;
-{
-  if (funmap_entry + 2 >= funmap_size)
-    if (!funmap)
-      funmap = (FUNMAP **)xmalloc ((funmap_size = 80) * sizeof (FUNMAP *));
-    else
-      funmap =
-	(FUNMAP **)xrealloc (funmap, (funmap_size += 80) * sizeof (FUNMAP *));
-  
-  funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
-  funmap[funmap_entry]->name = name;
-  funmap[funmap_entry]->function = function;
-
-  funmap[++funmap_entry] = (FUNMAP *)NULL;
-}
-
-static int funmap_initialized = 0;
-
-/* Make the funmap contain all of the default entries. */
-rl_initialize_funmap ()
-{
-  register int i;
-
-  if (funmap_initialized)
-    return;
-
-  for (i = 0; default_funmap[i].name; i++)
-    rl_add_funmap_entry (default_funmap[i].name, default_funmap[i].function);
-
-  funmap_initialized = 1;
-}
-
-/* Things that mean `Control'. */
-char *possible_control_prefixes[] = {
-  "Control-", "C-", "CTRL-", (char *)NULL
-};
-
-char *possible_meta_prefixes[] = {
-  "Meta", "M-", (char *)NULL
-};
-
-#ifdef STATIC_MALLOC
-
-/* **************************************************************** */
-/*								    */
-/*			xmalloc and xrealloc ()		     	    */
-/*								    */
-/* **************************************************************** */
-
-static void memory_error_and_abort ();
-
-static char *
-xmalloc (bytes)
-     int bytes;
-{
-  char *temp = (char *)malloc (bytes);
-
-  if (!temp)
-    memory_error_and_abort ();
-  return (temp);
-}
-
-static char *
-xrealloc (pointer, bytes)
-     char *pointer;
-     int bytes;
-{
-  char *temp = (char *)realloc (pointer, bytes);
-
-  if (!temp)
-    memory_error_and_abort ();
-  return (temp);
-}
-
-static void
-memory_error_and_abort ()
-{
-  fprintf (stderr, "history: Out of virtual memory!\n");
-  abort ();
-}
-#endif /* STATIC_MALLOC */
End of readline/funmap.c
echo readline/history.h 1>&2
sed 's/^-//' >readline/history.h <<'End of readline/history.h'
-/* History.h -- the names of functions that you can call in history. */
-/* modified by pjf */
-
-typedef struct _hist_entry {
-  char *line;
-  char *data;
-} HIST_ENTRY;
-
-/* For convenience only.  You set this when interpreting history commands.
-   It is the logical offset of the first history element. */
-extern int tfev;
-#define history_base tfev
-
-/* Begin a session in which the history functions might be used.  This
-   just initializes the interactive variables. */
-extern void using_history ();
-
-/* Place STRING at the end of the history list.
-   The associated data field (if any) is set to NULL. */
-/* extern void add_history (); */
-
-/* Returns the number which says what history element we are now
-   looking at.  */
-extern int where_history ();
-  
-/* Set the position in the history list to POS. */
-int history_set_pos ();
-   
-/* Search for STRING in the history list, starting at POS, an
-   absolute index into the list.  DIR, if negative, says to search
-   backwards from POS, else forwards.
-   Returns the absolute index of the history element where STRING
-   was found, or -1 otherwise. */
-extern int history_search_pos ();
-
-/* A reasonably useless function, only here for completeness.  WHICH
-   is the magic number that tells us which element to delete.  The
-   elements are numbered from 0. */
-/* inline HIST_ENTRY *remove_history () {return NULL;} */
-
-/* Stifle the history list, remembering only MAX number of entries. */
-/* extern void stifle_history (); */
-
-/* Stop stifling the history.  This returns the previous amount the
-   history was stifled by.  The value is positive if the history was
-   stifled, negative if it wasn't. */
-/* extern int unstifle_history (); */
-
-/* Add the contents of FILENAME to the history list, a line at a time.
-   If FILENAME is NULL, then read from ~/.history.  Returns 0 if
-   successful, or errno if not. */
-/* extern int read_history (); */
-
-/* Append the current history to FILENAME.  If FILENAME is NULL,
-   then append the history list to ~/.history.  Values returned
-   are as in read_history ().  */
-/* extern int write_history (); */
-
-
-/* Make the history entry at WHICH have LINE and DATA.  This returns
-   the old entry so you can dispose of the data.  In the case of an
-   invalid WHICH, a NULL pointer is returned. */
-/* extern HIST_ENTRY *replace_history_entry (); */
-
-/* Return the history entry at the current position, as determined by
-   history_offset.  If there is no entry there, return a NULL pointer. */
-HIST_ENTRY *current_history ();
-
-/* Back up history_offset to the previous history entry, and return
-   a pointer to that entry.  If there is no previous entry, return
-   a NULL pointer. */
-extern HIST_ENTRY *previous_history ();
-
-/* Move history_offset forward to the next item in the input_history,
-   and return the a pointer to that entry.  If there is no next entry,
-   return a NULL pointer. */
-extern HIST_ENTRY *next_history ();
-
-/* Return a NULL terminated array of HIST_ENTRY which is the current input
-   history.  Element 0 of this list is the beginning of time.  If there
-   is no history, return NULL. */
-/*extern HIST_ENTRY **history_list ();*/
-
-/* Search the history for STRING, starting at history_offset.
-   If DIRECTION < 0, then the search is through previous entries,
-   else through subsequent.  If the string is found, then
-   current_history () is the history entry, and the value of this function
-   is the offset in the line of that history entry that the string was
-   found in.  Otherwise, nothing is changed, and a -1 is returned. */
-/* extern int history_search (); */
-
-/* Expand the string STRING, placing the result into OUTPUT, a pointer
-   to a string.  Returns:
-
-   0) If no expansions took place (or, if the only change in
-      the text was the de-slashifying of the history expansion
-      character)
-   1) If expansions did take place
-  -1) If there was an error in expansion.
-
-  If an error ocurred in expansion, then OUTPUT contains a descriptive
-  error message. */
-/*extern int history_expand ();*/
-
-/* Extract a string segment consisting of the FIRST through LAST
-   arguments present in STRING.  Arguments are broken up as in
-   the shell. pjf: only 1-segment strings are supported.  */
-extern char *history_arg_extract ();
-
-
End of readline/history.h
echo readline/keymaps.c 1>&2
sed 's/^-//' >readline/keymaps.c <<'End of readline/keymaps.c'
-/* keymaps.c -- Functions and keymaps for the GNU Readline library. */
-
-/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
-
-   This file is part of GNU Readline, a library for reading lines
-   of text with interactive input and history editing.
-
-   Readline is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 1, or (at your option) any
-   later version.
-
-   Readline is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline; see the file COPYING.  If not, write to the Free
-   Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#include "keymaps.h"
-#include "emacs_keymap.c"
-
-#ifdef VI_MODE
-#include "vi_keymap.c"
-#endif
-
-/* Remove these declarations when we have a complete libgnu.a. */
-#define STATIC_MALLOC
-#ifndef STATIC_MALLOC
-extern char *xmalloc (), *xrealloc ();
-#else
-static char *xmalloc (), *xrealloc ();
-#endif
-
-/* **************************************************************** */
-/*								    */
-/*		      Functions for manipulating Keymaps.	    */
-/*								    */
-/* **************************************************************** */
-
-
-/* Return a new, empty keymap.
-   Free it with free() when you are done. */
-Keymap
-rl_make_bare_keymap ()
-{
-  register int i;
-  Keymap keymap = (Keymap)xmalloc (128 * sizeof (KEYMAP_ENTRY));
-
-  for (i = 0; i < 128; i++)
-    {
-      keymap[i].type = ISFUNC;
-      keymap[i].function = (Function *)NULL;
-    }
-
-  for (i = 'A'; i < ('Z' + 1); i++)
-    {
-      keymap[i].type = ISFUNC;
-      keymap[i].function = rl_do_lowercase_version;
-    }
-
-  return (keymap);
-}
-
-/* Return a new keymap which is a copy of MAP. */
-Keymap
-rl_copy_keymap (map)
-     Keymap map;
-{
-  register int i;
-  Keymap temp = rl_make_bare_keymap ();
-
-  for (i = 0; i < 128; i++)
-    {
-      temp[i].type = map[i].type;
-      temp[i].function = map[i].function;
-    }
-  return (temp);
-}
-
-/* Return a new keymap with the printing characters bound to rl_insert,
-   the uppercase Meta characters bound to run their lowercase equivalents,
-   and the Meta digits bound to produce numeric arguments. */
-Keymap
-rl_make_keymap ()
-{
-  extern rl_insert (), rl_rubout (), rl_do_lowercase_version ();
-  extern rl_digit_argument ();
-  register int i;
-  Keymap newmap;
-
-  newmap = rl_make_bare_keymap ();
-
-  /* All printing characters are self-inserting. */
-  for (i = ' '; i < 126; i++)
-    newmap[i].function = rl_insert;
-
-  newmap[TAB].function = rl_insert;
-  newmap[RUBOUT].function = rl_rubout;
-
-  return (newmap);
-}
-
-/* Free the storage associated with MAP. */
-rl_discard_keymap (map)
-     Keymap (map);
-{
-  int i;
-
-  if (!map)
-    return;
-
-  for (i = 0; i < 128; i++)
-    {
-      switch (map[i].type)
-	{
-	case ISFUNC:
-	  break;
-
-	case ISKMAP:
-	  rl_discard_keymap ((Keymap)map[i].function);
-	  break;
-
-	case ISMACR:
-	  free ((char *)map[i].function);
-	  break;
-	}
-    }
-}
-
-#ifdef STATIC_MALLOC
-
-/* **************************************************************** */
-/*								    */
-/*			xmalloc and xrealloc ()		     	    */
-/*								    */
-/* **************************************************************** */
-
-static void memory_error_and_abort ();
-
-static char *
-xmalloc (bytes)
-     int bytes;
-{
-  char *temp = (char *)malloc (bytes);
-
-  if (!temp)
-    memory_error_and_abort ();
-  return (temp);
-}
-
-static char *
-xrealloc (pointer, bytes)
-     char *pointer;
-     int bytes;
-{
-  char *temp = (char *)realloc (pointer, bytes);
-
-  if (!temp)
-    memory_error_and_abort ();
-  return (temp);
-}
-
-static void
-memory_error_and_abort ()
-{
-  fprintf (stderr, "readline: Out of virtual memory!\n");
-  abort ();
-}
-#endif /* STATIC_MALLOC */
End of readline/keymaps.c
echo readline/keymaps.h 1>&2
sed 's/^-//' >readline/keymaps.h <<'End of readline/keymaps.h'
-/* keymaps.h -- Manipulation of readline keymaps. */
-
-#ifndef _KEYMAPS_H_
-#define _KEYMAPS_H_
-
-#include <readline/chardefs.h>
-
-#ifndef __FUNCTION_DEF
-typedef int Function ();
-#define __FUNCTION_DEF
-#endif
-
-/* A keymap contains one entry for each key in the ASCII set.
-   Each entry consists of a type and a pointer.
-   POINTER is the address of a function to run, or the
-   address of a keymap to indirect through.
-   TYPE says which kind of thing POINTER is. */
-typedef struct _keymap_entry {
-  char type;
-  Function *function;
-} KEYMAP_ENTRY;
-
-/* I wanted to make the above structure contain a union of:
-   union { Function *function; struct _keymap_entry *keymap; } value;
-   but this made it impossible for me to create a static array.
-   Maybe I need C lessons. */
-
-typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[128];
-typedef KEYMAP_ENTRY *Keymap;
-
-/* The values that TYPE can have in a keymap entry. */
-#define ISFUNC 0
-#define ISKMAP 1
-#define ISMACR 2
-
-extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_meta_keymap, emacs_ctlx_keymap;
-extern KEYMAP_ENTRY_ARRAY vi_insertion_keymap, vi_movement_keymap;
-
-/* Return a new, empty keymap.
-   Free it with free() when you are done. */
-Keymap rl_make_bare_keymap ();
-
-/* Return a new keymap which is a copy of MAP. */
-Keymap rl_copy_keymap ();
-
-/* Return a new keymap with the printing characters bound to rl_insert,
-   the lowercase Meta characters bound to run their equivalents, and
-   the Meta digits bound to produce numeric arguments. */
-Keymap rl_make_keymap ();
-
-#endif /* _KEYMAPS_H_ */
-
-
End of readline/keymaps.h
echo readline/readline.c 1>&2
sed 's/^-//' >readline/readline.c <<'End of readline/readline.c'
-/* readline.c -- a general facility for reading lines of input
-   with emacs style editing and completion. */
-
-/* Copyright (C) 1987,1989 Free Software Foundation, Inc.
-
-   This file contains the Readline Library (the Library), a set of
-   routines for providing Emacs style line input to programs that ask
-   for it.
-
-   The Library is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 1, or (at your option)
-   any later version.
-
-   The Library is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   The GNU General Public License is often shipped with GNU software, and
-   is generally kept in a file called COPYING or LICENSE.  If you do not
-   have a copy of the license, write to the Free Software Foundation,
-   675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* Remove these declarations when we have a complete libgnu.a. */
-#define STATIC_MALLOC
-#ifndef STATIC_MALLOC
-extern char *xmalloc (), *xrealloc ();
-#else
-static char *xmalloc (), *xrealloc ();
-#endif
-
-char *docompsubs();
-extern int errno,errflag;
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/file.h>
-#include <sys/param.h>
-#include <signal.h>
-
-#ifdef __GNUC__
-#define alloca __builtin_alloca
-#else
-#if defined (sparc) && defined (sun)
-#include <alloca.h>
-#endif
-#endif
-
-#define NEW_TTY_DRIVER
-#if defined (SYSV) || defined (hpux)
-#undef NEW_TTY_DRIVER
-#include <termio.h>
-#else
-#include <sgtty.h>
-#endif
-
-#include <errno.h>
-extern int errno;
-
-#include <setjmp.h>
-
-/* These next are for filename completion.  Perhaps this belongs
-   in a different place. */
-#include <sys/stat.h>
-
-#include <pwd.h>
-#ifdef SYSV
-struct passwd *getpwuid (), *getpwent ();
-#endif
-
-#define HACK_TERMCAP_MOTION
-
-#ifndef SYSV
-#include <sys/dir.h>
-#else  /* SYSV */
-#if defined (xenix)
-#include <sys/ndir.h>
-#else
-#ifdef hpux
-#include <ndir.h>
-#else
-#include <dirent.h>
-#define direct dirent
-#define d_namlen d_reclen
-#endif  /* hpux */
-#endif  /* xenix */
-#endif  /* SYSV */
-
-#ifndef O_CBREAK
-#define O_CBREAK CBREAK
-#define O_ECHO ECHO
-#define O_RAW RAW
-#endif
-
-/* Some standard library routines. */
-#include "readline.h"
-#include "history.h"
-
-#ifndef digit
-#define digit(c)  ((c) >= '0' && (c) <= '9')
-#endif
-
-#ifndef isletter
-#define isletter(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z'))
-#endif
-
-#ifndef digit_value
-#define digit_value(c) ((c) - '0')
-#endif
-
-#ifndef member
-char *index ();
-#define member(c, s) ((c) ? index ((s), (c)) : 0)
-#endif
-
-#ifndef isident
-#define isident(c) ((isletter(c) || digit(c) || c == '_'))
-#endif
-
-#ifndef exchange
-#define exchange(x, y) {int temp = x; x = y; y = temp;}
-#endif
-
-static update_line ();
-static void output_character_function ();
-static delete_chars ();
-static delete_chars ();
-static insert_some_chars ();
-
-void rl_safe_insert_text();
-
-#ifdef VOID_SIGHANDLER
-#define sighandler void
-#else
-#define sighandler int
-#endif
-
-/* This typedef is equivalant to the one for Function; it allows us
-   to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
-typedef sighandler SigHandler ();
-
-#ifdef SIGWINCH
-static sighandler rl_handle_sigwinch ();
-static SigHandler *old_sigwinch = (SigHandler *)NULL;
-#endif
-
-/* If on, then readline handles signals in a way that doesn't screw. */
-#define HANDLE_SIGNALS
-
-#if defined (SYSV)
-#ifdef HANDLE_SIGNALS
-#undef HANDLE_SIGNALS
-#endif
-#endif
-
-
-/* **************************************************************** */
-/*                                                                  */
-/*                      Line editing input utility                  */
-/*                                                                  */
-/* **************************************************************** */
-
-/* A pointer to the keymap that is currently in use.
-   By default, it is the standard emacs keymap. */
-Keymap keymap = emacs_standard_keymap;
-
-#define vi_mode 0
-#define emacs_mode 1
-
-/* The current style of editing. */
-int rl_editing_mode = emacs_mode;
-
-/* Non-zero if the previous command was a kill command. */
-static int last_command_was_kill = 0;
-
-/* The current value of the numeric argument specified by the user. */
-int rl_numeric_arg = 1;
-
-/* Non-zero if an argument was typed. */
-int rl_explicit_arg = 0;
-
-/* Temporary value used while generating the argument. */
-static int arg_sign = 1;
-
-/* Non-zero means we have been called at least once before. */
-static int rl_initialized = 0;
-
-/* If non-zero, this program is running in an EMACS buffer. */
-static char *running_in_emacs = (char *)NULL;
-
-/* The current offset in the current input line. */
-int rl_point;
-
-/* Mark in the current input line. */
-int rl_mark;
-
-/* Length of the current input line. */
-int rl_end;
-
-/* Make this non-zero to return the current input_line. */
-int rl_done;
-
-/* The last function executed by readline. */
-Function *rl_last_func = (Function *)NULL;
-
-/* Top level environment for readline_internal (). */
-static jmp_buf readline_top_level;
-
-/* The streams we interact with. */
-static FILE *in_stream, *out_stream;
-
-/* The names of the streams that we do input and output to. */
-FILE *rl_instream = stdin, *rl_outstream = stdout;
-
-/* Non-zero means echo characters as they are read. */
-int readline_echoing_p = 1;
-
-/* Current prompt. */
-char *rl_prompt;
-
-/* The number of characters read in order to type this complete command. */
-int rl_key_sequence_length = 0;
-
-/* 1 means the line editor is active. */
-int rl_active = 0;
-
-/* 1 means we are waiting for a character. */
-int rl_waiting = 0;
-
-/* If non-zero, then this is the address of a function to call just
-   before readline_internal () prints the first prompt. */
-Function *rl_startup_hook = (Function *)NULL;
-
-/* What we use internally.  You should always refer to RL_LINE_BUFFER. */
-static char *the_line;
-
-/* The character that can generate an EOF.  Really read from
-   the terminal driver... just defaulted here. */
-static int eof_char = CTRL ('D');
-
-/* Non-zero makes this the next keystroke to read. */
-int rl_pending_input = 0;
-
-/* Pointer to a useful terminal name. */
-char *rl_terminal_name = (char *)NULL;
-
-/* Line buffer and maintenence. */
-char *rl_line_buffer = (char *)NULL;
-static int rl_line_buffer_len = 0;
-#define DEFAULT_BUFFER_SIZE 256
-
-
-/* **************************************************************** */
-/*                                                                  */
-/*                      `Forward' declarations                      */
-/*                                                                  */
-/* **************************************************************** */
-
-/* Non-zero means do not parse any lines other than comments and
-   parser directives. */
-static unsigned char parsing_conditionalized_out = 0;
-
-/* Caseless strcmp (). */
-static int stricmp (), strnicmp ();
-
-/* Non-zero means to save keys that we dispatch on in a kbd macro. */
-static int defining_kbd_macro = 0;
-
-
-/* **************************************************************** */
-/*                                                                  */
-/*                      Top Level Functions                         */
-/*                                                                  */
-/* **************************************************************** */
-
-/* Read a line of input.  Prompt with PROMPT.  A NULL PROMPT means
-   none.  A return value of NULL means that EOF was encountered. */
-char *
-readline (prompt)
-char *prompt;
-{
-	int rl_prep_terminal (), rl_deprep_terminal ();
-	char *readline_internal ();
-	char *value;
-
-	rl_prompt = prompt;
-
-	/* If we are at EOF return a NULL string. */
-	if (rl_pending_input == EOF)
-	{
-		rl_pending_input = 0;
-		return ((char *)NULL);
-	}
-
-	rl_initialize ();
-	rl_prep_terminal ();
-
-#ifdef SIGWINCH
-	old_sigwinch = (SigHandler *)signal (SIGWINCH, rl_handle_sigwinch);
-#endif
-
-#ifdef HANDLE_SIGNALS
-	rl_set_signals ();
-#endif
-
-	rl_active = 1;
-	rl_waiting = 0;
-	value = readline_internal ();
-	rl_active = 0;
-	rl_deprep_terminal ();
-
-#ifdef SIGWINCH
-	signal (SIGWINCH, old_sigwinch);
-#endif
-
-#ifdef HANDLE_SIGNALS
-	rl_clear_signals ();
-#endif
-
-	return (value);
-}
-
-/* Read a line of input from the global rl_instream, doing output on
-   the global rl_outstream.
-   If rl_prompt is non-null, then that is our prompt. */
-char *
-readline_internal ()
-{
-	int lastc, c, eof_found;
-
-	in_stream = rl_instream; 
-	out_stream = rl_outstream;
-	lastc = eof_found = 0;
-
-	if (rl_startup_hook)
-		(*rl_startup_hook) ();
-
-	if (!readline_echoing_p)
-	{
-		if (rl_prompt)
-		{
-			fprintf (out_stream, "%s", rl_prompt);
-			fflush (out_stream);
-		}
-	}
-	else
-	{
-		rl_on_new_line ();
-		rl_redisplay ();
-#ifdef VI_MODE
-		if (rl_editing_mode == vi_mode)
-			rl_vi_insertion_mode ();
-#endif /* VI_MODE */
-	}
-
-	while (!rl_done)
-	{
-		int lk = last_command_was_kill;
-		int code = setjmp (readline_top_level);
-
-		if (code)
-			rl_redisplay ();
-
-		if (!rl_pending_input)
-		{
-			/* Then initialize the argument and number of keys read. */
-			rl_init_argument ();
-			rl_key_sequence_length = 0;
-		}
-
-		c = rl_read_key ();
-		if (c == EOF)
-			{
-			eof_found = 1;
-			putc('\n',stderr);
-			break;
-			}
-
-		/* EOF typed to a non-blank line is a <NL>. */
-		if (c == EOF && rl_end)
-			c = NEWLINE;
-
-		if (errflag)
-		{
-			eof_found = 1;
-			break;
-		}
-
-		/* The character eof_char typed to blank line, and not as the
-	 previous character is interpreted as EOF. */
-		if (((c == eof_char && lastc != c) || c == EOF) && !rl_end)
-		{
-			eof_found = 1;
-			break;
-		}
-
-		lastc = c;
-		rl_dispatch (c, keymap);
-
-		/* If there was no change in last_command_was_kill, then no kill
-	 has taken place.  Note that if input is pending we are reading
-	 a prefix command, so nothing has changed yet. */
-		if (!rl_pending_input)
-		{
-			if (lk == last_command_was_kill)
-				last_command_was_kill = 0;
-		}
-
-#ifdef VI_MODE
-		/* In vi mode, when you exit insert mode, the cursor moves back
-	 over the previous character.  We explicitly check for that here. */
-		if (rl_editing_mode == vi_mode && keymap == vi_movement_keymap)
-			rl_vi_check ();
-#endif
-		if (!rl_done)
-			rl_redisplay ();
-	}
-
-	/* Restore the original of this history line, iff the line that we
-     are editing was originally in the history, AND the line has changed. */
-	{
-		HIST_ENTRY *entry = current_history ();
-
-		if (entry && rl_undo_list)
-		{
-			char *temp = savestring (the_line);
-			rl_revert_line ();
-			free_history_entry (entry);
-
-			strcpy (the_line, temp);
-			free (temp);
-		}
-	}
-
-	/* At any rate, it is highly likely that this line has an undo list.  Get
-     rid of it now. */
-	if (rl_undo_list)
-		free_undo_list ();
-
-	if (eof_found)
-		return (char *)NULL;
-	else
-		return (savestring (the_line));
-}
-
-
-/* **************************************************************** */
-/*					        		    */
-/*			   Signal Handling                          */
-/*								    */
-/* **************************************************************** */
-
-#ifdef SIGWINCH
-static sighandler
-rl_handle_sigwinch (sig, code, scp)
-int sig, code;
-struct sigcontext *scp;
-{
-	char *term = rl_terminal_name, *getenv ();
-
-	if (readline_echoing_p)
-	{
-		if (!term)
-			term = getenv ("TERM");
-		if (!term)
-			term = "dumb";
-		rl_reset_terminal (term);
-#ifdef NEVER
-		crlf ();
-		rl_forced_update_display ();
-#endif
-	}
-
-	if (old_sigwinch &&
-	    old_sigwinch != (SigHandler *)SIG_IGN &&
-	    old_sigwinch != (SigHandler *)SIG_DFL)
-		(*old_sigwinch)(sig, code, scp);
-}
-#endif  /* SIGWINCH */
-
-#ifdef HANDLE_SIGNALS
-/* Interrupt handling. */
-static SigHandler *old_int  = (SigHandler *)NULL,
-*old_tstp = (SigHandler *)NULL,
-*old_ttou = (SigHandler *)NULL,
-*old_ttin = (SigHandler *)NULL,
-*old_cont = (SigHandler *)NULL;
-
-/* Handle an interrupt character. */
-static sighandler
-rl_signal_handler (sig, code, scp)
-int sig, code;
-struct sigcontext *scp;
-{
-	rl_prep_terminal (), rl_deprep_terminal ();
-
-	switch (sig)
-	{
-	case SIGINT:
-		free_undo_list ();
-		rl_clear_message ();
-		rl_init_argument ();
-#ifdef SIGWINCH
-		signal (SIGWINCH, old_sigwinch);
-#endif
-
-#ifdef SIGTSTP
-	case SIGTSTP:
-	case SIGTTOU:
-	case SIGTTIN:
-#endif
-
-		rl_clean_up_for_exit ();
-		rl_deprep_terminal ();
-		rl_clear_signals ();
-		rl_pending_input = 0;
-
-		kill (getpid (), sig);
-		sigsetmask (0);
-
-		rl_prep_terminal ();
-		rl_set_signals ();
-	}
-}
-
-rl_set_signals ()
-{
-	old_int = (SigHandler *)signal (SIGINT, rl_signal_handler);
-	if (old_int == (SigHandler *)SIG_IGN)
-		signal (SIGINT, SIG_IGN);
-
-#ifdef SIGTSTP
-	old_tstp = (SigHandler *)signal (SIGTSTP, rl_signal_handler);
-	if (old_tstp == (SigHandler *)SIG_IGN)
-		signal (SIGTSTP, SIG_IGN);
-#endif
-#ifdef SIGTTOU
-	old_ttou = (SigHandler *)signal (SIGTTOU, rl_signal_handler);
-	old_ttin = (SigHandler *)signal (SIGTTIN, rl_signal_handler);
-
-	if (old_tstp == (SigHandler *)SIG_IGN)
-	{
-		signal (SIGTTOU, SIG_IGN);
-		signal (SIGTTIN, SIG_IGN);
-	}
-#endif
-}
-
-rl_clear_signals ()
-{
-	signal (SIGINT, old_int);
-
-#ifdef SIGTSTP
-	signal (SIGTSTP, old_tstp);
-#endif
-#ifdef SIGTTOU
-	signal (SIGTTOU, old_ttou);
-	signal (SIGTTIN, old_ttin);
-#endif
-}
-#endif  /* HANDLE_SIGNALS */
-
-
-/* **************************************************************** */
-/*								    */
-/*			Character Input Buffering       	    */
-/*								    */
-/* **************************************************************** */
-
-/* If the terminal was in xoff state when we got to it, then xon_char
-   contains the character that is supposed to start it again. */
-static int xon_char, xoff_state;
-static int pop_index = 0, push_index = 0, ibuffer_len = 511;
-static unsigned char ibuffer[512];
-
-/* Non-null means it is a pointer to a function to run while waiting for
-   character input. */
-Function *rl_event_hook = (Function *)NULL;
-
-#define any_typein (push_index != pop_index)
-
-/* Add KEY to the buffer of characters to be read. */
-rl_stuff_char (key)
-int key;
-{
-	if (key == EOF)
-	{
-		key = NEWLINE;
-		rl_pending_input = EOF;
-	}
-	ibuffer[push_index++] = key;
-	if (push_index >= ibuffer_len)
-		push_index = 0;
-}
-
-/* Return the amount of space available in the
-   buffer for stuffing characters. */
-int
-ibuffer_space ()
-{
-	if (pop_index > push_index)
-		return (pop_index - push_index);
-	else
-		return (ibuffer_len - (push_index - pop_index));
-}
-
-/* Get a key from the buffer of characters to be read.
-   Return the key in KEY.
-   Result is KEY if there was a key, or 0 if there wasn't. */
-int
-rl_get_char (key)
-int *key;
-{
-	if (push_index == pop_index)
-		return (0);
-
-	*key = ibuffer[pop_index++];
-
-	if (pop_index >= ibuffer_len)
-		pop_index = 0;
-
-	return (1);
-}
-
-/* Stuff KEY into the *front* of the input buffer.
-   Returns non-zero if successful, zero if there is
-   no space left in the buffer. */
-int
-rl_unget_char (key)
-int key;
-{
-	if (ibuffer_space ())
-	{
-		pop_index--;
-		if (pop_index < 0)
-			pop_index = ibuffer_len - 1;
-		ibuffer[pop_index] = key;
-		return (1);
-	}
-	return (0);
-}
-
-/* If a character is available to be read, then read it
-   and stuff it into IBUFFER.  Otherwise, just return. */
-rl_gather_tyi ()
-{
-	int tty = fileno (in_stream);
-	register int tem, result = -1;
-	long chars_avail;
-	char input;
-
-#ifdef FIONREAD
-	result = ioctl (tty, FIONREAD, &chars_avail);
-#endif
-
-	if (result == -1)
-	{
-		fcntl (tty, F_SETFL, O_NDELAY);
-		chars_avail = read (tty, &input, 1);
-		fcntl (tty, F_SETFL, 0);
-		if (chars_avail == -1 && errno == EAGAIN)
-			return;
-	}
-
-	tem = ibuffer_space ();
-
-	if (chars_avail > tem)
-		chars_avail = tem;
-
-	/* One cannot read all of the available input.  I can only read a single
-     character at a time, or else programs which require input can be
-     thwarted.  If the buffer is larger than one character, I lose.
-     Damn! */
-	if (tem < ibuffer_len)
-		chars_avail = 0;
-
-	if (result != -1)
-	{
-		while (chars_avail--)
-			rl_stuff_char (rl_getc (in_stream));
-	}
-	else
-	{
-		if (chars_avail)
-			rl_stuff_char (input);
-	}
-}
-
-/* Read a key, including pending input. */
-int
-rl_read_key ()
-{
-	int c;
-
-	rl_key_sequence_length++;
-
-	if (rl_pending_input)
-	{
-		c = rl_pending_input;
-		rl_pending_input = 0;
-	}
-	else
-	{
-		static int next_macro_key ();
-
-		/* If input is coming from a macro, then use that. */
-		if (c = next_macro_key ())
-			return (c);
-
-		/* If the user has an event function, then call it periodically. */
-		if (rl_event_hook)
-		{
-			while (rl_event_hook && !rl_get_char (&c))
-			{
-				(*rl_event_hook) ();
-				rl_gather_tyi ();
-			}
-		}
-		else
-		{
-			if (!rl_get_char (&c))
-				c = rl_getc (in_stream);
-		}
-	}
-
-#ifdef NEVER  /* This breaks supdup to 4.0.3c machines. */
-#ifdef TIOCSTART
-	/* Ugh.  But I can't think of a better way. */
-	if (xoff_state && c == xon_char)
-	{
-		ioctl (fileno (in_stream), TIOCSTART, 0);
-		xoff_state = 0;
-		return (rl_read_key ());
-	}
-#endif /* TIOCSTART */
-#endif
-
-	return (c);
-}
-
-/* I'm beginning to hate the declaration rules for various compilers. */
-static void add_macro_char ();
-
-/* Do the command associated with KEY in MAP.
-   If the associated command is really a keymap, then read
-   another key, and dispatch into that map. */
-rl_dispatch (key, map)
-register int key;
-Keymap map;
-{
-
-	if (defining_kbd_macro)
-		add_macro_char (key);
-
-	if (key > 127 && key < 256)
-	{
-		if (map[ESC].type == ISKMAP)
-		{
-			map = (Keymap)map[ESC].function;
-			key -= 128;
-			rl_dispatch (key, map);
-		}
-		else
-			ding ();
-		return;
-	}
-
-	switch (map[key].type)
-	{
-	case ISFUNC:
-		{
-			Function *func = map[key].function;
-
-			if (func != (Function *)NULL)
-			{
-				/* Special case rl_do_lowercase_version (). */
-				if (func == rl_do_lowercase_version)
-				{
-					rl_dispatch (to_lower (key), map);
-					return;
-				}
-
-				(*map[key].function)(rl_numeric_arg * arg_sign, key);
-			}
-			else
-			{
-				ding ();
-				return;
-			}
-		}
-		break;
-
-	case ISKMAP:
-		if (map[key].function != (Function *)NULL)
-		{
-			int newkey;
-
-			rl_key_sequence_length++;
-			newkey = rl_read_key ();
-			rl_dispatch (newkey, (Keymap)map[key].function);
-		}
-		else
-		{
-			ding ();
-			return;
-		}
-		break;
-
-	case ISMACR:
-		if (map[key].function != (Function *)NULL)
-		{
-			static with_macro_input ();
-			char *macro = savestring ((char *)map[key].function);
-
-			with_macro_input (macro);
-			return;
-		}
-		break;
-	}
-
-	/* If we have input pending, then the last command was a prefix
-     command.  Don't change the state of rl_last_func. */
-	if (!rl_pending_input)
-		rl_last_func = map[key].function;
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Hacking Keyboard Macros 		    */
-/*								    */
-/* **************************************************************** */
-
-/* The currently executing macro string.  If this is non-zero,
-   then it is a malloc ()'ed string where input is coming from. */
-static char *executing_macro = (char *)NULL;
-
-/* The offset in the above string to the next character to be read. */
-static int executing_macro_index = 0;
-
-/* The current macro string being built.  Characters get stuffed
-   in here by add_macro_char (). */
-static char *current_macro = (char *)NULL;
-
-/* The size of the buffer allocated to current_macro. */
-static int current_macro_size = 0;
-
-/* The index at which characters are being added to current_macro. */
-static int current_macro_index = 0;
-
-/* A structure used to save nested macro strings.
-   It is a linked list of string/index for each saved macro. */
-struct saved_macro {
-	struct saved_macro *next;
-	char *string;
-	int index;
-};
-
-/* The list of saved macros. */
-struct saved_macro *macro_list = (struct saved_macro *)NULL;
-
-/* Forward declarations of static functions.  Thank you C. */
-static void push_executing_macro (), pop_executing_macro ();
-
-/* This one has to be declared earlier in the file. */
-/* static void add_macro_char (); */
-
-/* Set up to read subsequent input from STRING.
-   STRING is free ()'ed when we are done with it. */
-static
-with_macro_input (string)
-char *string;
-{
-	push_executing_macro ();
-	executing_macro = string;
-	executing_macro_index = 0;
-}
-
-/* Return the next character available from a macro, or 0 if
-   there are no macro characters. */
-static int
-next_macro_key ()
-{
-	if (!executing_macro)
-		return (0);
-
-	if (!executing_macro[executing_macro_index])
-	{
-		pop_executing_macro ();
-		return (next_macro_key ());
-	}
-
-	return (executing_macro[executing_macro_index++]);
-}
-
-/* Save the currently executing macro on a stack of saved macros. */
-static void
-push_executing_macro ()
-{
-	struct saved_macro *saver;
-
-	saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
-	saver->next = macro_list;
-	saver->index = executing_macro_index;
-	saver->string = executing_macro;
-
-	macro_list = saver;
-}
-
-/* Discard the current macro, replacing it with the one
-   on the top of the stack of saved macros. */
-static void
-pop_executing_macro ()
-{
-	if (executing_macro)
-		free (executing_macro);
-
-	executing_macro = (char *)NULL;
-	executing_macro_index = 0;
-
-	if (macro_list)
-	{
-		struct saved_macro *disposer = macro_list;
-		executing_macro = macro_list->string;
-		executing_macro_index = macro_list->index;
-		macro_list = macro_list->next;
-		free (disposer);
-	}
-}
-
-/* Add a character to the macro being built. */
-static void
-add_macro_char (c)
-int c;
-{
-	if (current_macro_index + 1 >= current_macro_size)
-	{
-		if (!current_macro)
-			current_macro = (char *)xmalloc (current_macro_size = 25);
-		else
-			current_macro =
-			    (char *)xrealloc (current_macro, current_macro_size += 25);
-	}
-
-	current_macro[current_macro_index++] = c;
-	current_macro[current_macro_index] = '\0';
-}
-
-/* Begin defining a keyboard macro.
-   Keystrokes are recorded as they are executed.
-   End the definition with rl_end_kbd_macro ().
-   If a numeric argument was explicitly typed, then append this
-   definition to the end of the existing macro, and start by
-   re-executing the existing macro. */
-rl_start_kbd_macro (ignore1, ignore2)
-int ignore1, ignore2;
-{
-	if (defining_kbd_macro)
-		rl_abort ();
-
-	if (rl_explicit_arg)
-	{
-		if (current_macro)
-			with_macro_input (savestring (current_macro));
-	}
-	else
-		current_macro_index = 0;
-
-	defining_kbd_macro = 1;
-}
-
-/* Stop defining a keyboard macro.
-   A numeric argument says to execute the macro right now,
-   that many times, counting the definition as the first time. */
-rl_end_kbd_macro (count, ignore)
-int count, ignore;
-{
-	if (!defining_kbd_macro)
-		rl_abort ();
-
-	current_macro_index -= (rl_key_sequence_length - 1);
-	current_macro[current_macro_index] = '\0';
-
-	defining_kbd_macro = 0;
-
-	rl_call_last_kbd_macro (--count, 0);
-}
-
-/* Execute the most recently defined keyboard macro.
-   COUNT says how many times to execute it. */
-rl_call_last_kbd_macro (count, ignore)
-int count, ignore;
-{
-	if (!current_macro)
-		rl_abort ();
-
-	while (count--)
-		with_macro_input (savestring (current_macro));
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Initializations 			    */
-/*								    */
-/* **************************************************************** */
-
-/* Initliaze readline (and terminal if not already). */
-rl_initialize ()
-{
-	extern char *rl_display_prompt;
-
-	/* If we have never been called before, initialize the
-     terminal and data structures. */
-	if (!rl_initialized)
-	{
-		readline_initialize_everything ();
-		rl_initialized++;
-	}
-
-	/* Initalize the current line information. */
-	rl_point = rl_end = 0;
-	the_line = rl_line_buffer;
-	the_line[0] = 0;
-
-	/* We aren't done yet.  We haven't even gotten started yet! */
-	rl_done = 0;
-
-	/* Tell the history routines what is going on. */
-	start_using_history ();
-
-	/* Make the display buffer match the state of the line. */
-	{
-		extern char *rl_display_prompt;
-		extern int forced_display;
-
-		rl_on_new_line ();
-
-		rl_display_prompt = rl_prompt ? rl_prompt : "";
-		forced_display = 1;
-	}
-
-	/* No such function typed yet. */
-	rl_last_func = (Function *)NULL;
-
-	/* Parsing of key-bindings begins in an enabled state. */
-	parsing_conditionalized_out = 0;
-}
-
-/* Initialize the entire state of the world. */
-readline_initialize_everything ()
-{
-	/* Find out if we are running in Emacs. */
-	running_in_emacs = (char *)getenv ("EMACS");
-
-	/* Allocate data structures. */
-	if (!rl_line_buffer)
-		rl_line_buffer =
-		    (char *)xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE);
-
-	/* Initialize the terminal interface. */
-	init_terminal_io ((char *)NULL);
-
-	/* Bind tty characters to readline functions. */
-	readline_default_bindings ();
-
-	/* Initialize the function names. */
-	rl_initialize_funmap ();
-
-	/* Read in the init file. */
-	rl_read_init_file ((char *)NULL);
-
-	/* If the completion parser's default word break characters haven't
-     been set yet, then do so now. */
-	{
-		extern char *rl_completer_word_break_characters;
-		extern char *rl_basic_word_break_characters;
-
-		if (rl_completer_word_break_characters == (char *)NULL)
-			rl_completer_word_break_characters = rl_basic_word_break_characters;
-	}
-}
-
-/* If this system allows us to look at the values of the regular
-   input editing characters, then bind them to their readline
-   equivalents. */
-readline_default_bindings ()
-{
-
-#ifdef NEW_TTY_DRIVER
-	struct sgttyb ttybuff;
-	int tty = fileno (rl_instream);
-
-	if (ioctl (tty, TIOCGETP, &ttybuff) != -1)
-	{
-		int erase = ttybuff.sg_erase, kill = ttybuff.sg_kill;
-
-		if (erase != -1 && keymap[erase].type == ISFUNC)
-			keymap[erase].function = rl_rubout;
-
-		if (kill != -1 && keymap[kill].type == ISFUNC)
-			keymap[kill].function = rl_unix_line_discard;
-	}
-
-#ifdef TIOCGLTC
-	{
-		struct ltchars lt;
-
-		if (ioctl (tty, TIOCGLTC, &lt) != -1)
-		{
-			int erase = lt.t_werasc, nextc = lt.t_lnextc;
-
-			if (erase != -1 && keymap[erase].type == ISFUNC)
-				keymap[erase].function = rl_unix_word_rubout;
-
-			if (nextc != -1 && keymap[nextc].type == ISFUNC)
-				keymap[nextc].function = rl_quoted_insert;
-		}
-	}
-#endif /* TIOCGLTC */
-#else /* not NEW_TTY_DRIVER */
-	struct termio ttybuff;
-	int tty = fileno (rl_instream);
-
-	if (ioctl (tty, TCGETA, &ttybuff) != -1)
-	{
-		int erase = ttybuff.c_cc[VERASE];
-		int kill = ttybuff.c_cc[VKILL]l
-
-		if (erase != -1 && keymap[(unsigned char)erase].type == ISFUNC)
-			keymap[(unsigned char)erase].function = rl_rubout;
-
-		if (kill != -1 && keymap[(unsigned char)kill].type == ISFUNC)
-			keymap[(unsigned char)kill].function = rl_unix_line_discard;
-	}
-#endif /* NEW_TTY_DRIVER */
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Numeric Arguments			    */
-/*								    */
-/* **************************************************************** */
-
-/* Handle C-u style numeric args, as well as M--, and M-digits. */
-
-/* Add the current digit to the argument in progress. */
-rl_digit_argument (ignore, key)
-int ignore, key;
-{
-	rl_pending_input = key;
-	rl_digit_loop ();
-}
-
-/* What to do when you abort reading an argument. */
-rl_discard_argument ()
-{
-	ding ();
-	rl_clear_message ();
-	rl_init_argument ();
-}
-
-/* Create a default argument. */
-rl_init_argument ()
-{
-	rl_numeric_arg = arg_sign = 1;
-	rl_explicit_arg = 0;
-}
-
-/* C-u, universal argument.  Multiply the current argument by 4.
-   Read a key.  If the key has nothing to do with arguments, then
-   dispatch on it.  If the key is the abort character then abort. */
-rl_universal_argument ()
-{
-	rl_numeric_arg *= 4;
-	rl_digit_loop ();
-}
-
-rl_digit_loop ()
-{
-	int key, c;
-	while (1)
-	{
-		rl_message ("(arg: %d) ", arg_sign * rl_numeric_arg);
-		key = c = rl_read_key ();
-
-		if (keymap[c].type == ISFUNC &&
-		    keymap[c].function == rl_universal_argument)
-		{
-			rl_numeric_arg *= 4;
-			continue;
-		}
-		c = UNMETA (c);
-		if (numeric (c))
-		{
-			if (rl_explicit_arg)
-				rl_numeric_arg = (rl_numeric_arg * 10) + (c - '0');
-			else
-				rl_numeric_arg = (c - '0');
-			rl_explicit_arg = 1;
-		}
-		else
-		{
-			if (c == '-' && !rl_explicit_arg)
-			{
-				rl_numeric_arg = 1;
-				arg_sign = -1;
-			}
-			else
-			{
-				rl_clear_message ();
-				rl_dispatch (key, keymap);
-				return;
-			}
-		}
-	}
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Display stuff				    */
-/*								    */
-/* **************************************************************** */
-
-/* This is the stuff that is hard for me.  I never seem to write good
-   display routines in C.  Let's see how I do this time. */
-
-/* (PWP) Well... Good for a simple line updater, but totally ignores
-   the problems of input lines longer than the screen width.
-
-   update_line and the code that calls it makes a multiple line,
-   automatically wrapping line update.  Carefull attention needs
-   to be paid to the vertical position variables.
-
-   handling of terminals with autowrap on (incl. DEC braindamage)
-   could be improved a bit.  Right now I just cheat and decrement
-   screenwidth by one. */
-
-/* Keep two buffers; one which reflects the current contents of the
-   screen, and the other to draw what we think the new contents should
-   be.  Then compare the buffers, and make whatever changes to the
-   screen itself that we should.  Finally, make the buffer that we
-   just drew into be the one which reflects the current contents of the
-   screen, and place the cursor where it belongs.
-
-   Commands that want to can fix the display themselves, and then let
-   this function know that the display has been fixed by setting the
-   RL_DISPLAY_FIXED variable.  This is good for efficiency. */
-
-/* Termcap variables: */
-extern char *term_up, *term_dc, *term_cr;
-extern int screenheight, screenwidth, terminal_can_insert;
-
---cut here---cut here---cut here---

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

---cut here---cut here---cut here---
-/* What YOU turn on when you have handled all redisplay yourself. */
-int rl_display_fixed = 0;
-
-/* The visible cursor position.  If you print some text, adjust this. */
-int last_c_pos = 0;
-int last_v_pos = 0;
-
-/* The last left edge of text that was displayed.  This is used when
-   doing horizontal scrolling.  It shifts in thirds of a screenwidth. */
-static int last_lmargin = 0;
-
-/* The line display buffers.  One is the line currently displayed on
-   the screen.  The other is the line about to be displayed. */
-static char *visible_line = (char *)NULL;
-static char *invisible_line = (char *)NULL;
-
-/* Number of lines currently on screen minus 1. */
-int vis_botlin = 0;
-
-/* A buffer for `modeline' messages. */
-char msg_buf[128];
-
-/* Non-zero forces the redisplay even if we thought it was unnecessary. */
-int forced_display = 0;
-
-/* The stuff that gets printed out before the actual text of the line.
-   This is usually pointing to rl_prompt. */
-char *rl_display_prompt = (char *)NULL;
-
-/* Default and initial buffer size.  Can grow. */
-static int line_size = 1024;
-
-/* Non-zero means to always use horizontal scrolling in line display. */
-int horizontal_scroll_mode = 0;
-
-/* I really disagree with this, but my boss (among others) insists that we
-   support compilers that don't work.  I don't think we are gaining by doing
-   so; what is the advantage in producing better code if we can't use it? */
-/* The following two declarations belong inside the
-   function block, not here. */
-static void move_cursor_relative ();
-static void output_some_chars ();
-static void output_character_function ();
-static int compare_strings ();
-
-/* Basic redisplay algorithm. */
-rl_redisplay ()
-{
-	register int in, out, c, linenum;
-	register char *line = invisible_line;
-	int c_pos = 0;
-	int inv_botlin = 0;		/* Number of lines in newly drawn buffer. */
-
-	extern int readline_echoing_p;
-
-	if (!readline_echoing_p)
-		return;
-
-	if (!rl_display_prompt)
-		rl_display_prompt = "";
-
-	if (!invisible_line)
-	{
-		visible_line = (char *)xmalloc (line_size);
-		invisible_line = (char *)xmalloc (line_size);
-		line = invisible_line;
-		for (in = 0; in < line_size; in++)
-		{
-			visible_line[in] = 0;
-			invisible_line[in] = 1;
-		}
-		rl_on_new_line ();
-	}
-
-	/* Draw the line into the buffer. */
-	c_pos = -1;
-
-	/* Mark the line as modified or not.  We only do this for history
-     lines.  No we don't.  -pjf */
-	out = 0;
-	/*if (current_history () && rl_undo_list)
-    {
-      line[out++] = '*';
-      line[out] = '\0';
-    }*/
-
-	/* If someone thought that the redisplay was handled, but the currently
-     visible line has a different modification state than the one about
-     to become visible, then correct the callers misconception. */
-	if (visible_line[0] != invisible_line[0])
-		rl_display_fixed = 0;
-
-	strncpy (line + out,  rl_display_prompt, strlen (rl_display_prompt));
-	out += strlen (rl_display_prompt);
-	line[out] = '\0';
-
-	for (in = 0; in < rl_end; in++)
-	{
-		c = the_line[in];
-
-		if (out + 1 >= line_size)
-		{
-			line_size *= 2;
-			visible_line = (char *)xrealloc (visible_line, line_size);
-			invisible_line = (char *)xrealloc (invisible_line, line_size);
-			line = invisible_line;
-		}
-
-		if (in == rl_point)
-			c_pos = out;
-
-		if (c > 127)
-		{
-			line[out++] = 'M';
-			line[out++] = '-';
-			line[out++] = c - 128;
-		}
-#define DISPLAY_TABS
-#ifdef DISPLAY_TABS
-		else if (c == '\t')
-		{
-			register int newout = (out | (int)7) + 1;
-			while (out < newout)
-				line[out++] = ' ';
-		}
-#endif
-		else if (c == '\n')
-		{
-			line[out++] = '\\';
-			line[out++] = 'n';
-		}
-		else if (c < 32)
-		{
-			line[out++] = '^';
-			line[out++] = c + 64;
-		}
-		else
-			line[out++] = c;
-	}
-	line[out] = '\0';
-	if (c_pos < 0)
-		c_pos = out;
-
-	/* PWP: now is when things get a bit hairy.  The visible and invisible
-     line buffers are really multiple lines, which would wrap every
-     (screenwidth - 1) characters.  Go through each in turn, finding
-     the changed region and updating it.  The line order is top to bottom. */
-
-	/* If we can move the cursor up and down, then use multiple lines,
-     otherwise, let long lines display in a single terminal line, and
-     horizontally scroll it. */
-
-	if (!horizontal_scroll_mode && term_up && *term_up)
-	{
-		int total_screen_chars = (screenwidth * screenheight);
-
-		if (!rl_display_fixed || forced_display)
-		{
-			forced_display = 0;
-
-			/* If we have more than a screenful of material to display, then
-	     only display a screenful.  We should display the last screen,
-	     not the first.  I'll fix this in a minute. */
-			if (out >= total_screen_chars)
-				out = total_screen_chars - 1;
-
-			/* Number of screen lines to display. */
-			inv_botlin = out / screenwidth;
-
-			/* For each line in the buffer, do the updating display. */
-			for (linenum = 0; linenum <= inv_botlin; linenum++)
-				update_line (linenum > vis_botlin ? ""
-				    : &visible_line[linenum * screenwidth],
-				    &invisible_line[linenum * screenwidth],
-				    linenum);
-
-			/* We may have deleted some lines.  If so, clear the left over
-	     blank ones at the bottom out. */
-			if (vis_botlin > inv_botlin)
-			{
-				char *tt;
-				for (; linenum <= vis_botlin; linenum++)
-				{
-					tt = &visible_line[linenum * screenwidth];
-					move_vert (linenum);
-					move_cursor_relative (0, tt);
-					clear_to_eol ((linenum == vis_botlin)?
-					    strlen (tt) : screenwidth);
-				}
-			}
-			vis_botlin = inv_botlin;
-
-			/* Move the cursor where it should be. */
-			move_vert (c_pos / screenwidth);
-			move_cursor_relative (c_pos % screenwidth,
-			    &invisible_line[(c_pos / screenwidth) * screenwidth]);
-		}
-	}
-	else	/* Do horizontal scrolling. */
-	{
-		int lmargin;
-
-		/* Always at top line. */
-		last_v_pos = 0;
-
-		/* If the display position of the cursor would be off the edge
-	 of the screen, start the display of this line at an offset that
-	 leaves the cursor on the screen. */
-		if (c_pos - last_lmargin > screenwidth - 2)
-			lmargin = (c_pos / (screenwidth / 3) - 2) * (screenwidth / 3);
-		else if (c_pos - last_lmargin < 1)
-			lmargin = ((c_pos - 1) / (screenwidth / 3)) * (screenwidth / 3);
-		else
-			lmargin = last_lmargin;
-
-		/* If the first character on the screen isn't the first character
-	 in the display line, indicate this with a special character. */
-		if (lmargin > 0)
-			line[lmargin] = '<';
-
-		if (lmargin + screenwidth < out)
-			line[lmargin + screenwidth - 1] = '>';
-
-		if (!rl_display_fixed || forced_display || lmargin != last_lmargin)
-		{
-			forced_display = 0;
-			update_line (&visible_line[last_lmargin],
-			    &invisible_line[lmargin], 0);
-
-			move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
-			last_lmargin = lmargin;
-		}
-	}
-	fflush (out_stream);
-
-	/* Swap visible and non-visible lines. */
-	{
-		char *temp = visible_line;
-		visible_line = invisible_line;
-		invisible_line = temp;
-		rl_display_fixed = 0;
-	}
-}
-
-/* PWP: update_line() is based on finding the middle difference of each
-   line on the screen; vis:
-
-			     /old first difference
-	/beginning of line   |              /old last same       /old EOL
-	v		     v              v                    v
-old:	eddie> Oh, my little gruntle-buggy is to me, as lurgid as
-new:	eddie> Oh, my little buggy says to me, as lurgid as
-	^		     ^        ^			   ^
-	\beginning of line   |        \new last same	   \new end of line
-			     \new first difference
-
-   All are character pointers for the sake of speed.  Special cases for
-   no differences, as well as for end of line additions must be handeled.
-
-   Could be made even smarter, but this works well enough */
-static
-update_line (old, new, current_line)
-register char *old, *new;
-int current_line;
-{
-	register char *ofd, *ols, *oe, *nfd, *nls, *ne;
-	int lendiff, wsatend;
-
-	/* Find first difference. */
-	for (ofd = old, nfd = new;
-	    (ofd - old < screenwidth) && *ofd && (*ofd == *nfd);
-	    ofd++, nfd++)
-		;
-
-	/* Move to the end of the screen line. */
-	for (oe = ofd; ((oe - old) < screenwidth) && *oe; oe++);
-	for (ne = nfd; ((ne - new) < screenwidth) && *ne; ne++);
-
-	/* If no difference, continue to next line. */
-	if (ofd == oe && nfd == ne)
-		return;
-
-	wsatend = 1;			/* flag for trailing whitespace */
-	ols = oe - 1;			/* find last same */
-	nls = ne - 1;
-	while ((*ols == *nls) && (ols > ofd) && (nls > nfd))
-	{
-		if (*ols != ' ')
-			wsatend = 0;
-		ols--;
-		nls--;
-	}
-
-	if (wsatend)
-	{
-		ols = oe;
-		nls = ne;
-	}
-	else if (*ols != *nls)
-	{
-		if (*ols)			/* don't step past the NUL */
-			ols++;
-		if (*nls)
-			nls++;
-	}
-
-	move_vert (current_line);
-	move_cursor_relative (ofd - old, old);
-
-	/* if (len (new) > len (old)) */
-	lendiff = (nls - nfd) - (ols - ofd);
-
-	/* Insert (diff(len(old),len(new)) ch */
-	if (lendiff > 0)
-	{
-		if (terminal_can_insert)
-		{
-			extern char *term_IC;
-
-			/* Sometimes it is cheaper to print the characters rather than
-	     use the terminal's capabilities. */
-			if ((2 * (ne - nfd)) < lendiff && !term_IC)
-			{
-				output_some_chars (nfd, (ne - nfd));
-				last_c_pos += (ne - nfd);
-			}
-			else
-			{
-				if (*ols)
-				{
-					insert_some_chars (nfd, lendiff);
-					last_c_pos += lendiff;
-				}
-				else
-				{
-					/* At the end of a line the characters do not have to
-		     be "inserted".  They can just be placed on the screen. */
-					output_some_chars (nfd, lendiff);
-					last_c_pos += lendiff;
-				}
-				/* Copy (new) chars to screen from first diff to last match. */
-				if (((nls - nfd) - lendiff) > 0)
-				{
-					output_some_chars (&nfd[lendiff], ((nls - nfd) - lendiff));
-					last_c_pos += ((nls - nfd) - lendiff);
-				}
-			}
-		}
-		else
-		{		/* cannot insert chars, write to EOL */
-			output_some_chars (nfd, (ne - nfd));
-			last_c_pos += (ne - nfd);
-		}
-	}
-	else	/* Delete characters from line. */
-	{
-		/* If possible and inexpensive to use terminal deletion, then do so. */
-		if (term_dc && (2 * (ne - nfd)) >= (-lendiff))
-		{
-			if (lendiff)
-				delete_chars (-lendiff); /* delete (diff) characters */
-
-			/* Copy (new) chars to screen from first diff to last match */
-			if ((nls - nfd) > 0)
-			{
-				output_some_chars (nfd, (nls - nfd));
-				last_c_pos += (nls - nfd);
-			}
-		}
-		/* Otherwise, print over the existing material. */
-		else
-		{
-			output_some_chars (nfd, (ne - nfd));
-			last_c_pos += (ne - nfd);
-			clear_to_eol ((oe - old) - (ne - new));
-		}
-	}
-}
-
-/* (PWP) tell the update routines that we have moved onto a
-   new (empty) line. */
-rl_on_new_line ()
-{
-	if (visible_line)
-		visible_line[0] = '\0';
-
-	last_c_pos = last_v_pos = 0;
-	vis_botlin = last_lmargin = 0;
-}
-
-/* Actually update the display, period. */
-rl_forced_update_display ()
-{
-	if (visible_line)
-	{
-		register char *temp = visible_line;
-
-		while (*temp) *temp++ = '\0';
-	}
-	rl_on_new_line ();
-	forced_display++;
-	rl_redisplay ();
-}
-
-/* Move the cursor from last_c_pos to NEW, which are buffer indices.
-   DATA is the contents of the screen line of interest; i.e., where
-   the movement is being done. */
-static void
-move_cursor_relative (new, data)
-int new;
-char *data;
-{
-	register int i;
-
-	/* It may be faster to output a CR, and then move forwards instead
-     of moving backwards. */
-	if (new + 1 < last_c_pos - new)
-	{
-		tputs (term_cr, 1, output_character_function);
-		last_c_pos = 0;
-	}
-
-	if (last_c_pos == new) return;
-
-	if (last_c_pos < new)
-	{
-		/* Move the cursor forward.  We do it by printing the command
-	 to move the cursor forward if there is one, else print that
-	 portion of the output buffer again.  Which is cheaper? */
-
-		/* The above comment is left here for posterity.  It is faster
-	 to print one character (non-control) than to print a control
-	 sequence telling the terminal to move forward one character.
-	 That kind of control is for people who don't know what the
-	 data is underneath the cursor. */
-#ifdef HACK_TERMCAP_MOTION
-		extern char *term_forward_char;
-
-		if (term_forward_char)
-			for (i = last_c_pos; i < new; i++)
-				tputs (term_forward_char, 1, output_character_function);
-		else
-			for (i = last_c_pos; i < new; i++)
-				putc (data[i], out_stream);
-#else
-		for (i = last_c_pos; i < new; i++)
-			putc (data[i], out_stream);
-#endif				/* HACK_TERMCAP_MOTION */
-	}
-	else
-		backspace (last_c_pos - new);
-	last_c_pos = new;
-}
-
-/* PWP: move the cursor up or down. */
-move_vert (to)
-int to;
-{
-	void output_character_function ();
-	register int delta, i;
-
-	if (last_v_pos == to) return;
-
-	if (to > screenheight)
-		return;
-
-	if ((delta = to - last_v_pos) > 0)
-	{
-		for (i = 0; i < delta; i++)
-			putc ('\n', out_stream);
-		tputs (term_cr, 1, output_character_function);
-		last_c_pos = 0;		/* because crlf() will do \r\n */
-	}
-	else
-	{			/* delta < 0 */
-		if (term_up && *term_up)
-			for (i = 0; i < -delta; i++)
-				tputs (term_up, 1, output_character_function);
-	}
-	last_v_pos = to;		/* now to is here */
-}
-
-/* Physically print C on out_stream.  This is for functions which know
-   how to optimize the display. */
-rl_show_char (c)
-int c;
-{
-	if (c > 127)
-	{
-		fprintf (out_stream, "M-");
-		c -= 128;
-	}
-
-#ifdef DISPLAY_TABS
-	if (c < 32 && c != '\t')
-#else
-		if (c < 32)
-#endif
-		{
-
-			c += 64;
-		}
-
-	putc (c, out_stream);
-	fflush (out_stream);
-}
-
-#ifdef DISPLAY_TABS
-int
-rl_character_len (c, pos)
-register int c, pos;
-{
-	if (c < ' ' || c > 126)
-	{
-		if (c == '\t')
-			return (((pos | (int)7) + 1) - pos);
-		else
-			return (3);
-	}
-	else
-		return (1);
-}
-#else
-int
-rl_character_len (c)
-int c;
-{
-	if (c < ' ' || c > 126)
-		return (3);
-	else
-		return (1);
-}
-#endif  /* DISPLAY_TAB */
-
-/* How to print things in the "echo-area".  The prompt is treated as a
-   mini-modeline. */
-rl_message (string, arg1, arg2)
-char *string;
-{
-	sprintf (msg_buf, string, arg1, arg2);
-	rl_display_prompt = msg_buf;
-	rl_redisplay ();
-}
-
-/* How to clear things from the "echo-area". */
-rl_clear_message ()
-{
-	rl_display_prompt = rl_prompt;
-	rl_redisplay ();
-}
-
-/* **************************************************************** */
-/*								    */
-/*			Terminal and Termcap			    */
-/*								    */
-/* **************************************************************** */
-
-static char *term_buffer = (char *)NULL;
-static char *term_string_buffer = (char *)NULL;
-
-/* Non-zero means this terminal can't really do anything. */
-int dumb_term = 0;
-
-char PC;
-char *BC, *UP;
-
-/* Some strings to control terminal actions.  These are output by tputs (). */
-char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
-
-int screenwidth, screenheight;
-
-/* Non-zero if we determine that the terminal can do character insertion. */
-int terminal_can_insert = 0;
-
-/* How to insert characters. */
-char *term_im, *term_ei, *term_ic, *term_ip, *term_IC;
-
-/* How to delete characters. */
-char *term_dc, *term_DC;
-
-#ifdef HACK_TERMCAP_MOTION
-char *term_forward_char;
-#endif  /* HACK_TERMCAP_MOTION */
-
-/* How to go up a line. */
-char *term_up;
-
-/* Re-initialize the terminal considering that the TERM/TERMCAP variable
-   has changed. */
-rl_reset_terminal (terminal_name)
-char *terminal_name;
-{
-	init_terminal_io (terminal_name);
-}
-
-init_terminal_io (terminal_name)
-char *terminal_name;
-{
-	char *term = (terminal_name? terminal_name : (char *)getenv ("TERM"));
-	char *tgetstr (), *buffer;
-
-
-	if (!term_string_buffer)
-		term_string_buffer = (char *)xmalloc (2048);
-
-	if (!term_buffer)
-		term_buffer = (char *)xmalloc (2048);
-
-	buffer = term_string_buffer;
-
-	term_clrpag = term_cr = term_clreol = (char *)NULL;
-
-	if (!term)
-		term = "dumb";
-
-	if (tgetent (term_buffer, term) < 0)
-	{
-		dumb_term = 1;
-		return;
-	}
-
-	BC = tgetstr ("pc", &buffer);
-	PC = buffer ? *buffer : 0;
-
-	term_backspace = tgetstr ("le", &buffer);
-
-	term_cr = tgetstr ("cr", &buffer);
-	term_clreol = tgetstr ("ce", &buffer);
-	term_clrpag = tgetstr ("cl", &buffer);
-
-	if (!term_cr)
-		term_cr =  "\r";
-
-#ifdef HACK_TERMCAP_MOTION
-	term_forward_char = tgetstr ("nd", &buffer);
-#endif  /* HACK_TERMCAP_MOTION */
-
-	screenwidth = tgetnum ("co");
-	if (screenwidth <= 0)
-		screenwidth = 80;
-	screenwidth--;		/* PWP: avoid autowrap bugs */
-
-	screenheight = tgetnum ("li");
-	if (screenheight <= 0)
-		screenheight = 24;
-
-	term_im = tgetstr ("im", &buffer);
-	term_ei = tgetstr ("ei", &buffer);
-	term_IC = tgetstr ("IC", &buffer);
-	term_ic = tgetstr ("ic", &buffer);
-
-	/* "An application program can assume that the terminal can do
-      character insertion if *any one of* the capabilities `IC',
-      `im', `ic' or `ip' is provided."  But we can't do anything if
-      only `ip' is provided, so... */
-	terminal_can_insert = (term_IC || term_im || term_ic);
-
-	term_up = tgetstr ("up", &buffer);
-	term_dc = tgetstr ("dc", &buffer);
-	term_DC = tgetstr ("DC", &buffer);
-}
-
-/* A function for the use of tputs () */
-static void
-output_character_function (c)
-int c;
-{
-	putc (c, out_stream);
-}
-
-/* Write COUNT characters from STRING to the output stream. */
-static void
-output_some_chars (string, count)
-char *string;
-int count;
-{
-	fwrite (string, 1, count, out_stream);
-}
-
-
-/* Delete COUNT characters from the display line. */
-static
-delete_chars (count)
-int count;
-{
-	if (count > screenwidth)
-		return;
-
-	if (term_DC && *term_DC)
-	{
-		char *tgoto (), *buffer;
-		buffer = tgoto (term_DC, 0, count);
-		tputs (buffer, 1, output_character_function);
-	}
-	else
-	{
-		if (term_dc && *term_dc)
-			while (count--)
-				tputs (term_dc, 1, output_character_function);
-	}
-}
-
-/* Insert COUNT character from STRING to the output stream. */
-static
-insert_some_chars (string, count)
-char *string;
-int count;
-{
-	/* If IC is defined, then we do not have to "enter" insert mode. */
-	if (term_IC)
-	{
-		char *tgoto (), *buffer;
-		buffer = tgoto (term_IC, 0, count);
-		tputs (buffer, 1, output_character_function);
-		output_some_chars (string, count);
-	}
-	else
-	{
-		register int i;
-
-		/* If we have to turn on insert-mode, then do so. */
-		if (term_im && *term_im)
-			tputs (term_im, 1, output_character_function);
-
-		/* If there is a special command for inserting characters, then
-	 use that first to open up the space. */
-		if (term_ic && *term_ic)
-		{
-			for (i = count; i--; )
-				tputs (term_ic, 1, output_character_function);
-		}
-
-		/* Print the text. */
-		output_some_chars (string, count);
-
-		/* If there is a string to turn off insert mode, we had best use
-	 it now. */
-		if (term_ei && *term_ei)
-			tputs (term_ei, 1, output_character_function);
-	}
-}
-
-/* Move the cursor back. */
-backspace (count)
-int count;
-{
-	register int i;
-
-	if (term_backspace)
-		for (i = 0; i < count; i++)
-			tputs (term_backspace, 1, output_character_function);
-	else
-		for (i = 0; i < count; i++)
-			putc ('\b', out_stream);
-}
-
-/* Move to the start of the next line. */
-crlf ()
-{
-	tputs (term_cr, 1, output_character_function);
-	putc ('\n', out_stream);
-}
-
-/* Clear to the end of the line.  COUNT is the minimum
-   number of character spaces to clear, */
-clear_to_eol (count)
-int count;
-{
-	if (term_clreol)
-	{
-		tputs (term_clreol, 1, output_character_function);
-	}
-	else
-	{
-		register int i;
-
-		/* Do one more character space. */
-		count++;
-
-		for (i = 0; i < count; i++)
-			putc (' ', out_stream);
-
-		backspace (count);
-	}
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*		      Saving and Restoring the TTY	    	    */
-/*								    */
-/* **************************************************************** */
-
-#ifdef NEW_TTY_DRIVER
-
-/* We use this to get and set the tty_flags. */
-static struct sgttyb the_ttybuff;
-
-/* Put the terminal in CBREAK mode so that we can detect key presses. */
-rl_prep_terminal ()
-{
-int original_tty_flags,local_mode_flags;
-
-	static int firsttime = 1;
-	int tty = fileno (rl_instream);
-
-	/* We always get the latest tty values.  Maybe stty changed them. */
-	ioctl (tty, TIOCGETP, &the_ttybuff);
-	original_tty_flags = ((the_ttybuff.sg_flags)&~(O_CBREAK|O_RAW))|O_ECHO;
-
-	readline_echoing_p = (original_tty_flags & ECHO);
-
-	/* If this terminal doesn't care how the 8th bit is used,
-     then we can use it for the meta-key.
-     We check by seeing if BOTH odd and even parity are allowed. */
-	if ((the_ttybuff.sg_flags & ODDP) && (the_ttybuff.sg_flags & EVENP))
-	{
-#ifdef PASS8
-		the_ttybuff.sg_flags |= PASS8;
-#endif
-	}
-
-	/* Hack on local mode flags if we can. */
-#if defined (TIOCLGET) && defined (LPASS8)
-	{
-		int flags;
-
-		ioctl (tty, TIOCLGET, &local_mode_flags);
-		flags = local_mode_flags | LPASS8;
-		ioctl (tty, TIOCLSET, &flags);
-	}
-#endif
-
-#ifdef TIOCGETC
-	{
-		struct tchars temp;
-
-		ioctl (tty, TIOCGETC, &temp);
-
-		/* Get rid of C-s and C-q.
-       We remember the value of startc (C-q) so that if the terminal is in
-       xoff state, the user can xon it by pressing that character. */
-		xon_char = temp.t_startc;
-		temp.t_stopc = -1;
-		temp.t_startc = -1;
-
-		/* If there is an XON character, bind it to restart the output. */
-		if (xon_char != -1)
-			rl_bind_key (xon_char, rl_restart_output);
-
-		/* If there is an EOF char, bind eof_char to it. */
-		if (temp.t_eofc != -1)
-			eof_char = temp.t_eofc;
-
-#ifdef NEVER
-		/* Get rid of C-\ and C-c. */
-		temp.t_intrc = temp.t_quitc = -1;
-#endif
-
-		ioctl (tty, TIOCSETC, &temp);
-	}
-#endif /* TIOCGETC */
-
-#ifdef TIOCGLTC
-	{
-		struct ltchars temp;
-
-		ioctl (tty, TIOCGLTC, &temp);
-
-		/* Make the interrupt keys go away.  Just enough to make people happy. */
-		temp.t_dsuspc = -1;		/* C-y */
-		temp.t_lnextc = -1;		/* C-v */
-
-		ioctl (tty, TIOCSLTC, &temp);
-	}
-#endif /* TIOCGLTC */
-
-	the_ttybuff.sg_flags &= ~ECHO;
-	the_ttybuff.sg_flags |= CBREAK;
-	ioctl (tty, TIOCSETN, &the_ttybuff);
-}
-
-
-#else  /* !defined (NEW_TTY_DRIVER) */
-
-#if !defined (VMIN)
-#define VMIN VEOF
-#endif
-
-#if !defined (VTIME)
-#define VTIME VEOL
-#endif
-
-static struct termio otio;
-
-rl_prep_terminal ()
-{
-	int tty = fileno (rl_instream);
-	struct termio tio;
-
-	ioctl (tty, TCGETA, &tio);
-	ioctl (tty, TCGETA, &otio);
-
-	readline_echoing_p = (tio.c_lflag & ECHO);
-
-	tio.c_lflag &= ~(ICANON|ECHO);
-	tio.c_iflag &= ~(IXON|IXOFF|IXANY|ISTRIP|INPCK);
-
-#if !defined (HANDLE_SIGNALS)
-	tio.c_lflag &= ~ISIG;
-#endif
-
-	tio.c_cc[VMIN] = 1;
-	tio.c_cc[VTIME] = 0;
-	ioctl (tty, TCSETAW, &tio);
-	ioctl (tty, TCXONC, 1);	/* Simulate a ^Q. */
-}
-
-#endif  /* NEW_TTY_DRIVER */
-
-/* Restore the terminal to its original state. */
-rl_deprep_terminal ()
-{
-	rl_active = 0;
-	restoretty();
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Utility Functions			    */
-/*								    */
-/* **************************************************************** */
-
-/* Return 0 if C is not a member of the class of characters that belong
-   in words, or 1 if it is. */
-
-int allow_pathname_alphabetic_chars = 0;
-char *pathname_alphabetic_chars = "/-_=~.#$";
-
-int
-alphabetic (c)
-int c;
-{
-	char *rindex ();
-	if (pure_alphabetic (c) || (numeric (c)))
-		return (1);
-
-	if (allow_pathname_alphabetic_chars)
-		return ((int)rindex (pathname_alphabetic_chars, c));
-	else
-		return (0);
-}
-
-/* Return non-zero if C is a numeric character. */
-int
-numeric (c)
-int c;
-{
-	return (c >= '0' && c <= '9');
-}
-
-/* Ring the terminal bell. */
-int
-ding ()
-{
-extern int opts[128];
-
-	if (readline_echoing_p && opts['B'] == 0)
-	{
-		fprintf (stderr, "\007");
-		fflush (stderr);
-	}
-	return (-1);
-}
-
-/* How to abort things. */
-rl_abort ()
-{
-	ding ();
-	rl_clear_message ();
-	rl_init_argument ();
-	rl_pending_input = 0;
-
-	defining_kbd_macro = 0;
-	while (executing_macro)
-		pop_executing_macro ();
-
-	longjmp (readline_top_level, 1);
-}
-
-/* Return a copy of the string between FROM and TO.
-   FROM is inclusive, TO is not. */
-static char *
-rl_copy (from, to)
-int from, to;
-{
-	register int length;
-	char *copy;
-
-	/* Fix it if the caller is confused. */
-	if (from > to) {
-		int t = from;
-		from = to;
-		to = t;
-	}
-
-	length = to - from;
-	copy = (char *)xmalloc (1 + length);
-	strncpy (copy, the_line + from, length);
-	copy[length] = '\0';
-	return (copy);
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Insert and Delete			    */
-/*								    */
-/* **************************************************************** */
-
-
-/* Insert a string of text into the line at point.  This is the only
-   way that you should do insertion.  rl_insert () calls this
-   function. */
-rl_insert_text (string)
-char *string;
-{
-	extern int doing_an_undo;
-	register int i, l = strlen (string);
-	while (rl_end + l >= rl_line_buffer_len)
-	{
-		rl_line_buffer =
-		    (char *)xrealloc (rl_line_buffer,
-		    rl_line_buffer_len += DEFAULT_BUFFER_SIZE);
-		the_line = rl_line_buffer;
-	}
-
-	for (i = rl_end; i >= rl_point; i--)
-		the_line[i + l] = the_line[i];
-	strncpy (the_line + rl_point, string, l);
-
-	/* Remember how to undo this if we aren't undoing something. */
-	if (!doing_an_undo)
-	{
-		/* If possible and desirable, concatenate the undos. */
-		if ((strlen (string) == 1) &&
-		    rl_undo_list &&
-		    (rl_undo_list->what == UNDO_INSERT) &&
-		    (rl_undo_list->end == rl_point) &&
-		    (rl_undo_list->end - rl_undo_list->start < 20))
-			rl_undo_list->end++;
-		else
-			rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
-	}
-	rl_point += l;
-	rl_end += l;
-	the_line[rl_end] = '\0';
-}
-
-/* Delete the string between FROM and TO.  FROM is
-   inclusive, TO is not. */
-rl_delete_text (from, to)
-int from, to;
-{
-	extern int doing_an_undo;
-	register char *text;
-
-	/* Fix it if the caller is confused. */
-	if (from > to) {
-		int t = from;
-		from = to;
-		to = t;
-	}
-	text = rl_copy (from, to);
-	strncpy (the_line + from, the_line + to, rl_end - to);
-
-	/* Remember how to undo this delete. */
-	if (!doing_an_undo)
-		rl_add_undo (UNDO_DELETE, from, to, text);
-	else
-		free (text);
-
-	rl_end -= (to - from);
-	the_line[rl_end] = '\0';
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Readline character functions		    */
-/*								    */
-/* **************************************************************** */
-
-/* This is not a gap editor, just a stupid line input routine.  No hair
-   is involved in writing any of the functions, and none should be. */
-
-/* Note that:
-
-   rl_end is the place in the string that we would place '\0';
-   i.e., it is always safe to place '\0' there.
-
-   rl_point is the place in the string where the cursor is.  Sometimes
-   this is the same as rl_end.
-
-   Any command that is called interactively receives two arguments.
-   The first is a count: the numeric arg pased to this command.
-   The second is the key which invoked this command.
-*/
-
-
-/* **************************************************************** */
-/*								    */
-/*			Movement Commands			    */
-/*								    */
-/* **************************************************************** */
-
-/* Note that if you `optimize' the display for these functions, you cannot
-   use said functions in other functions which do not do optimizing display.
-   I.e., you will have to update the data base for rl_redisplay, and you
-   might as well let rl_redisplay do that job. */
-
-/* Move forward COUNT characters. */
-rl_forward (count)
-int count;
-{
-	if (count < 0)
-		rl_backward (-count);
-	else
-		while (count)
-		{
-#ifdef VI_MODE
-			if (rl_point == (rl_end - (rl_editing_mode == vi_mode)))
-#else
-				if (rl_point == rl_end)
-#endif
-				{
-					ding ();
-					return;
-				}
-				else
-					rl_point++;
-			--count;
-		}
-}
-
-/* Move backward COUNT characters. */
-rl_backward (count)
-int count;
-{
-	if (count < 0)
-		rl_forward (-count);
-	else
-		while (count)
-		{
-			if (!rl_point)
-			{
-				ding ();
-				return;
-			}
-			else
-				--rl_point;
-			--count;
-		}
-}
-
-/* Move to the beginning of the line. */
-rl_beg_of_line ()
-{
-	rl_point = 0;
-}
-
-/* Move to the end of the line. */
-rl_end_of_line ()
-{
-	rl_point = rl_end;
-}
-
-/* Move forward a word.  We do what Emacs does. */
-rl_forward_word (count)
-int count;
-{
-	int c;
-
-	if (count < 0)
-	{
-		rl_backward_word (-count);
-		return;
-	}
-
-	while (count)
-	{
-		if (rl_point == rl_end)
-			return;
-
-		/* If we are not in a word, move forward until we are in one.
-	 Then, move forward until we hit a non-alphabetic character. */
-		c = the_line[rl_point];
-		if (!alphabetic (c))
-		{
-			while (++rl_point < rl_end)
-			{
-				c = the_line[rl_point];
-				if (alphabetic (c)) break;
-			}
-		}
-		if (rl_point == rl_end) return;
-		while (++rl_point < rl_end)
-		{
-			c = the_line[rl_point];
-			if (!alphabetic (c)) break;
-		}
-		--count;
-	}
-}
-
-/* Move backward a word.  We do what Emacs does. */
-rl_backward_word (count)
-int count;
-{
-	int c;
-
-	if (count < 0)
-	{
-		rl_forward_word (-count);
-		return;
-	}
-
-	while (count)
-	{
-		if (!rl_point)
-			return;
-
-		/* Like rl_forward_word (), except that we look at the characters
-	 just before point. */
-
-		c = the_line[rl_point - 1];
-		if (!alphabetic (c))
-		{
-			while (--rl_point)
-			{
-				c = the_line[rl_point - 1];
-				if (alphabetic (c)) break;
-			}
-		}
-
-		while (rl_point)
-		{
-			c = the_line[rl_point - 1];
-			if (!alphabetic (c))
-				break;
-			else --rl_point;
-		}
-		--count;
-	}
-}
-
-/* Clear the current line.  Numeric argument to C-l does this. */
-rl_refresh_line ()
-{
-	int curr_line = last_c_pos / screenwidth;
-	extern char *term_clreol;
-
-	move_vert(curr_line);
-	move_cursor_relative (0, the_line);   /* XXX is this right */
-
-	if (term_clreol)
-		tputs (term_clreol, 1, output_character_function);
-
-	rl_forced_update_display ();
-	rl_display_fixed = 1;
-}
-
-/* C-l typed to a line without quoting clears the screen, and then reprints
-   the prompt and the current input line.  Given a numeric arg, redraw only
-   the current line. */
-rl_clear_screen ()
-{
-	extern char *term_clrpag;
-
-	if (rl_explicit_arg)
-	{
-		rl_refresh_line ();
-		return;
-	}
-
-	if (term_clrpag)
-		tputs (term_clrpag, 1, output_character_function);
-	else
-		crlf ();
-
-	rl_forced_update_display ();
-	rl_display_fixed = 1;
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Text commands				    */
-/*								    */
-/* **************************************************************** */
-
-/* Insert the character C at the current location, moving point forward. */
-rl_insert (count, c)
-int count, c;
-{
-	register int i;
-	char *string;
-
-	if (count <= 0)
-		return;
-
-	/* If we can optimize, then do it.  But don't let people crash
-     readline because of extra large arguments. */
-	if (count > 1 && count < 1024)
-	{
-		string = (char *)alloca (1 + count);
-
-		for (i = 0; i < count; i++)
-			string[i] = c;
-
-		string[i] = '\0';
-		rl_insert_text (string);
-		return;
-	}
-
-	if (count > 1024)
-	{
-		int decreaser;
-
-		string = (char *)alloca (1024 + 1);
-
-		for (i = 0; i < 1024; i++)
-			string[i] = c;
-
-		while (count)
-		{
-			decreaser = (count > 1024 ? 1024 : count);
-			string[decreaser] = '\0';
-			rl_insert_text (string);
-			count -= decreaser;
-		}
-		return;
-	}
-
-	/* We are inserting a single character.
-     If there is pending input, then make a string of all of the
-     pending characters that are bound to rl_insert, and insert
-     them all. */
-	if (any_typein)
-	{
-		int key = 0, t;
-
-		i = 0;
-		string = (char *)alloca (ibuffer_len + 1);
-		string[i++] = c;
-
-		while ((t = rl_get_char (&key)) &&
-		    (keymap[key].type == ISFUNC &&
-		    keymap[key].function == rl_insert))
-			string[i++] = key;
-
-		if (t)
-			rl_unget_char (key);
-
-		string[i] = '\0';
-		rl_insert_text (string);
-		return;
-	}
-	else
-	{
-		/* Inserting a single character. */
-		string = (char *)alloca (2);
-
-		string[1] = '\0';
-		string[0] = c;
-		rl_insert_text (string);
-	}
-}
-
-/* Insert the next typed character verbatim. */
-rl_quoted_insert (count)
-int count;
-{
-	int c = rl_read_key ();
-	rl_insert (count, c);
-}
-
-/* Insert a tab character. */
-rl_tab_insert (count)
-int count;
-{
-	rl_insert (count, '\t');
-}
-
-/* What to do when a NEWLINE is pressed.  We accept the whole line.
-   KEY is the key that invoked this command.  I guess it could have
-   meaning in the future. */
-rl_newline (count, key)
-int count, key;
-{
-
-	rl_done = 1;
-#ifdef VI_MODE
-	{
-		extern int vi_doing_insert;
-		if (vi_doing_insert)
-		{
-			rl_end_undo_group ();
-			vi_doing_insert = 0;
-		}
-	}
-#endif /* VI_MODE */
-
-	if (readline_echoing_p)
-	{
-		move_vert (vis_botlin);
-		vis_botlin = 0;
-		crlf ();
-		fflush (out_stream);
-		rl_display_fixed++;
-	}
-	rl_end_of_line(); 
-	rl_insert(1,'\n');  /* added by pjf */
-}
-
-rl_clean_up_for_exit ()
-{
-	if (readline_echoing_p)
-	{
-		move_vert (vis_botlin);
-		vis_botlin = 0;
-		fflush (out_stream);
-		rl_restart_output ();
-	}
-}
-
-/* What to do for some uppercase characters, like meta characters,
-   and some characters appearing in emacs_ctlx_keymap.  This function
-   is just a stub, you bind keys to it and the code in rl_dispatch ()
-   is special cased. */
-rl_do_lowercase_version (ignore1, ignore2)
-int ignore1, ignore2;
-{
-}
-
-/* Rubout the character behind point. */
-rl_rubout (count)
-int count;
-{
-	if (count < 0)
-	{
-		rl_delete (-count);
-		return;
-	}
-
-	if (!rl_point)
-	{
-		ding ();
-		return;
-	}
-
-	if (count > 1)
-	{
-		int orig_point = rl_point;
-		rl_backward (count);
-		rl_kill_text (orig_point, rl_point);
-	}
-	else
-	{
-		int c = the_line[--rl_point];
-		rl_delete_text (rl_point, rl_point + 1);
-
-		if (rl_point == rl_end && alphabetic (c) && last_c_pos)
-		{
-			backspace (1);
-			putc (' ', out_stream);
-			backspace (1);
-			last_c_pos--;
-			rl_display_fixed++;
-		}
-	}
-}
-
-/* Delete the character under the cursor.  Given a numeric argument,
-   kill that many characters instead. */
-rl_delete (count, invoking_key)
-int count, invoking_key;
-{
-	if (count < 0)
-	{
-		rl_rubout (-count);
-		return;
-	}
-
-	if (rl_point == rl_end)
-	{
-		ding ();
-		return;
-	}
-
-	if (count > 1)
-	{
-		int orig_point = rl_point;
-		rl_forward (count);
-		rl_kill_text (orig_point, rl_point);
-		rl_point = orig_point;
-	}
-	else
-		rl_delete_text (rl_point, rl_point + 1);
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Kill commands				    */
-/*								    */
-/* **************************************************************** */
-
-/* The next two functions mimic unix line editing behaviour, except they
-   save the deleted text on the kill ring.  This is safer than not saving
-   it, and since we have a ring, nobody should get screwed. */
-
-/* This does what C-w does in Unix.  We can't prevent people from
-   using behaviour that they expect. */
-rl_unix_word_rubout ()
-{
-	if (!rl_point) ding ();
-	else {
-		int orig_point = rl_point;
-		while (rl_point && whitespace (the_line[rl_point - 1]))
-			rl_point--;
-		while (rl_point && !whitespace (the_line[rl_point - 1]))
-			rl_point--;
-		rl_kill_text (rl_point, orig_point);
-	}
-}
-
-/* Here is C-u doing what Unix does.  You don't *have* to use these
-   key-bindings.  We have a choice of killing the entire line, or
-   killing from where we are to the start of the line.  We choose the
-   latter, because if you are a Unix weenie, then you haven't backspaced
-   into the line at all, and if you aren't, then you know what you are
-   doing.  (pjf: I disagree*/
-rl_unix_line_discard ()
-{
-	rl_end_of_line();
-	if (!rl_point) ding ();
-	else {
-		rl_kill_text (rl_point, 0);
-		rl_point = 0;
-	}
-}
-
-
-
-/* **************************************************************** */
-/*								    */
-/*			Commands For Typos			    */
-/*								    */
-/* **************************************************************** */
-
-/* Random and interesting things in here.  */
-
-
-/* **************************************************************** */
-/*								    */
-/*			Changing Case				    */
-/*								    */
-/* **************************************************************** */
-
-/* The three kinds of things that we know how to do. */
-#define UpCase 1
-#define DownCase 2
-#define CapCase 3
-
-/* Uppercase the word at point. */
-rl_upcase_word (count)
-int count;
-{
-	rl_change_case (count, UpCase);
-}
-
-/* Lowercase the word at point. */
-rl_downcase_word (count)
-int count;
-{
-	rl_change_case (count, DownCase);
-}
-
-/* Upcase the first letter, downcase the rest. */
-rl_capitalize_word (count)
-int count;
-{
-	rl_change_case (count, CapCase);
-}
-
-/* The meaty function.
-   Change the case of COUNT words, performing OP on them.
-   OP is one of UpCase, DownCase, or CapCase.
-   If a negative argument is given, leave point where it started,
-   otherwise, leave it where it moves to. */
-rl_change_case (count, op)
-int count, op;
-{
-	register int start = rl_point, end;
-	int state = 0;
-
-	rl_forward_word (count);
-	end = rl_point;
-
-	if (count < 0)
-	{
-		int temp = start;
-		start = end;
-		end = temp;
-	}
-
-	/* We are going to modify some text, so let's prepare to undo it. */
-	rl_modifying (start, end);
-
-	for (; start < end; start++)
-	{
-		switch (op)
-		{
-		case UpCase:
-			the_line[start] = to_upper (the_line[start]);
-			break;
-
-		case DownCase:
-			the_line[start] = to_lower (the_line[start]);
-			break;
-
-		case CapCase:
-			if (state == 0)
-			{
-				the_line[start] = to_upper (the_line[start]);
-				state = 1;
-			}
-			else
-			{
-				the_line[start] = to_lower (the_line[start]);
-			}
-			if (!pure_alphabetic (the_line[start]))
-				state = 0;
-			break;
-
-		default:
-			abort ();
-		}
-	}
-	rl_point = end;
-}
-
-/* **************************************************************** */
-/*								    */
-/*			Transposition				    */
-/*								    */
-/* **************************************************************** */
-
-/* Transpose the words at point. */
-rl_transpose_words (count)
-int count;
-{
-	char *word1, *word2;
-	int w1_beg, w1_end, w2_beg, w2_end;
-	int orig_point = rl_point;
-
-	if (!count) return;
-
-	/* Find the two words. */
-	rl_forward_word (count);
-	w2_end = rl_point;
-	rl_backward_word (1);
-	w2_beg = rl_point;
-	rl_backward_word (count);
-	w1_beg = rl_point;
-	rl_forward_word (1);
-	w1_end = rl_point;
-
-	/* Do some check to make sure that there really are two words. */
-	if ((w1_beg == w2_beg) || (w2_beg < w1_end))
-	{
-		ding ();
-		rl_point = orig_point;
-		return;
-	}
-
-	/* Get the text of the words. */
-	word1 = rl_copy (w1_beg, w1_end);
-	word2 = rl_copy (w2_beg, w2_end);
-
-	/* We are about to do many insertions and deletions.  Remember them
-     as one operation. */
-	rl_begin_undo_group ();
-
-	/* Do the stuff at word2 first, so that we don't have to worry
-     about word1 moving. */
-	rl_point = w2_beg;
-	rl_delete_text (w2_beg, w2_end);
-	rl_insert_text (word1);
-
-	rl_point = w1_beg;
-	rl_delete_text (w1_beg, w1_end);
-	rl_insert_text (word2);
-
-	/* This is exactly correct since the text before this point has not
-     changed in length. */
-	rl_point = w2_end;
-
-	/* I think that does it. */
-	rl_end_undo_group ();
-	free (word1); 
-	free (word2);
-}
-
-/* Transpose the characters at point.  If point is at the end of the line,
-   then transpose the characters before point. */
-rl_transpose_chars (count)
-int count;
-{
-	if (!count)
-		return;
-
-	if (!rl_point || rl_end < 2) {
-		ding ();
-		return;
-	}
-
-	while (count) {
-		if (rl_point == rl_end) {
-			int t = the_line[rl_point - 1];
-			the_line[rl_point - 1] = the_line[rl_point - 2];
-			the_line[rl_point - 2] = t;
-		} else {
-			int t = the_line[rl_point];
-			the_line[rl_point] = the_line[rl_point - 1];
-			the_line[rl_point - 1] = t;
-			if (count < 0 && rl_point)
-				rl_point--;
-			else
-				rl_point++;
-		}
-		if (count < 0)
-			count++;
-		else
-			count--;
-	}
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Bogus Flow Control      		    */
-/*								    */
-/* **************************************************************** */
-
-rl_restart_output (count, key)
-int count, key;
-{
-	int fildes = fileno (stdin);
-#ifdef TIOCSTART
-	ioctl (fildes, TIOCSTART, 0);
-#endif /* TIOCSTART */
-}
-
-/* **************************************************************** */
-/*								    */
-/*	Completion matching, from readline's point of view.	    */
-/*								    */
-/* **************************************************************** */
-
-/* Pointer to the generator function for completion_matches ().
-   NULL means to use filename_entry_function (), the default filename
-   completer. */
-Function *rl_completion_entry_function = (Function *)NULL;
-
-/* Pointer to alternative function to create matches.
-   Function is called with TEXT, START, and END.
-   START and END are indices in RL_LINE_BUFFER saying what the boundaries
-   of TEXT are.
-   If this function exists and returns NULL then call the value of
-   rl_completion_entry_function to try to match, otherwise use the
-   array of strings returned. */
-Function *rl_attempted_completion_function = (Function *)NULL;
-
-/* Complete the word at or before point.  You have supplied the function
-   that does the initial simple matching selection algorithm (see
-   completion_matches ()).  The default is to do filename completion. */
-rl_complete (ignore, invoking_key)
-int ignore, invoking_key;
-{
-	rl_complete_internal (TAB);
-}
-
-/* List the possible completions.  See description of rl_complete (). */
-rl_possible_completions ()
-{
-	rl_complete_internal ('?');
-}
-
-/* The user must press "y" or "n". Non-zero return means "y" pressed. */
-get_y_or_n ()
-{
-	int c;
-loop:
-	c = rl_read_key ();
-	if (c == 'y' || c == 'Y') return (1);
-	if (c == 'n' || c == 'N') return (0);
-	if (c == ABORT_CHAR) rl_abort ();
-	ding (); 
-	goto loop;
-}
-
-/* Up to this many items will be displayed in response to a
-   possible-completions call.  After that, we ask the user if
-   she is sure she wants to see them all. */
-int rl_completion_query_items = 100;
-
-/* The basic list of characters that signal a break between words for the
-   completer routine.  The contents of this variable is what breaks words
-   in the shell, i.e. " \t\n\"\\'`@><" */
-char *rl_basic_word_break_characters = " \t\n@><;(";
-
-/* The list of characters that signal a break between words for
-   rl_complete_internal.  The default list is the contents of
-   rl_basic_word_break_characters.  */
-char *rl_completer_word_break_characters = (char *)NULL;
-
-/* List of characters that are word break characters, but should be left
-   in TEXT when it is passed to the completion function.  The shell uses
-   this to help determine what kind of completing to do. */
-char *rl_special_prefixes = (char *)NULL;
-
-/* If non-zero, then disallow duplicates in the matches. */
-int rl_ignore_completion_duplicates = 1;
-
-/* Non-zero means that the results of the matches are to be treated
-   as filenames.  This is ALWAYS zero on entry, and can only be changed
-   within a completion entry finder function. */
-int rl_filename_completion_desired = 0;
-
-/* Complete the word at or before point.
-   WHAT_TO_DO says what to do with the completion.
-   `?' means list the possible completions.
-   TAB means do standard completion.
-   `*' means insert all of the possible completions. */
-rl_complete_internal (what_to_do)
-int what_to_do;
-{
-	char *filename_completion_function ();
-	char **completion_matches (), **matches;
-	Function *our_func;
-	int start, end,did = 0;
-	char *text;
-
-	if (rl_completion_entry_function)
-		our_func = rl_completion_entry_function;
-	else
-		our_func = (int (*)())filename_completion_function;
-
-	/* Only the completion entry function can change this. */
-	rl_filename_completion_desired = 0;
-
-	/* We now look backwards for the start of a filename/variable word. */
-	end = rl_point;
-	if (rl_point)
-	{
-		for(;;) {
-			while (--rl_point >= 0 &&
-			    !rindex (rl_completer_word_break_characters, the_line[rl_point]))
-				if (the_line[rl_point] == '`')
-					while(rl_point-- && the_line[rl_point] != '`');
-				else if (the_line[rl_point] == '\'')
-					while(rl_point-- && the_line[rl_point] != '\'');
-				else if (the_line[rl_point] == '\"')
-					while(rl_point-- && the_line[rl_point] != '\"');
-
-			if (rl_point < 0)
-				{
-				rl_point = end;
-				ding();
-				return 0;
-				}
-			if (rl_point == 0 || the_line[rl_point-1] != '\\')
-				break;
-			rl_point--;
-		}
-		/* If we are at a word break, then advance past it. */
-		if (rindex (rl_completer_word_break_characters,  (the_line[rl_point])))
-			rl_point++;
-	}
-
-	start = rl_point;
-	rl_point = end;
-	text = rl_copy (start, end);
-	text = docompsubs(text,&did);
-	rl_prep_terminal();
-	if (!text)
-		return 0;
-	if (did)
-	{
-		rl_delete_text (start, rl_point);
-		rl_point = start;
-		if (what_to_do == '?')
-			puts(text);
-		else if (did == 2)
-			rl_insert_text(text);
-		else
-			rl_safe_insert_text (text);
-		free(text);
-		return 0;
-	}
-	/* If the user wants to TRY to complete, but then wants to give
-     up and use the default completion function, they set the
-     variable rl_attempted_completion_function. */
-	if (rl_attempted_completion_function)
-	{
-		matches =
-		    (char **)(*rl_attempted_completion_function) (text, start, end);
-
-		if (matches)
-			goto after_usual_completion;
-	}
-
-	matches = completion_matches (text, our_func, start, end);
-
-after_usual_completion:
-	free (text);
-
-	if (!matches)
-		ding ();
-	else
-	{
-		register int i;
-
-some_matches:
-
-		/* It seems to me that in all the cases we handle we would like
-	 to ignore duplicate possiblilities.  Scan for the text to
-	 insert being identical to the other completions. */
-		if (rl_ignore_completion_duplicates)
-		{
-			char *lowest_common;
-			int j, newlen = 0;
-
-			/* Sort the items. */
-			/* It is safe to sort this array, because the lowest common
-	     denominator found in matches[0] will remain in place. */
-			for (i = 0; matches[i]; i++);
-			qsort (matches, i, sizeof (char *), compare_strings);
-
-			/* Remember the lowest common denimator for it may be unique. */
-			lowest_common = savestring (matches[0]);
-
-			for (i = 0; matches[i + 1]; i++)
-			{
-				if (strcmp (matches[i], matches[i + 1]) == 0)
-				{
-					free (matches[i]);
-					matches[i] = (char *)-1;
-				}
-				else
-					newlen++;
-			}
-
-			/* We have marked all the dead slots with (char *)-1.
-	     Copy all the non-dead entries into a new array. */
-			{
-				char **temp_array =
-				(char **)malloc ((3 + newlen) * sizeof (char *));
-
-				for (i = 1, j = 1; matches[i]; i++)
-					if (matches[i] != (char *)-1)
-						temp_array[j++] = matches[i];
-				temp_array[j] = (char *)NULL;
-
-				if (matches[0] != (char *)-1)
-					free (matches[0]);
-				free (matches);
-
-				matches = temp_array;
-			}
-
-			/* Place the lowest common denominator back in [0]. */
-			matches[0] = lowest_common;
-
-			/* If there is one string left, and it is identical to the
-	     lowest common denominator, then the LCD is the string to
-	     insert. */
-			if (j == 2 && strcmp (matches[0], matches[1]) == 0)
-			{
-				free (matches[1]);
-				matches[1] = (char *)NULL;
-			}
-		}
-
-		switch (what_to_do)
-		{
-		case TAB:
-			if (matches[0])
-			{
-				rl_delete_text (start, rl_point);
-				rl_point = start;
-				rl_safe_insert_text (matches[0]);
-			}
-
-			/* If there are more matches, ring the bell to indicate.
-	     If this was the only match, and we are hacking files,
-	     check the file to see if it was a directory.  If so,
-	     add a '/' to the name.  If not, and we are at the end
-	     of the line, then add a space. */
-			if (matches[1])
-			{
-			extern int opts[128];
-
-				ding ();		/* There are other matches remaining. */
-				if (opts['9'] == 2)
-					goto autolist;
-			}
-			else
-			{
-				char temp_string[2];
-
-				temp_string[0] = ' ';
-				temp_string[1] = '\0';
-
-				if (rl_filename_completion_desired)
-				{
-					struct stat finfo;
-					char *tilde_expand ();
-					char *filename = tilde_expand (matches[0]);
-
-					if ((stat (filename, &finfo) == 0) &&
-					    ((finfo.st_mode & S_IFMT) == S_IFDIR))
-					{
-						if (the_line[rl_point] != '/')
-							rl_insert_text ("/");
-					}
-					else
-					{
-						if (rl_point == rl_end)
-							rl_insert_text (temp_string);
-					}
-					free (filename);
-				}
-				else
-				{
-					if (rl_point == rl_end)
-						rl_insert_text (temp_string);
-				}
-			}
-			break;
-
-		case '*':
-			{
-				int i = 1;
-
-				rl_delete_text (start, rl_point);
-				rl_point = start;
-				rl_begin_undo_group ();
-				if (matches[1])
-				{
-					while (matches[i])
-					{
-						rl_safe_insert_text (matches[i++]);
-						rl_insert_text (" ");
-					}
-				}
-				else
-				{
-					rl_safe_insert_text (matches[0]);
-					rl_insert_text (" ");
-				}
-				rl_end_undo_group ();
-			}
-			break;
-
-
-		case '?':
-			{
-				int len, count, limit, max = 0;
-				int j, k, l;
-
-autolist:
-				/* Handle simple case first.  What if there is only one answer? */
-				if (!matches[1])
-				{
-					char *rindex (), *temp;
-
-					if (rl_filename_completion_desired)
-						temp = rindex (matches[0], '/');
-					else
-						temp = (char *)NULL;
-
-					if (!temp)
-						temp = matches[0];
-					else
-						temp++;
-
-					crlf ();
-					fprintf (out_stream, "%s", temp);
-					crlf ();
-					goto restart;
-				}
-
-				/* There is more than one answer.  Find out how many there are,
-	       and find out what the maximum printed length of a single entry
-	       is. */
-				for (i = 1; matches[i]; i++)
-				{
-					char *rindex (), *temp = (char *)NULL;
-
-					/* If we are hacking filenames, then only count the characters
-		   after the last slash in the pathname. */
-					if (rl_filename_completion_desired)
-						temp = rindex (matches[i], '/');
-					else
-						temp = (char *)NULL;
-
-					if (!temp)
-						temp = matches[i];
-					else
-						temp++;
-
-					if (strlen (temp) > max)
-						max = strlen (temp);
-				}
-
-				len = i;
-
-				/* If there are many items, then ask the user if she
-	       really wants to see them all. */
-				if (len >= rl_completion_query_items)
-				{
-					crlf ();
-					fprintf (out_stream,
-					    "There are %d possibilities.  Do you really", len);
-					crlf ();
-					fprintf (out_stream, "wish to see them all? (y or n)");
-					fflush (out_stream);
-					if (!get_y_or_n ())
-					{
-						crlf ();
-						goto restart;
-					}
-				}
-				/* How many items of MAX length can we fit in the screen window? */
-				max += 2;
-				limit = screenwidth / max;
-				if (limit != 1 && (limit * max == screenwidth))
-					limit--;
-
-				/* How many iterations of the printing loop? */
-				count = (len + (limit - 1)) / limit;
-
-				/* Watch out for special case.  If LEN is less than LIMIT, then
-	       just do the inner printing loop. */
-				if (len < limit) count = 1;
-
-				/* Sort the items if they are not already sorted. */
-				if (!rl_ignore_completion_duplicates)
-					qsort (matches, len, sizeof (char *), compare_strings);
-
-				/* Print the sorted items, up-and-down alphabetically, like
-	       ls might. */
-				crlf ();
-
-				for (i = 1; i < count + 1; i++)
-				{
-					for (j = 0, l = i; j < limit; j++)
-					{
-						if (l > len || !matches[l])
-						{
-							break;
-						}
-						else
-						{
-							char *rindex (), *temp = (char *)NULL;
-
-							if (rl_filename_completion_desired)
-								temp = rindex (matches[l], '/');
-							else
-								temp = (char *)NULL;
-
-							if (!temp)
-								temp = matches[l];
-							else
-								temp++;
-
-							fprintf (out_stream, "%s", temp);
-							for (k = 0; k < max - strlen (temp); k++)
-								putc (' ', out_stream);
-						}
-						l += count;
-					}
-					crlf ();
-				}
-restart:
-
-				rl_on_new_line ();
-			}
-			break;
-
-		default:
-			abort ();
-		}
-
-		for (i = 0; matches[i]; i++)
-			free (matches[i]);
-		free (matches);
-	}
-}
-
-/* Stupid comparison routine for qsort () ing strings. */
-static int
-compare_strings (s1, s2)
-char **s1, **s2;
-{
-	return (strcmp (*s1, *s2));
-}
-
-/* If non-null, this contains the address of a function to call if the
-   standard meaning for expanding a tilde fails.  The function is called
-   with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
-   which is the expansion, or a NULL pointer if there is no expansion. */
-Function *rl_tilde_expander = (Function *)NULL;
-
-/* Expand FILENAME if it begins with a tilde.  This always returns
-   a new string. */
-char *
-tilde_expand (filename)
-char *filename;
-{
-	char *dirname = filename ? savestring (filename) : (char *)NULL;
-
-	if (dirname && *dirname == '~')
-	{
-		char *temp_name;
-		if (!dirname[1] || dirname[1] == '/')
-		{
-			/* Prepend $HOME to the rest of the string. */
-			char *temp_home = (char *)getenv ("HOME");
-
-			temp_name = (char *)alloca (1 + strlen (&dirname[1])
-			    + (temp_home? strlen (temp_home) : 0));
-			temp_name[0] = '\0';
-			if (temp_home)
-				strcpy (temp_name, temp_home);
-			strcat (temp_name, &dirname[1]);
-			free (dirname);
-			dirname = savestring (temp_name);
-		}
-		else
-		{
-			struct passwd *getpwnam (), *user_entry;
-			char *username = (char *)alloca (257);
-			int i, c;
-
-			for (i = 1; c = dirname[i]; i++)
-			{
-				if (c == '/') break;
-				else username[i - 1] = c;
-			}
-			username[i - 1] = '\0';
-
-			if (!(user_entry = getpwnam (username)))
-			{
-				/* If the calling program has a special syntax for
-		 expanding tildes, and we couldn't find a standard
-		 expansion, then let them try. */
-				if (rl_tilde_expander)
-				{
-					char *expansion;
-
-					expansion = (char *)(*rl_tilde_expander) (username);
-
-					if (expansion)
-					{
-						temp_name = (char *)alloca (1 + strlen (expansion)
-						    + strlen (&dirname[i]));
-						strcpy (temp_name, expansion);
-						strcat (temp_name, &dirname[i]);
-						free (expansion);
-						goto return_name;
-					}
-				}
-				/*
-	       * We shouldn't report errors.
-	       */
-			}
-			else
-			{
-				temp_name = (char *)alloca (1 + strlen (user_entry->pw_dir)
-				    + strlen (&dirname[i]));
-				strcpy (temp_name, user_entry->pw_dir);
-				strcat (temp_name, &dirname[i]);
-return_name:
-				free (dirname);
-				dirname = savestring (temp_name);
-			}
-		}
-	}
-	return (dirname);
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Undo, and Undoing			    */
-/*								    */
-/* **************************************************************** */
-
-/* Non-zero tells rl_delete_text and rl_insert_text to not add to
-   the undo list. */
-int doing_an_undo = 0;
-
-/* The current undo list for THE_LINE. */
-UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
-
-/* Remember how to undo something.  Concatenate some undos if that
-   seems right. */
-rl_add_undo (what, start, end, text)
-enum undo_code what;
-int start, end;
-char *text;
-{
-	UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
-	temp->what = what;
-	temp->start = start;
-	temp->end = end;
-	temp->text = text;
-	temp->next = rl_undo_list;
-	rl_undo_list = temp;
-}
-
-/* Free the existing undo list. */
-free_undo_list ()
-{
-	while (rl_undo_list) {
-		UNDO_LIST *release = rl_undo_list;
-		rl_undo_list = rl_undo_list->next;
-
-		if (release->what == UNDO_DELETE)
-			free (release->text);
-
-		free (release);
-	}
-}
-
-/* Undo the next thing in the list.  Return 0 if there
-   is nothing to undo, or non-zero if there was. */
-int
-rl_do_undo ()
-{
-	UNDO_LIST *release;
-	int waiting_for_begin = 0;
-
-undo_thing:
-	if (!rl_undo_list)
-		return (0);
-
-	doing_an_undo = 1;
-
-	switch (rl_undo_list->what) {
-
-		/* Undoing deletes means inserting some text. */
-	case UNDO_DELETE:
-		rl_point = rl_undo_list->start;
-		rl_insert_text (rl_undo_list->text);
-		free (rl_undo_list->text);
-		break;
-
-		/* Undoing inserts means deleting some text. */
-	case UNDO_INSERT:
-		rl_delete_text (rl_undo_list->start, rl_undo_list->end);
-		rl_point = rl_undo_list->start;
-		break;
-
-		/* Undoing an END means undoing everything 'til we get to
-       a BEGIN. */
-	case UNDO_END:
-		waiting_for_begin++;
-		break;
-
-		/* Undoing a BEGIN means that we are done with this group. */
-	case UNDO_BEGIN:
-		if (waiting_for_begin)
-			waiting_for_begin--;
-		else
-			abort ();
-		break;
-	}
-
-	doing_an_undo = 0;
-
-	release = rl_undo_list;
-	rl_undo_list = rl_undo_list->next;
-	free (release);
-
-	if (waiting_for_begin)
-		goto undo_thing;
-
-	return (1);
-}
-
-/* Begin a group.  Subsequent undos are undone as an atomic operation. */
-rl_begin_undo_group ()
-{
-	rl_add_undo (UNDO_BEGIN, 0, 0, 0);
-}
-
-/* End an undo group started with rl_begin_undo_group (). */
-rl_end_undo_group ()
-{
-	rl_add_undo (UNDO_END, 0, 0, 0);
-}
-
-/* Save an undo entry for the text from START to END. */
-rl_modifying (start, end)
-int start, end;
-{
-	if (start > end)
-	{
-		int t = start;
-		start = end;
-		end = t;
-	}
-
-	if (start != end)
-	{
-		char *temp = rl_copy (start, end);
-		rl_begin_undo_group ();
-		rl_add_undo (UNDO_DELETE, start, end, temp);
-		rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);
-		rl_end_undo_group ();
-	}
-}
-
-/* Revert the current line to its previous state. */
-rl_revert_line ()
-{
-	if (!rl_undo_list) ding ();
-	else {
-		while (rl_undo_list)
-			rl_do_undo ();
-	}
-}
-
-/* Do some undoing of things that were done. */
-rl_undo_command (count)
-{
-	if (count < 0) return;	/* Nothing to do. */
-
-	while (count)
-	{
-		if (rl_do_undo ())
-		{
-			count--;
-		}
-		else
-		{
-			ding ();
-			break;
-		}
-	}
-}
-
-/* **************************************************************** */
-/*								    */
-/*			History Utilities			    */
-/*								    */
-/* **************************************************************** */
-
-/* We already have a history library, and that is what we use to control
-   the history features of readline.  However, this is our local interface
-   to the history mechanism. */
-
-/* While we are editing the history, this is the saved
-   version of the original line. */
-HIST_ENTRY *saved_line_for_history = (HIST_ENTRY *)NULL;
-
-/* Set the history pointer back to the last entry in the history. */
-start_using_history ()
-{
-	using_history ();
-	if (saved_line_for_history)
-		free_history_entry (saved_line_for_history);
-
-	saved_line_for_history = (HIST_ENTRY *)NULL;
-}
-
-/* Free the contents (and containing structure) of a HIST_ENTRY. */
-free_history_entry (entry)
-HIST_ENTRY *entry;
-{
-	if (!entry) return;
-	if (entry->line)
-		free (entry->line);
-	free (entry);
-}
-
-/* Perhaps put back the current line if it has changed. */
-maybe_replace_line ()
-{
-	HIST_ENTRY *temp = current_history ();
-
-	/* If the current line has changed, save the changes. */
-	if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list)) {
-		free (temp->line);
-		free (temp);
-	}
-}
-
-/* Put back the saved_line_for_history if there is one. */
-maybe_unsave_line ()
-{
-	if (saved_line_for_history) {
-		strcpy (the_line, saved_line_for_history->line);
-		rl_undo_list = (UNDO_LIST *)saved_line_for_history->data;
-		free_history_entry (saved_line_for_history);
-		saved_line_for_history = (HIST_ENTRY *)NULL;
-		rl_end = rl_point = strlen (the_line);
-	} else {
-		ding ();
-	}
-}
-
-/* Save the current line in saved_line_for_history. */
-maybe_save_line ()
-{
-	if (!saved_line_for_history) {
-		saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
-		saved_line_for_history->line = savestring (the_line);
-		saved_line_for_history->data = (char *)rl_undo_list;
-	}
-}
-
-
-
-/* **************************************************************** */
-/*								    */
-/*			History Commands			    */
-/*								    */
-/* **************************************************************** */
-
-/* Meta-< goes to the start of the history. */
-rl_beginning_of_history ()
-{
-	rl_get_previous_history (1 + where_history ());
-}
-
-/* Meta-> goes to the end of the history.  (The current line). */
-rl_end_of_history ()
-{
-	maybe_replace_line ();
-	using_history ();
-	maybe_unsave_line ();
-}
-
-/* Move down to the next history line. */
-rl_get_next_history (count)
-int count;
-{
-	HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
-
-	if (count < 0)
-	{
-		rl_get_previous_history (-count);
-		return;
-	}
-
-	if (!count)
-		return;
-
-	maybe_replace_line ();
-
-	while (count)
-	{
-		temp = next_history ();
-		if (!temp)
-			break;
-		if (--count)
-			free(temp);
-	}
-
-	if (!temp)
-		maybe_unsave_line ();
-	else
-	{
-		free(temp);
-		strcpy (the_line, temp->line);
-		rl_undo_list = (UNDO_LIST *)temp->data;
-		rl_end = rl_point = strlen (the_line);
-	}
-}
-
-/* Get the previous item out of our interactive history, making it the current
-   line.  If there is no previous history, just ding. */
-rl_get_previous_history (count)
-int count;
-{
-	HIST_ENTRY *old_temp = (HIST_ENTRY *)NULL;
-	HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
-
-	if (count < 0)
-	{
-		rl_get_next_history (-count);
-		return;
-	}
-
-	if (!count)
-		return;
-
-	/* If we don't have a line saved, then save this one. */
-	maybe_save_line ();
-
-	/* If the current line has changed, save the changes. */
-	maybe_replace_line ();
-
-	while (count)
-	{
-		temp = previous_history ();
-		if (!temp)
-			break;
-		else
-			old_temp = temp;
-		if (--count)
-			free(temp);
-	}
-
-	/* If there was a large argument, and we moved back to the start of the
-     history, that is not an error.  So use the last value found. */
-	if (!temp && old_temp)
-		temp = old_temp;
-
-	if (!temp)
-		ding ();
-	else
-	{
-		strcpy (the_line, temp->line);
-		rl_undo_list = (UNDO_LIST *)temp->data;
-		rl_end = rl_point = strlen (the_line);
-#ifdef VI_MODE
-		if (rl_editing_mode == vi_mode)
-			rl_point = 0;
-#endif /* VI_MODE */
-	}
-}
-
-/* There is a command in ksh which yanks into this line, the last word
-   of the previous line.  Here it is.  We left it on M-. */
-rl_yank_previous_last_arg (ignore)
-int ignore;
-{
-}
-
-/* Make C be the next command to be executed. */
-rl_execute_next (c)
-int c;
-{
-	rl_pending_input = c;
-}
-
-/* **************************************************************** */
-/*								    */
-/*			Killing Mechanism			    */
-/*								    */
-/* **************************************************************** */
-
-/* What we assume for a max number of kills. */
-#define DEFAULT_MAX_KILLS 10
-
-/* The real variable to look at to find out when to flush kills. */
-int rl_max_kills = DEFAULT_MAX_KILLS;
-
-/* Where to store killed text. */
-char **rl_kill_ring = (char **)NULL;
-
-/* Where we are in the kill ring. */
-int rl_kill_index = 0;
-
-/* How many slots we have in the kill ring. */
-int rl_kill_ring_length = 0;
-
-/* How to say that you only want to save a certain amount
-   of kill material. */
-rl_set_retained_kills (num)
-int num;
-{
-}
-
-/* The way to kill something.  This appends or prepends to the last
-   kill, if the last command was a kill command.  if FROM is less
-   than TO, then the text is appended, otherwise prepended.  If the
-   last command was not a kill command, then a new slot is made for
-   this kill. */
-rl_kill_text (from, to)
-int from, to;
-{
-	int slot;
-	char *text = rl_copy (from, to);
-
-	/* Is there anything to kill? */
-	if (from == to) {
-		free (text);
-		last_command_was_kill++;
-		return;
-	}
-
-	/* Delete the copied text from the line. */
-	rl_delete_text (from, to);
-
-	/* First, find the slot to work with. */
-	if (!last_command_was_kill) {
-
-		/* Get a new slot.  */
-		if (!rl_kill_ring) {
-
-			/* If we don't have any defined, then make one. */
-			rl_kill_ring =
-			    (char **)xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
-			slot = 1;
-
-		} else {
-
-			/* We have to add a new slot on the end, unless we have exceeded
-	 the max limit for remembering kills. */
-			slot = rl_kill_ring_length;
-			if (slot == rl_max_kills) {
-				register int i;
-				free (rl_kill_ring[0]);
-				for (i = 0; i < slot; i++)
-					rl_kill_ring[i] = rl_kill_ring[i + 1];
-			} else {
-				rl_kill_ring =
-				    (char **)xrealloc (rl_kill_ring,
-				    ((slot = (rl_kill_ring_length += 1)) + 1)
-				    * sizeof (char *));
-			}
-		}
-		slot--;
-	} else {
-		slot = rl_kill_ring_length - 1;
-	}
-
-	/* If the last command was a kill, prepend or append. */
-	if (last_command_was_kill) {
-		char *old = rl_kill_ring[slot];
-		char *new = (char *)xmalloc (1 + strlen (old) + strlen (text));
-
-		if (from < to) {
-			strcpy (new, old);
-			strcat (new, text);
-		} else {
-			strcpy (new, text);
-			strcat (new, old);
-		}
-		free (old);
-		free (text);
-		rl_kill_ring[slot] = new;
-	} else {
-		rl_kill_ring[slot] = text;
-	}
-	rl_kill_index = slot;
-	last_command_was_kill++;
-}
-
-/* Now REMEMBER!  In order to do prepending or appending correctly, kill
-   commands always make rl_point's original position be the FROM argument,
-   and rl_point's extent be the TO argument. */
-
-
-/* **************************************************************** */
-/*								    */
-/*			Killing Commands			    */
-/*								    */
-/* **************************************************************** */
-
-/* Delete the word at point, saving the text in the kill ring. */
-rl_kill_word (count)
-int count;
-{
-	int orig_point = rl_point;
-
-	if (count < 0)
-		rl_backward_kill_word (-count);
-	else
-	{
-		rl_forward_word (count);
-
-		if (rl_point != orig_point)
-			rl_kill_text (orig_point, rl_point);
-
-		rl_point = orig_point;
-	}
-}
-
-/* Rubout the word before point, placing it on the kill ring. */
-rl_backward_kill_word (count)
-int count;
-{
-	int orig_point = rl_point;
-
-	if (count < 0)
-		rl_kill_word (-count);
-	else
-	{
-		rl_backward_word (count);
-
-		if (rl_point != orig_point)
-			rl_kill_text (orig_point, rl_point);
-	}
-}
-
-/* Kill from here to the end of the line.  If DIRECTION is negative, kill
-   back to the line start instead. */
-rl_kill_line (direction)
-int direction;
-{
-	int orig_point = rl_point;
-
-	if (direction < 0)
-		rl_backward_kill_line (1);
-	else
-	{
-		rl_end_of_line ();
-		if (orig_point != rl_point)
-			rl_kill_text (orig_point, rl_point);
-		rl_point = orig_point;
-	}
-}
-
-/* Kill backwards to the start of the line.  If DIRECTION is negative, kill
-   forwards to the line end instead. */
-rl_backward_kill_line (direction)
-int direction;
-{
-	int orig_point = rl_point;
-
-	if (direction < 0)
-		rl_kill_line (1);
-	else
-	{
-		if (!rl_point)
-			ding ();
-		else
-		{
-			rl_beg_of_line ();
-			rl_kill_text (orig_point, rl_point);
-		}
-	}
-}
-
-/* Yank back the last killed text.  This ignores arguments. */
-rl_yank ()
-{
-	if (!rl_kill_ring) rl_abort ();
-	rl_insert_text (rl_kill_ring[rl_kill_index]);
-}
-
-/* If the last command was yank, or yank_pop, and the text just
-   before point is identical to the current kill item, then
-   delete that text from the line, rotate the index down, and
-   yank back some other text. */
-rl_yank_pop ()
-{
-	int l;
-
-	if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
-	    !rl_kill_ring)
-	{
-		rl_abort ();
-	}
-
-	l = strlen (rl_kill_ring[rl_kill_index]);
-	if (((rl_point - l) >= 0) &&
-	    (strncmp (the_line + (rl_point - l),
-	    rl_kill_ring[rl_kill_index], l) == 0))
-	{
-		rl_delete_text ((rl_point - l), rl_point);
-		rl_point -= l;
-		rl_kill_index--;
-		if (rl_kill_index < 0)
-			rl_kill_index = rl_kill_ring_length - 1;
-		rl_yank ();
-	}
-	else
-		rl_abort ();
-
-}
-
-extern char *extracthistarg();
-
-/* Yank the COUNTth argument from the previous history line. */
-rl_yank_nth_arg (count, ignore)
-int count;
-{
-char *arg;
-
-	arg = extracthistarg(count);
-	if (!arg || !*arg)
-	{
-		ding ();
-		return;
-	}
-
-	rl_begin_undo_group ();
-	if (rl_point && the_line[rl_point - 1] != ' ')
-		rl_insert_text (" ");
-	rl_insert_text (arg);
-	free (arg);
-	rl_end_undo_group ();
-}
-
-/* Vi Mode. */
-#ifdef VI_MODE
-#include "vi_mode.c"
-#endif /* VI_MODE */
-
-/* How to toggle back and forth between editing modes. */
-rl_vi_editing_mode ()
-{
-#ifdef VI_MODE
-	rl_editing_mode = vi_mode;
-	rl_vi_insertion_mode ();
-#endif /* VI_MODE */
-}
-
-rl_emacs_editing_mode ()
-{
-	rl_editing_mode = emacs_mode;
-	keymap = emacs_standard_keymap;
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			     Completion				    */
-/*								    */
-/* **************************************************************** */
-
-/* Non-zero means that case is not significant in completion. */
-int completion_case_fold = 0;
-
-/* Return an array of (char *) which is a list of completions for TEXT.
-   If there are no completions, return a NULL pointer.
-   The first entry in the returned array is the substitution for TEXT.
-    The remaining entries are the possible completions.
-   The array is terminated with a NULL pointer.
-
-   ENTRY_FUNCTION is a function of two args, and returns a (char *).
-     The first argument is TEXT.
-     The second is a state argument; it should be zero on the first call, and
-     non-zero on subsequent calls.  It returns a NULL pointer to the caller
-     when there are no more matches.
- */
-char **
-completion_matches (text, entry_function)
-char *text;
-char *(*entry_function) ();
-{
-	/* Number of slots in match_list. */
-	int match_list_size;
-
-	/* The list of matches. */
-	char **match_list =
-	(char **)xmalloc (((match_list_size = 10) + 1) * sizeof (char *));
-
-	/* Number of matches actually found. */
-	int matches = 0;
-
-	/* Temporary string binder. */
-	char *string;
-
-	match_list[1] = (char *)NULL;
-
-	while (string = (*entry_function) (text, matches))
-	{
-		if (matches + 1 == match_list_size)
-			match_list =
-			    (char **)xrealloc (match_list,
-			    ((match_list_size += 10) + 1) * sizeof (char *));
-
-		match_list[++matches] = string;
-		match_list[matches + 1] = (char *)NULL;
-	}
-
-	/* If there were any matches, then look through them finding out the
-     lowest common denominator.  That then becomes match_list[0]. */
-	if (matches)
-	{
-		register int i = 1;
-		int low = 100000;		/* Count of max-matched characters. */
-
-		/* If only one match, just use that. */
-		if (matches == 1)
-		{
-			match_list[0] = match_list[1];
-			match_list[1] = (char *)NULL;
-		}
-		else
-		{
-			/* Otherwise, compare each member of the list with
-	     the next, finding out where they stop matching. */
-
-			while (i < matches)
-			{
-				register int c1, c2, si;
-
-				if (completion_case_fold)
-				{
-					for (si = 0;
-					    (c1 = to_lower(match_list[i][si])) &&
-					    (c2 = to_lower(match_list[i + 1][si]));
-					    si++)
-						if (c1 != c2) break;
-				}
-				else
-				{
-					for (si = 0;
-					    (c1 = match_list[i][si]) &&
-					    (c2 = match_list[i + 1][si]);
-					    si++)
-						if (c1 != c2) break;
-				}
-
-				if (low > si) low = si;
-				i++;
-			}
-			match_list[0] = (char *)xmalloc (low + 1);
-			strncpy (match_list[0], match_list[1], low);
-			match_list[0][low] = '\0';
-		}
-	}
-	else	/* There were no matches. */
-	{
-		free (match_list);
-		match_list = (char **)NULL;
-	}
-	return (match_list);
-}
-
-/* Okay, now we write the entry_function for filename completion.  In the
-   general case.  Note that completion in the shell is a little different
-   because of all the pathnames that must be followed when looking up the
-   completion for a command. */
-char *
-filename_completion_function (text, state)
-int state;
-char *text;
-{
-	static DIR *directory;
-	static char *filename = (char *)NULL;
-	static char *dirname = (char *)NULL;
-	static char *users_dirname = (char *)NULL;
-	static int filename_len;
-
-	struct direct *entry = (struct direct *)NULL;
-
-	/* If we don't have any state, then do some initialization. */
-	if (!state)
-	{
-		char *rindex (), *temp;
-
-		if (dirname) free (dirname);
-		if (filename) free (filename);
-		if (users_dirname) free (users_dirname);
-
-		filename = savestring (text);
-		if (!*text) text = ".";
-		dirname = savestring (text);
-
-		temp = rindex (dirname, '/');
-
-		if (temp)
-		{
-			strcpy (filename, ++temp);
-			*temp = '\0';
-		}
-		else
-			strcpy (dirname, ".");
-
-		/* We aren't done yet.  We also support the "~user" syntax. */
-
-		/* Save the version of the directory that the user typed. */
-		users_dirname = savestring (dirname);
-		directory = opendir (dirname);
-		filename_len = strlen (filename);
-
-		rl_filename_completion_desired = 1;
-	}
-
-	/* At this point we should entertain the possibility of hacking wildcarded
-     filenames, like /usr/man*\/te<TAB>.  If the directory name contains
-     globbing characters, then build an array of directories to glob on, and
-     glob on the first one. */
-
-	/* Now that we have some state, we can read the directory. */
-
-	while (directory && (entry = readdir (directory)))
-	{
-		/* Special case for no filename.
-	 All entries except "." and ".." match. */
-		if (!filename_len)
-		{
-			if ((strcmp (entry->d_name, ".") != 0) &&
-			    (strcmp (entry->d_name, "..") != 0))
-				break;
-		}
-		else
-		{
-			/* Otherwise, if these match upto the length of filename, then
-	     it is a match. */
-#ifdef TMB_SYSV
-			if ((strlen (entry->d_name) >= filename_len) &&
-			    (strncmp (filename, entry->d_name, filename_len) == 0))
-#else
-				if ((entry->d_namlen >= filename_len) &&
-				    (strncmp (filename, entry->d_name, filename_len) == 0))
-#endif /* TMB_SYSV */
-				{
-					break;
-				}
-		}
-	}
-
-	if (!entry)
-	{
-		if (directory)
-		{
-			closedir (directory);
-			directory = (DIR *)NULL;
-		}
-		return (char *)NULL;
-	}
-	else
-	{
-		char *temp;
-
-		if (dirname && (strcmp (dirname, ".") != 0))
-		{
-#ifdef TMB_SYSV
-			temp = (char *)xmalloc (1 + strlen (users_dirname)
-			    + strlen (entry->d_name));
-#else
-			temp = (char *)xmalloc (1 + strlen (users_dirname)
-			    + entry->d_namlen);
-#endif /* TMB_SYSV */
-			strcpy (temp, users_dirname);
-			strcat (temp, entry->d_name);
-		}
-		else
-		{
-			temp = (savestring (entry->d_name));
-		}
-		return (temp);
-	}
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Binding keys				    */
-/*								    */
-/* **************************************************************** */
-
-/* rl_add_defun (char *name, Function *function, int key)
-   Add NAME to the list of named functions.  Make FUNCTION
-   be the function that gets called.
-   If KEY is not -1, then bind it. */
-rl_add_defun (name, function, key)
-char *name;
-Function *function;
-int key;
-{
-	if (key != -1)
-		rl_bind_key (key, function);
-	rl_add_funmap_entry (name, function);
-}
-
-/* Bind KEY to FUNCTION.  Returns non-zero if KEY is out of range. */
-int
-rl_bind_key (key, function)
-int key;
-Function *function;
-{
-	if (key < 0)
-		return (key);
-
-	if (key > 127 && key < 256)
-	{
-		if (keymap[ESC].type == ISKMAP)
-		{
-			Keymap escmap = (Keymap)keymap[ESC].function;
-
-			key -= 128;
-			escmap[key].type = ISFUNC;
-			escmap[key].function = function;
-			return (0);
-		}
-		return (key);
-	}
-
-	keymap[key].type = ISFUNC;
-	keymap[key].function = function;
-	return (0);
-}
-
-/* Bind KEY to FUNCTION in MAP.  Returns non-zero in case of invalid
-   KEY. */
-int
-rl_bind_key_in_map (key, function, map)
-int key;
-Function *function;
-Keymap map;
-{
-	int result;
-	Keymap oldmap = keymap;
-
-	keymap = map;
-	result = rl_bind_key (key, function);
-	keymap = oldmap;
-	return (result);
-}
-
-/* Make KEY do nothing in the currently selected keymap.
-   Returns non-zero in case of error. */
-int
-rl_unbind_key (key)
-int key;
-{
-	return (rl_bind_key (key, (Function *)NULL));
-}
-
-/* Make KEY do nothing in MAP.
-   Returns non-zero in case of error. */
-int
-rl_unbind_key_in_map (key, map)
-int key;
-Keymap map;
-{
-	return (rl_bind_key_in_map (key, (Function *)NULL, map));
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
-   FUNCTION.  This makes new keymaps as necessary.  The initial
-   place to do bindings is in MAP. */
-rl_set_key (keyseq, function, map)
-char *keyseq;
-Function *function;
-Keymap map;
-{
-	rl_generic_bind (ISFUNC, keyseq, function, map);
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
-   the string of characters MACRO.  This makes new keymaps as
-   necessary.  The initial place to do bindings is in MAP. */
-rl_macro_bind (keyseq, macro, map)
-char *keyseq, *macro;
-Keymap map;
-{
-	char *macro_keys = (char *)xmalloc (2 * (strlen (macro)));
-	int macro_keys_len;
-
-	if (rl_translate_keyseq (macro, macro_keys, &macro_keys_len))
-	{
-		free (macro_keys);
-		return;
-	}
-	rl_generic_bind (ISMACR, keyseq, macro_keys, map);
-}
-
-/* Bind the key sequence represented by the string KEYSEQ to
-   the arbitrary pointer DATA.  TYPE says what kind of data is
-   pointed to by DATA, right now this can be a function (ISFUNC),
-   a macro (ISMACR), or a keymap (ISKMAP).  This makes new keymaps
-   as necessary.  The initial place to do bindings is in MAP. */
-rl_generic_bind (type, keyseq, data, map)
-int type;
-char *keyseq, *data;
-Keymap map;
-{
-	char *keys;
-	int keys_len;
-	register int i;
-
-	/* If no keys to bind to, exit right away. */
-	if (!keyseq || !*keyseq)
-	{
-		if (type == ISMACR)
-			free (data);
-		return;
-	}
-
-	keys = (char *)alloca (1 + (2 * strlen (keyseq)));
-
-	/* Translate the ASCII representation of KEYSEQ into an array
-     of characters.  Stuff the characters into ARRAY, and the
-     length of ARRAY into LENGTH. */
-	if (rl_translate_keyseq (keyseq, keys, &keys_len))
-		return;
-
-	/* Bind keys, making new keymaps as necessary. */
-	for (i = 0; i < keys_len; i++)
-	{
-		if (i + 1 < keys_len)
-		{
-			if (map[keys[i]].type != ISKMAP)
-			{
-				if (map[i].type == ISMACR)
-					free ((char *)map[i].function);
-
-				map[keys[i]].type = ISKMAP;
-				map[keys[i]].function = (Function *)rl_make_bare_keymap ();
-			}
-			map = (Keymap)map[keys[i]].function;
-		}
-		else
-		{
-			if (map[keys[i]].type == ISMACR)
-				free ((char *)map[keys[i]].function);
-
-			map[keys[i]].function = (Function *)data;
-			map[keys[i]].type = type;
-		}
-	}
-}
-
-/* Translate the ASCII representation of SEQ, stuffing the
-   values into ARRAY, an array of characters.  LEN gets the
-   final length of ARRAY.  Return non-zero if there was an
-   error parsing SEQ. */
-rl_translate_keyseq (seq, array, len)
-char *seq, *array;
-int *len;
-{
-	register int i, c, l = 0;
-
-	for (i = 0; c = seq[i]; i++)
-	{
-		if (c == '\\')
-		{
-			c = seq[++i];
-
-			if (!c)
-				break;
-
-			if (((c == 'C' || c == 'M') &&  seq[i + 1] == '-') ||
-			    (c == 'e'))
-			{
-				/* Handle special case of backwards define. */
-				if (strncmp (&seq[i], "C-\\M-", 5) == 0)
-				{
-					array[l++] = ESC;
-					i += 5;
-					array[l++] = CTRL (to_upper (seq[i]));
-					if (!seq[i])
-						i--;
-					continue;
-				}
-
-				switch (c)
-				{
-				case 'M':
-					i++;
-					array[l++] = ESC;
-					break;
-
-				case 'C':
-					i += 2;
-					array[l++] = CTRL (to_upper (seq[i]));
-					break;
-
-				case 'e':
-					array[l++] = ESC;
-				}
-
-				continue;
-			}
-		}
-		array[l++] = c;
-	}
-
-	*len = l;
-	array[l] = '\0';
-	return (0);
-}
-
-/* Return a pointer to the function that STRING represents.
-   If STRING doesn't have a matching function, then a NULL pointer
-   is returned. */
-Function *
-rl_named_function (string)
-char *string;
-{
-	register int i;
-
-	for (i = 0; funmap[i]; i++)
-		if (stricmp (funmap[i]->name, string) == 0)
-			return (funmap[i]->function);
-	return ((Function *)NULL);
-}
-
---cut here---cut here---cut here---

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

---cut here---cut here---cut here---
-/* The last key bindings file read. */
-static char *last_readline_init_file = "~/.inputrc";
-
-/* Re-read the current keybindings file. */
-rl_re_read_init_file (count, ignore)
-int count, ignore;
-{
-	rl_read_init_file (last_readline_init_file);
-}
-
-/* Do key bindings from a file.  If FILENAME is NULL it defaults
-   to `~/.inputrc'.  If the file existed and could be opened and
-   read, 0 is returned, otherwise errno is returned. */
-int
-rl_read_init_file (filename)
-char *filename;
-{
-	extern int errno;
-	int line_size, line_index;
-	char *line = (char *)xmalloc (line_size = 100);
-	char *openname;
-	FILE *file;
-
-	int c;
-
-	/* Default the filename. */
-	if (!filename)
-		filename = "~/.inputrc";
-
-	openname = tilde_expand (filename);
-
-	/* Open the file. */
-	file = fopen (openname, "r");
-	free (openname);
-
-	if (!file)
-		return (errno);
-
-	last_readline_init_file = filename;
-
-	/* Loop reading lines from the file.  Lines that start with `#' are
-     comments, all other lines are commands for readline initialization. */
-	while ((c = rl_getc (file)) != EOF)
-	{
-		/* If comment, flush to EOL. */
-		if (c == '#')
-		{
-			while ((c = rl_getc (file)) != EOF && c != '\n');
-			if (c == EOF)
-				goto function_exit;
-			continue;
-		}
-
-		/* Otherwise, this is the start of a line.  Read the
-	 line from the file. */
-		line_index = 0;
-		while (c != EOF && c != '\n')
-		{
-			line[line_index++] = c;
-			if (line_index == line_size)
-				line = (char *)xrealloc (line, line_size += 100);
-			c = rl_getc (file);
-		}
-		line[line_index] = '\0';
-
-		/* Parse the line. */
-		rl_parse_and_bind (line);
-	}
-
-function_exit:
-
-	free (line);
-	/* Close up the file and exit. */
-	fclose (file);
-	return (0);
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			Parser Directives       		    */
-/*								    */
-/* **************************************************************** */
-
-/* Conditionals. */
-
-/* Calling programs set this to have their argv[0]. */
-char *rl_readline_name = "other";
-
-/* Stack of previous values of parsing_conditionalized_out. */
-static unsigned char *if_stack = (unsigned char *)NULL;
-static int if_stack_depth = 0;
-static int if_stack_size = 0;
-
-/* Push parsing_conditionalized_out, and set parser state based on ARGS. */
-parser_if (args)
-char *args;
-{
-	register int i;
-
-	/* Push parser state. */
-	if (if_stack_depth + 1 >= if_stack_size)
-	{
-		if (!if_stack)
-			if_stack = (unsigned char *)xmalloc (if_stack_size = 20);
-		else
-			if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20);
-	}
-	if_stack[if_stack_depth++] = parsing_conditionalized_out;
-
-	/* We only check to see if the first word in ARGS is the same as the
-     value stored in rl_readline_name. */
-
-	/* Isolate first argument. */
-	for (i = 0; args[i] && !whitespace (args[i]); i++);
-
-	if (args[i])
-		args[i++] = '\0';
-
-	if (stricmp (args, rl_readline_name) == 0)
-		parsing_conditionalized_out = 0;
-	else
-		parsing_conditionalized_out = 1;
-}
-
-/* Invert the current parser state if there is anything on the stack. */
-parser_else (args)
-char *args;
-{
-	if (if_stack_depth)
-		parsing_conditionalized_out = !parsing_conditionalized_out;
-	else
-	{
-		/* *** What, no error message? *** */
-	}
-}
-
-/* Terminate a conditional, popping the value of
-   parsing_conditionalized_out from the stack. */
-parser_endif (args)
-char *args;
-{
-	if (if_stack_depth)
-		parsing_conditionalized_out = if_stack[--if_stack_depth];
-	else
-	{
-		/* *** What, no error message? *** */
-	}
-}
-
-/* Associate textual names with actual functions. */
-static struct {
-	char *name;
-	Function *function;
-} parser_directives [] = {
-	{ "if", parser_if },
-	{ "endif", parser_endif },
-	{ "else", parser_else },
-	{ (char *)0x0, (Function *)0x0 }
-};
-
-
-/* Handle a parser directive.  STATEMENT is the line of the directive
-   without any leading `$'. */
-static int
-handle_parser_directive (statement)
-char *statement;
-{
-	register int i;
-	char *directive, *args;
-
-	/* Isolate the actual directive. */
-
-	/* Skip whitespace. */
-	for (i = 0; whitespace (statement[i]); i++);
-
-	directive = &statement[i];
-
-	for (; statement[i] && !whitespace (statement[i]); i++);
-
-	if (statement[i])
-		statement[i++] = '\0';
-
-	for (; statement[i] && whitespace (statement[i]); i++);
-
-	args = &statement[i];
-
-	/* Lookup the command, and act on it. */
-	for (i = 0; parser_directives[i].name; i++)
-		if (stricmp (directive, parser_directives[i].name) == 0)
-		{
-			(*parser_directives[i].function) (args);
-			return (0);
-		}
-
-	/* *** Should an error message be output? */
-	return (1);
-}
-
-/* Read the binding command from STRING and perform it.
-   A key binding command looks like: Keyname: function-name\0,
-   a variable binding command looks like: set variable value.
-   A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */
-rl_parse_and_bind (string)
-char *string;
-{
-	extern char *possible_control_prefixes[], *possible_meta_prefixes[];
-	char *rindex (), *funname, *kname;
-	static int substring_member_of_array ();
-	register int c;
-	int key, i;
-
-	if (!string || !*string || *string == '#')
-		return;
-
-	/* If this is a parser directive, act on it. */
-	if (*string == '$')
-	{
-		handle_parser_directive (&string[1]);
-		return;
-	}
-
-	/* If we are supposed to be skipping parsing right now, then do it. */
-	if (parsing_conditionalized_out)
-		return;
-
-	i = 0;
-	/* If this keyname is a complex key expression surrounded by quotes,
-     advance to after the matching close quote. */
-	if (*string == '"')
-	{
-		for (i = 1; c = string[i]; i++)
-		{
-			if (c == '"' && string[i - 1] != '\\')
-				break;
-		}
-	}
-
-	/* Advance to the colon (:) or whitespace which separates the two objects. */
-	for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );
-
-	/* Mark the end of the command (or keyname). */
-	if (string[i])
-		string[i++] = '\0';
-
-	/* If this is a command to set a variable, then do that. */
-	if (stricmp (string, "set") == 0)
-	{
-		char *var = string + i;
-		char *value;
-
-		/* Make VAR point to start of variable name. */
-		while (*var && whitespace (*var)) var++;
-
-		/* Make value point to start of value string. */
-		value = var;
-		while (*value && !whitespace (*value)) value++;
-		if (*value)
-			*value++ = '\0';
-		while (*value && whitespace (*value)) value++;
-
-		rl_variable_bind (var, value);
-		return;
-	}
-
-	/* Skip any whitespace between keyname and funname. */
-	for (; string[i] && whitespace (string[i]); i++);
-	funname = &string[i];
-
-	/* Now isolate funname.
-     For straight function names just look for whitespace, since
-     that will signify the end of the string.  But this could be a
-     macro definition.  In that case, the string is quoted, so skip
-     to the matching delimiter. */
-	if (*funname == '\'' || *funname == '"')
-	{
-		int delimiter = string[i++];
-
-		for (; c = string[i]; i++)
-		{
-			if (c == delimiter && string[i - 1] != '\\')
-				break;
-		}
-		if (c)
-			i++;
-	}
-
-	/* Advance to the end of the string.  */
-	for (; string[i] && !whitespace (string[i]); i++);
-
-	/* No extra whitespace at the end of the string. */
-	string[i] = '\0';
-
-	/* If this is a new-style key-binding, then do the binding with
-     rl_set_key ().  Otherwise, let the older code deal with it. */
-	if (*string == '"')
-	{
-		char *seq = (char *)alloca (1 + strlen (string));
-		register int j, k = 0;
-
-		for (j = 1; string[j]; j++)
-		{
-			if (string[j] == '"' && string[j - 1] != '\\')
-				break;
-
-			seq[k++] = string[j];
-		}
-		seq[k] = '\0';
-
-		/* Binding macro? */
-		if (*funname == '\'' || *funname == '"')
-		{
-			j = strlen (funname);
-
-			if (j && funname[j - 1] == *funname)
-				funname[j - 1] = '\0';
-
-			rl_macro_bind (seq, &funname[1], keymap);
-		}
-		else
-			rl_set_key (seq, rl_named_function (funname), keymap);
-
-		return;
-	}
-
-	/* Get the actual character we want to deal with. */
-	kname = rindex (string, '-');
-	if (!kname)
-		kname = string;
-	else
-		kname++;
-
-	key = glean_key_from_name (kname);
-
-	/* Add in control and meta bits. */
-	if (substring_member_of_array (string, possible_control_prefixes))
-		key = CTRL (to_upper (key));
-
-	if (substring_member_of_array (string, possible_meta_prefixes))
-		key = META (key);
-
-	/* Temporary.  Handle old-style keyname with macro-binding. */
-	if (*funname == '\'' || *funname == '"')
-	{
-		char seq[2];
-		int fl = strlen (funname);
-
-		seq[0] = key; 
-		seq[1] = '\0';
-		if (fl && funname[fl - 1] == *funname)
-			funname[fl - 1] = '\0';
-
-		rl_macro_bind (seq, &funname[1], keymap);
-	}
-	else
-		rl_bind_key (key, rl_named_function (funname));
-}
-
-rl_variable_bind (name, value)
-char *name, *value;
-{
-	if (stricmp (name, "editing-mode") == 0)
-	{
-		if (strnicmp (value, "vi", 2) == 0)
-		{
-#ifdef VI_MODE
-			keymap = vi_insertion_keymap;
-			rl_editing_mode = vi_mode;
-#endif /* VI_MODE */
-		}
-		else if (strnicmp (value, "emacs", 5) == 0)
-		{
-			keymap = emacs_standard_keymap;
-			rl_editing_mode = emacs_mode;
-		}
-	}
-	else if (stricmp (name, "horizontal-scroll-mode") == 0)
-	{
-		if (!*value || stricmp (value, "On") == 0)
-			horizontal_scroll_mode = 1;
-		else
-			horizontal_scroll_mode = 0;
-	}
-}
-
-/* Return the character which matches NAME.
-   For example, `Space' returns ' '. */
-
-typedef struct {
-	char *name;
-	int value;
-} assoc_list;
-
-assoc_list name_key_alist[] = {
-	{ "Space", ' ' },
-	{ "SPC", ' ' },
-	{ "Rubout", 0x7f },
-	{ "DEL", 0x7f },
-	{ "Tab", 0x09 },
-	{ "Newline", '\n' },
-	{ "Return", '\r' },
-	{ "RET", '\r' },
-	{ "LFD", '\n' },
-	{ "Escape", '\033' },
-	{ "ESC", '\033' },
-	{ (char *)0x0, 0 }
-};
-
-
-int
-glean_key_from_name (name)
-char *name;
-{
-	register int i;
-
-	for (i = 0; name_key_alist[i].name; i++)
-		if (stricmp (name, name_key_alist[i].name) == 0)
-			return (name_key_alist[i].value);
-
-	return (*name);
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			String Utility Functions		    */
-/*								    */
-/* **************************************************************** */
-
-/* Return non-zero if any members of ARRAY are a substring in STRING. */
-static int
-substring_member_of_array (string, array)
-char *string, **array;
-{
-	static char *strindex ();
-
-	while (*array)
-	{
-		if (strindex (string, *array))
-			return (1);
-		array++;
-	}
-	return (0);
-}
-
-/* Whoops, Unix doesn't have strnicmp. */
-
-/* Compare at most COUNT characters from string1 to string2.  Case
-   doesn't matter. */
-static int
-strnicmp (string1, string2, count)
-char *string1, *string2;
-{
-	register char ch1, ch2;
-
-	while (count)
-	{
-		ch1 = *string1++;
-		ch2 = *string2++;
-		if (to_upper(ch1) == to_upper(ch2))
-			count--;
-		else break;
-	}
-	return (count);
-}
-
-/* strcmp (), but caseless. */
-static int
-stricmp (string1, string2)
-char *string1, *string2;
-{
-	register char ch1, ch2;
-
-	while (*string1 && *string2)
-	{
-		ch1 = *string1++;
-		ch2 = *string2++;
-		if (to_upper(ch1) != to_upper(ch2))
-			return (1);
-	}
-	return (*string1 | *string2);
-}
-
-/* Determine if s2 occurs in s1.  If so, return a pointer to the
-   match in s1.  The compare is case insensitive. */
-static char *
-strindex (s1, s2)
-register char *s1, *s2;
-{
-	register int i, l = strlen (s2);
-	register int len = strlen (s1);
-
-	for (i = 0; (len - i) >= l; i++)
-		if (strnicmp (&s1[i], s2, l) == 0)
-			return (s1 + i);
-	return ((char *)NULL);
-}
-
-
-/* **************************************************************** */
-/*								    */
-/*			SYSV Support				    */
-/*								    */
-/* **************************************************************** */
-
-/* Since system V reads input differently than we do, I have to
-   make a special version of getc for that. */
-
-#include <sys/errno.h>
-
-int
-rl_getc (stream)
-FILE *stream;
-{
-	int result;
-	unsigned char c;
-	
-	rl_waiting = 1;
-	result = read (fileno (stream), &c, sizeof (char));
-	rl_waiting = 0;
-	if (result == sizeof (char))
-		return (c);
-
-	if (errno != EINTR)
-		return EOF;
-	rl_done = rl_end = errflag = 1;
-	return EOF;
-}
-
-#ifdef STATIC_MALLOC
-
-/* **************************************************************** */
-/*								    */
-/*			xmalloc and xrealloc ()		     	    */
-/*								    */
-/* **************************************************************** */
-
-static void memory_error_and_abort ();
-
-static char *
-xmalloc (bytes)
-int bytes;
-{
-	char *temp = (char *)malloc (bytes);
-
-	if (!temp)
-		memory_error_and_abort ();
-	return (temp);
-}
-
-static char *
-xrealloc (pointer, bytes)
-char *pointer;
-int bytes;
-{
-	char *temp = (char *)realloc (pointer, bytes);
-
-	if (!temp)
-		memory_error_and_abort ();
-	return (temp);
-}
-
-static void
-memory_error_and_abort ()
-{
-	fprintf (stderr, "readline: Out of virtual memory!\n");
-	abort ();
-}
-#endif /* STATIC_MALLOC */
-/*
- * Local variables:
- * compile-command: "gcc -g -traditional -I. -I.. -DTEST -o readline readline.c keymaps.o funmap.o history.o -ltermcap"
- * end:
- */
-
-rl_function_key(count)  /* pjf */
-{
-	switch(rl_getc(rl_instream))
-	{
-	case 'A':
-		rl_get_previous_history(count);
-		break;
-	case 'B':
-		rl_get_next_history(count);
-		break;
-	case 'C':
-		rl_forward(count);
-		break;
-	case 'D':
-		rl_backward(count);
-		break;
-	default:
-		ding();
-		break;
-	}
-}
-
-static char *spname();
-
-rl_check_spelling()
-{
-	char *match;
-	int start, end, delimiter = 0;
-	char *text;
-
-	/* We now look backwards for the start of a filename/variable word. */
-	end = rl_point;
-	if (rl_point)
-	{
-		while (--rl_point &&
-		    !rindex (rl_completer_word_break_characters, the_line[rl_point]));
-
-		/* If we are at a word break, then advance past it. */
-		if (rindex (rl_completer_word_break_characters,  (the_line[rl_point])))
-		{
-			/* If the character that caused the word break was a quoting
-	     character, then remember it as the delimiter. */
-			if (rindex ("\"'", the_line[rl_point]) && (end - rl_point) > 1)
-				delimiter = the_line[rl_point];
-
-			/* If the character isn't needed to determine something special
-	     about what kind of completion to perform, then advance past it. */
-
-			if (!rl_special_prefixes ||
-			    !rindex (rl_special_prefixes, the_line[rl_point]))
-				rl_point++;
-		}
-	}
-
-	start = rl_point;
-	rl_point = end;
-	text = rl_copy (start, end);
-
-	match = spname(text);
-
-	free (text);
-
-	if (!match)
-		ding ();
-	else
-	{
-		rl_delete_text (start, rl_point);
-		rl_point = start;
-		rl_insert_text (match);
-	}
-}
-
-/* next 3 functions stolen from Kernighan & Pike */
-/* "The UNIX Programming Environment" (w/o permission) */
-
-static char *spname (oldname) char *oldname;
-{
-	char *p,guess[MAXPATHLEN+1],best[MAXPATHLEN+1];
-	char newname[MAXPATHLEN+1];
-	char *new = newname, *old = oldname;
-
-	for (;;)
-	{
-		while (*old == '/')
-			*new++ = *old++;
-		*new = '\0';
-		if (*old == '\0')
-			return newname;
-		p = guess;
-		for (; *old != '/' && *old != '\0'; old++)
-			if (p < guess+MAXPATHLEN)
-				*p++ = *old;
-		*p = '\0';
-		if (mindist(newname,guess,best) >= 3)
-			return oldname;
-		for (p = best; *new = *p++; )
-			new++;
-	}
-}
-
-mindist(dir,guess,best) char *dir,*guess,*best;
-{
-	int d,nd;
-	DIR *dd;
-	struct direct *de;
-
-	if (dir[0] == '\0')
-		dir = ".";
-	d = 3;
-	if (!(dd = opendir(dir)))
-		return d;
-	while (de = readdir(dd))
-	{
-		nd = spdist(de->d_name,guess);
-		if (nd <= d && nd != 3) {
-			strcpy(best,de->d_name);
-			d = nd;
-			if (d == 0)
-				break;
-		}
-	}
-	closedir(dd);
-	return d;
-}
-
-#define EQ(s,t) (strcmp(s,t) == 0)
-
-spdist(s,t) char *s, *t;
-{
-	while (*s++ == *t)
-		if (*t++ == '\0')
-			return 0;
-	if (*--s)
-	{
-		if (*t)
-		{
-			if (s[1] && t[1] && *s == t[1] && *t == s[1] &&
-			    EQ(s+2,t+2))
-				return 1;
-			if (EQ(s+1,t+1))
-				return 2;
-		}
-		if (EQ(s+1,t))
-			return 2;
-	}
-	if (*t && EQ(s,t+1))
-		return 2;
-	return 3;
-}
-
-char *strpbrk(s,t) char *s,*t;
-{
-	char *u = t;
-
-	while (*s)
-	{
-		for (t = u; *t; t++)
-			if (*s == *t)
-				return s;
-		s++;
-	}
-	return NULL;
-}
-
-void rl_safe_insert_text(s) char *s;
-{
-	char *bad = " \\!#$^*()|=[]{}`\'\";?><";
-	char *t;
-
-	for(;;)
-		if (t = strpbrk(s,bad))
-		{
-			char a = *t;
-
-			*t = '\0';
-			rl_insert_text(s);
-			rl_insert_text("\\");
-			*t = a;
-			a = t[1];
-			t[1] = '\0';
-			rl_insert_text(t);
-			t[1] = a;
-			s = t+1;
-		}
-		else
-		{
-			rl_insert_text(s);
-			return;
-		}
-}
-
-#define HERR -125
-
-extern int magic;
-char *strdup();
-int hgetc();
-
-rl_magic_space ()
-{
-	int c,pt = 0;
-	char *str;
-
-	the_line[rl_end] = '\0'; /* necessary? */
-	str = strdup(the_line);
-	strinbeg();
-	magic = 1;
-	hungets(strdup("\n"));
-	hungets(strdup(the_line));
-	while ((c = hgetc()) != EOF)
-	{
-		if (c == HERR)
-		{
-			strcpy(the_line,str);
-			free(str);
-			hflush();
-			magic = 0;
-			strinend();
-			rl_on_new_line();
-			rl_redisplay();
-			return 0;
-		}
-		if (c == '!')
-			the_line[pt++] = '\\';
-		the_line[pt++] = c;
-	}
-	if (!pt)
-		fprintf(stderr,"Whoops.\n");
-	the_line[rl_end = rl_point = pt-1] = '\0';
-	magic = 0;
-	strinend();
-	free(str);
-}
End of readline/readline.c
echo readline/readline.h 1>&2
sed 's/^-//' >readline/readline.h <<'End of readline/readline.h'
-/* Readline.h -- the names of functions callable from within readline. */
-
-#ifndef _READLINE_H_
-#define _READLINE_H_
-
-#include <readline/keymaps.h>
-
-#ifndef __FUNCTION_DEF
-typedef int Function ();
-#define __FUNCTION_DEF
-#endif
-
-/* The functions for manipulating the text of the line within readline.
-Most of these functions are bound to keys by default. */
-extern int
-rl_beg_of_line (), rl_backward (), rl_delete (), rl_end_of_line (),
-rl_forward (), ding (), rl_backward (), rl_newline (), rl_kill_line (),
-rl_clear_screen (), rl_get_next_history (), rl_get_previous_history (),
-rl_quoted_insert (), rl_transpose_chars
-(), rl_unix_line_discard (), rl_quoted_insert (), rl_unix_word_rubout
-(), rl_yank (), rl_rubout (), rl_backward_word (), rl_kill_word (),
-rl_forward_word (), rl_tab_insert (), rl_yank_pop (), rl_yank_nth_arg (),
-rl_backward_kill_word (), rl_backward_kill_line (), rl_transpose_words
-(), rl_complete (), rl_possible_completions (), rl_do_lowercase_version
-(), rl_digit_argument (), rl_universal_argument (), rl_abort (),
-rl_undo_command (), rl_revert_line (), rl_beginning_of_history (),
-rl_end_of_history (), rl_insert (),
-rl_upcase_word (), rl_downcase_word (), rl_capitalize_word (),
-rl_restart_output (), rl_re_read_init_file ();
-
-extern int rl_function_key(); /* pjf */
-extern int rl_check_spelling(),rl_magic_space();
-extern int rl_break_c();
-
-/* These are *both* defined even when VI_MODE is not. */
-extern int rl_vi_editing_mode (), rl_emacs_editing_mode ();
-
-#ifdef VI_MODE
-/* Things for vi mode. */
-extern int rl_vi_movement_mode (), rl_vi_insertion_mode (), rl_vi_arg_digit (),
-rl_vi_prev_word (), rl_vi_next_word (), rl_vi_char_search (),
-rl_vi_eof_maybe (), rl_vi_append_mode (), rl_vi_put (),
-rl_vi_append_eol (), rl_vi_insert_beg (), rl_vi_delete (), rl_vi_comment (),
-rl_vi_first_print (), rl_vi_fword (), rl_vi_fWord (), rl_vi_bword (),
-rl_vi_bWord (), rl_vi_eword (), rl_vi_eWord (), rl_vi_end_word (),
-rl_vi_change_case (), rl_vi_match (), rl_vi_bracktype (), rl_vi_change_char (),
-rl_vi_yank_arg (), rl_vi_search (), rl_vi_search_again (),
-rl_vi_dosearch (), rl_vi_subst (), rl_vi_overstrike (),
-rl_vi_overstrike_delete (), rl_vi_replace(), rl_vi_column (),
-rl_vi_delete_to (), rl_vi_change_to (), rl_vi_yank_to (), rl_vi_complete ();
-#endif /* VI_MODE */
-
-/* Keyboard macro commands. */
-extern int
-rl_start_kbd_macro (), rl_end_kbd_macro (), rl_call_last_kbd_macro ();
-
-/* Maintaining the state of undo.  We remember individual deletes and inserts
-   on a chain of things to do. */
-
-/* The actions that undo knows how to undo.  Notice that UNDO_DELETE means
-   to insert some text, and UNDO_INSERT means to delete some text.   I.e.,
-   the code tells undo what to undo, not how to undo it. */
-enum undo_code { UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END };
-
-/* What an element of THE_UNDO_LIST looks like. */
-typedef struct undo_list {
-  struct undo_list *next;
-  int start, end;		/* Where the change took place. */
-  char *text;			/* The text to insert, if undoing a delete. */
-  enum undo_code what;		/* Delete, Insert, Begin, End. */
-} UNDO_LIST;
-
-/* The current undo list for RL_LINE_BUFFER. */
-extern UNDO_LIST *rl_undo_list;
-
-/* The data structure for mapping textual names to code addresses. */
-typedef struct {
-  char *name;
-  Function *function;
-} FUNMAP;
-
-extern FUNMAP **funmap;
-
-/* **************************************************************** */
-/*								    */
-/*			Well Published Variables		    */
-/*								    */
-/* **************************************************************** */
-
-/* The name of the calling program.  You should initialize this to
-   whatever was in argv[0].  It is used when parsing conditionals. */
-extern char *rl_readline_name;
-
-/* The line buffer that is in use. */
-extern char *rl_line_buffer;
-
-/* The location of point, and end. */
-extern int rl_point, rl_end;
-
-/* The name of the terminal to use. */
-extern char *rl_terminal_name;
-
-/* The input and output streams. */
-extern FILE *rl_instream, *rl_outstream;
-
-/* The basic list of characters that signal a break between words for the
-   completer routine.  The contents of this variable is what breaks words
-   in the shell, i.e. "n\"\\'`@$>". */
-extern char *rl_basic_word_break_characters;
-
-/* The list of characters that signal a break between words for
-   rl_complete_internal.  The default list is the contents of
-   rl_basic_word_break_characters.  */
-extern char *rl_completer_word_break_characters;
-
-/* List of characters that are word break characters, but should be left
-   in TEXT when it is passed to the completion function.  The shell uses
-   this to help determine what kind of completing to do. */
-extern char *rl_special_prefixes;
-
-/* Pointer to the generator function for completion_matches ().
-   NULL means to use filename_entry_function (), the default filename
-   completer. */
-extern Function *rl_completion_entry_function;
-
-/* Pointer to alternative function to create matches.
-   Function is called with TEXT, START, and END.
-   START and END are indices in RL_LINE_BUFFER saying what the boundaries
-   of TEXT are.
-   If this function exists and returns NULL then call the value of
-   rl_completion_entry_function to try to match, otherwise use the
-   array of strings returned. */
-extern Function *rl_attempted_completion_function;
-
-/* If non-null, this contains the address of a function to call if the
-   standard meaning for expanding a tilde fails.  The function is called
-   with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
-   which is the expansion, or a NULL pointer if there is no expansion. */
-extern Function *rl_tilde_expander;
-
-/* If non-zero, then this is the address of a function to call just
-   before readline_internal () prints the first prompt. */
-extern Function *rl_startup_hook;
-
-/* If non-zero, then this is the address of a function to call when
-   completing on a directory name.  The function is called with
-   the address of a string (the current directory name) as an arg. */
-extern Function *rl_symbolic_link_hook;
-
-/* Non-zero means that modified history lines are preceded
-   with an asterisk. */
-extern int rl_show_star;
-
-/* **************************************************************** */
-/*								    */
-/*			Well Published Functions		    */
-/*								    */
-/* **************************************************************** */
-
-/* Read a line of input.  Prompt with PROMPT.  A NULL PROMPT means none. */
-extern char *readline ();
-
-/* Return an array of strings which are the result of repeatadly calling
-   FUNC with TEXT. */
-extern char **completion_matches ();
-
-/* rl_add_defun (char *name, Function *function, int key)
-   Add NAME to the list of named functions.  Make FUNCTION
-   be the function that gets called.
-   If KEY is not -1, then bind it. */
-extern int rl_add_defun ();
-
-
-#endif /* _READLINE_H_ */
-
End of readline/readline.h
echo readline/vi_keymap.c 1>&2
sed 's/^-//' >readline/vi_keymap.c <<'End of readline/vi_keymap.c'
-/* vi_keymap.c -- the keymap for vi_mode in readline (). */
-
-/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
-
-   This file is part of GNU Readline, a library for reading lines
-   of text with interactive input and history editing.
-
-   Readline is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by the
-   Free Software Foundation; either version 1, or (at your option) any
-   later version.
-
-   Readline is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with Readline; see the file COPYING.  If not, write to the Free
-   Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifndef FILE
-#include <stdio.h>
-#endif /* FILE */
-
-#include "readline.h"
-
-extern KEYMAP_ENTRY_ARRAY vi_escape_keymap;
-
-/* The keymap arrays for handling vi mode. */
-KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
-
-  /* The regular control keys come first. */
-  { ISFUNC, (Function *)0x0 },		/* Control-@ */
-  { ISFUNC, (Function *)0x0 },		/* Control-a */
-  { ISFUNC, (Function *)0x0 },		/* Control-b */
-  { ISFUNC, (Function *)0x0 },		/* Control-c */
-  { ISFUNC, rl_vi_eof_maybe },		/* Control-d */
-  { ISFUNC, rl_emacs_editing_mode },	/* Control-e */
-  { ISFUNC, (Function *)0x0 },		/* Control-f */
-  { ISFUNC, rl_abort },			/* Control-g */
-  { ISFUNC, rl_rubout },		/* Control-h */ /* pjf */
-  { ISFUNC, (Function *)0x0 },		/* Control-i */
-  { ISFUNC, rl_newline },		/* Control-j */
-  { ISFUNC, rl_kill_line },		/* Control-k */
-  { ISFUNC, rl_clear_screen },		/* Control-l */
-  { ISFUNC, rl_newline },		/* Control-m */
-  { ISFUNC, rl_get_next_history },	/* Control-n */
-  { ISFUNC, (Function *)0x0 },		/* Control-o */
-  { ISFUNC, rl_get_previous_history },	/* Control-p */
-  { ISFUNC, rl_quoted_insert },		/* Control-q */
-  { ISFUNC, (Function *)0x0 },  /* Control-r */
-  { ISFUNC, (Function *)0x0 },  /* Control-s */
-  { ISFUNC, rl_transpose_chars },	/* Control-t */
-  { ISFUNC, rl_unix_line_discard },	/* Control-u */
-  { ISFUNC, rl_quoted_insert },		/* Control-v */
-  { ISFUNC, rl_unix_word_rubout },	/* Control-w */
-  { ISFUNC, (Function *)0x0 },		/* Control-x */
-  { ISFUNC, rl_yank },			/* Control-y */
-  { ISFUNC, (Function *)0x0 },		/* Control-z */
-
-  { ISKMAP, (Function *)vi_escape_keymap }, /* Control-[ */
-  { ISFUNC, (Function *)0x0 },		/* Control-\ */
-  { ISFUNC, (Function *)0x0 },		/* Control-] */
-  { ISFUNC, (Function *)0x0 },		/* Control-^ */
-  { ISFUNC, rl_undo_command },		/* Control-_ */
-
-  /* The start of printing characters. */
-  { ISFUNC, rl_forward },		/* SPACE */
-  { ISFUNC, (Function *)0x0 },		/* ! */
-  { ISFUNC, (Function *)0x0 },		/* " */
-  { ISFUNC, rl_vi_comment },		/* # */
-  { ISFUNC, rl_end_of_line },		/* $ */
-  { ISFUNC, rl_vi_match },		/* % */
-  { ISFUNC, (Function *)0x0 },		/* & */
-  { ISFUNC, (Function *)0x0 },		/* ' */
-  { ISFUNC, (Function *)0x0 },		/* ( */
-  { ISFUNC, (Function *)0x0 },		/* ) */
-  { ISFUNC, rl_vi_complete },		/* * */
-  { ISFUNC, rl_get_next_history},	/* + */
-  { ISFUNC, rl_vi_char_search },	/* , */
-  { ISFUNC, rl_get_previous_history },	/* - */
-  { ISFUNC, (Function *)0x0 },		/* . */
-  { ISFUNC, rl_vi_search },		/* / */
-
-  /* Regular digits. */
-  { ISFUNC, rl_vi_arg_digit },		/* 0 */
-  { ISFUNC, rl_vi_arg_digit },		/* 1 */
-  { ISFUNC, rl_vi_arg_digit },		/* 2 */
-  { ISFUNC, rl_vi_arg_digit },		/* 3 */
-  { ISFUNC, rl_vi_arg_digit },		/* 4 */
-  { ISFUNC, rl_vi_arg_digit },		/* 5 */
-  { ISFUNC, rl_vi_arg_digit },		/* 6 */
-  { ISFUNC, rl_vi_arg_digit },		/* 7 */
-  { ISFUNC, rl_vi_arg_digit },		/* 8 */
-  { ISFUNC, rl_vi_arg_digit },		/* 9 */
-
-  /* A little more punctuation. */
-  { ISFUNC, (Function *)0x0 },		/* : */
-  { ISFUNC, rl_vi_char_search },	/* ; */
-  { ISFUNC, (Function *)0x0 },		/* < */
-  { ISFUNC, (Function *)0x0 },		/* = */
-  { ISFUNC, (Function *)0x0 },		/* > */
-  { ISFUNC, rl_vi_search },		/* ? */
-  { ISFUNC, (Function *)0x0 },		/* @ */
-
-  /* Uppercase alphabet. */
-  { ISFUNC, rl_vi_append_eol },		/* A */
-  { ISFUNC, rl_vi_prev_word},		/* B */
-  { ISFUNC, rl_vi_change_to },		/* C */
-  { ISFUNC, rl_vi_delete_to },		/* D */
-  { ISFUNC, rl_vi_end_word },		/* E */
-  { ISFUNC, rl_vi_char_search },	/* F */
-  { ISFUNC, (Function *)0x0 },		/* G */
-  { ISFUNC, (Function *)0x0 },		/* H */
-  { ISFUNC, rl_vi_insert_beg },		/* I */
-  { ISFUNC, (Function *)0x0 },		/* J */
-  { ISFUNC, (Function *)0x0 },		/* K */
-  { ISFUNC, (Function *)0x0 },		/* L */
-  { ISFUNC, (Function *)0x0 },		/* M */
-  { ISFUNC, rl_vi_search_again },	/* N */
-  { ISFUNC, (Function *)0x0 },		/* O */
-  { ISFUNC, rl_vi_put },		/* P */
-  { ISFUNC, (Function *)0x0 },		/* Q */
-  { ISFUNC, rl_vi_replace },		/* R */
-  { ISFUNC, rl_vi_subst },		/* S */
-  { ISFUNC, rl_vi_char_search },	/* T */
-  { ISFUNC, rl_revert_line },		/* U */
-  { ISFUNC, (Function *)0x0 },		/* V */
-  { ISFUNC, rl_vi_next_word },		/* W */
-  { ISFUNC, rl_rubout },		/* X */
-  { ISFUNC, rl_vi_yank_to },		/* Y */
-  { ISFUNC, (Function *)0x0 },		/* Z */
-
-  /* Some more punctuation. */
-  { ISFUNC, (Function *)0x0 },		/* [ */
-  { ISFUNC, (Function *)0x0 },		/* \ */
-  { ISFUNC, (Function *)0x0 },		/* ] */
-  { ISFUNC, rl_vi_first_print },	/* ^ */
-  { ISFUNC, rl_vi_yank_arg },		/* _ */
-  { ISFUNC, (Function *)0x0 },		/* ` */
-
-  /* Lowercase alphabet. */
-  { ISFUNC, rl_vi_append_mode },	/* a */
-  { ISFUNC, rl_vi_prev_word },		/* b */
-  { ISFUNC, rl_vi_change_to },		/* c */
-  { ISFUNC, rl_vi_delete_to },		/* d */
-  { ISFUNC, rl_vi_end_word },		/* e */
-  { ISFUNC, rl_vi_char_search },	/* f */
-  { ISFUNC, (Function *)0x0 },		/* g */
-  { ISFUNC, rl_backward },		/* h */
-  { ISFUNC, rl_vi_insertion_mode },	/* i */
-  { ISFUNC, rl_get_next_history },	/* j */
-  { ISFUNC, rl_get_previous_history },	/* k */
-  { ISFUNC, rl_forward },		/* l */
-  { ISFUNC, (Function *)0x0 },		/* m */
-  { ISFUNC, rl_vi_search_again },	/* n */
-  { ISFUNC, (Function *)0x0 },		/* o */
-  { ISFUNC, rl_vi_put },		/* p */
-  { ISFUNC, (Function *)0x0 },		/* q */
-  { ISFUNC, rl_vi_change_char },	/* r */
-  { ISFUNC, rl_vi_subst },		/* s */
-  { ISFUNC, rl_vi_char_search },	/* t */
-  { ISFUNC, rl_undo_command },		/* u */
-  { ISFUNC, (Function *)0x0 },		/* v */
-  { ISFUNC, rl_vi_next_word },		/* w */
-  { ISFUNC, rl_vi_delete },		/* x */
-  { ISFUNC, rl_vi_yank_to },		/* y */
-  { ISFUNC, (Function *)0x0 },		/* z */
-
-  /* Final punctuation. */
-  { ISFUNC, (Function *)0x0 },		/* { */
-  { ISFUNC, rl_vi_column },		/* | */
-  { ISFUNC, (Function *)0x0 },		/* } */
-  { ISFUNC, rl_vi_change_case },	/* ~ */
-  { ISFUNC, rl_backward }		/* RUBOUT */
-};
-
-
-KEYMAP_ENTRY_ARRAY vi_insertion_keymap = {
-
-  /* The regular control keys come first. */
-  { ISFUNC, (Function *)0x0 },		/* Control-@ */
-  { ISFUNC, rl_insert },		/* Control-a */
-  { ISFUNC, rl_insert },		/* Control-b */
-  { ISFUNC, rl_insert },		/* Control-c */
-  { ISFUNC, rl_vi_eof_maybe },		/* Control-d */
-  { ISFUNC, rl_insert },		/* Control-e */
-  { ISFUNC, rl_insert },		/* Control-f */
-  { ISFUNC, rl_insert },		/* Control-g */
-  { ISFUNC, rl_rubout },		/* Control-h */
-  { ISFUNC, rl_complete },		/* Control-i */
-  { ISFUNC, rl_newline },		/* Control-j */
-  { ISFUNC, rl_insert },		/* Control-k */
-  { ISFUNC, rl_insert },		/* Control-l */
-  { ISFUNC, rl_newline },		/* Control-m */
-  { ISFUNC, rl_insert },		/* Control-n */
-  { ISFUNC, rl_insert },		/* Control-o */
-  { ISFUNC, rl_insert },		/* Control-p */
-  { ISFUNC, rl_insert },		/* Control-q */
-  { ISFUNC, (Function *)0x0 },
-  { ISFUNC, (Function *)0x0 },
-  { ISFUNC, rl_transpose_chars },	/* Control-t */
-  { ISFUNC, rl_unix_line_discard },	/* Control-u */
-  { ISFUNC, rl_quoted_insert },		/* Control-v */
-  { ISFUNC, rl_unix_word_rubout },	/* Control-w */
-  { ISFUNC, rl_insert },		/* Control-x */
-  { ISFUNC, rl_yank },			/* Control-y */
-  { ISFUNC, rl_insert },		/* Control-z */
-
-  { ISFUNC, rl_vi_movement_mode },	/* Control-[ */
-  { ISFUNC, rl_insert },		/* Control-\ */
-  { ISFUNC, rl_insert },		/* Control-] */
-  { ISFUNC, rl_insert },		/* Control-^ */
-  { ISFUNC, rl_undo_command },		/* Control-_ */
-
-  /* The start of printing characters. */
-  { ISFUNC, rl_insert },		/* SPACE */
-  { ISFUNC, rl_insert },		/* ! */
-  { ISFUNC, rl_insert },		/* " */
-  { ISFUNC, rl_insert },		/* # */
-  { ISFUNC, rl_insert },		/* $ */
-  { ISFUNC, rl_insert },		/* % */
-  { ISFUNC, rl_insert },		/* & */
-  { ISFUNC, rl_insert },		/* ' */
-  { ISFUNC, rl_insert },		/* ( */
-  { ISFUNC, rl_insert },		/* ) */
-  { ISFUNC, rl_insert },		/* * */
-  { ISFUNC, rl_insert },		/* + */
-  { ISFUNC, rl_insert },		/* , */
-  { ISFUNC, rl_insert },		/* - */
-  { ISFUNC, rl_insert },		/* . */
-  { ISFUNC, rl_insert },		/* / */
-
-  /* Regular digits. */
-  { ISFUNC, rl_insert },		/* 0 */
-  { ISFUNC, rl_insert },		/* 1 */
-  { ISFUNC, rl_insert },		/* 2 */
-  { ISFUNC, rl_insert },		/* 3 */
-  { ISFUNC, rl_insert },		/* 4 */
-  { ISFUNC, rl_insert },		/* 5 */
-  { ISFUNC, rl_insert },		/* 6 */
-  { ISFUNC, rl_insert },		/* 7 */
-  { ISFUNC, rl_insert },		/* 8 */
-  { ISFUNC, rl_insert },		/* 9 */
-
-  /* A little more punctuation. */
-  { ISFUNC, rl_insert },		/* : */
-  { ISFUNC, rl_insert },		/* ; */
-  { ISFUNC, rl_insert },		/* < */
-  { ISFUNC, rl_insert },		/* = */
-  { ISFUNC, rl_insert },		/* > */
-  { ISFUNC, rl_insert },		/* ? */
-  { ISFUNC, rl_insert },		/* @ */
-
-  /* Uppercase alphabet. */
-  { ISFUNC, rl_insert },		/* A */
-  { ISFUNC, rl_insert },		/* B */
-  { ISFUNC, rl_insert },		/* C */
-  { ISFUNC, rl_insert },		/* D */
-  { ISFUNC, rl_insert },		/* E */
-  { ISFUNC, rl_insert },		/* F */
-  { ISFUNC, rl_insert },		/* G */
-  { ISFUNC, rl_insert },		/* H */
-  { ISFUNC, rl_insert },		/* I */
-  { ISFUNC, rl_insert },		/* J */
-  { ISFUNC, rl_insert },		/* K */
-  { ISFUNC, rl_insert },		/* L */
-  { ISFUNC, rl_insert },		/* M */
-  { ISFUNC, rl_insert },		/* N */
-  { ISFUNC, rl_insert },		/* O */
-  { ISFUNC, rl_insert },		/* P */
-  { ISFUNC, rl_insert },		/* Q */
-  { ISFUNC, rl_insert },		/* R */
-  { ISFUNC, rl_insert },		/* S */
-  { ISFUNC, rl_insert },		/* T */
-  { ISFUNC, rl_insert },		/* U */
-  { ISFUNC, rl_insert },		/* V */
-  { ISFUNC, rl_insert },		/* W */
-  { ISFUNC, rl_insert },		/* X */
-  { ISFUNC, rl_insert },		/* Y */
-  { ISFUNC, rl_insert },		/* Z */
-
-  /* Some more punctuation. */
-  { ISFUNC, rl_insert },		/* [ */
-  { ISFUNC, rl_insert },		/* \ */
-  { ISFUNC, rl_insert },		/* ] */
-  { ISFUNC, rl_insert },		/* ^ */
-  { ISFUNC, rl_insert },		/* _ */
-  { ISFUNC, rl_insert },		/* ` */
-
-  /* Lowercase alphabet. */
-  { ISFUNC, rl_insert },		/* a */
-  { ISFUNC, rl_insert },		/* b */
-  { ISFUNC, rl_insert },		/* c */
-  { ISFUNC, rl_insert },		/* d */
-  { ISFUNC, rl_insert },		/* e */
-  { ISFUNC, rl_insert },		/* f */
-  { ISFUNC, rl_insert },		/* g */
-  { ISFUNC, rl_insert },		/* h */
-  { ISFUNC, rl_insert },		/* i */
-  { ISFUNC, rl_insert },		/* j */
-  { ISFUNC, rl_insert },		/* k */
-  { ISFUNC, rl_insert },		/* l */
-  { ISFUNC, rl_insert },		/* m */
-  { ISFUNC, rl_insert },		/* n */
-  { ISFUNC, rl_insert },		/* o */
-  { ISFUNC, rl_insert },		/* p */
-  { ISFUNC, rl_insert },		/* q */
-  { ISFUNC, rl_insert },		/* r */
-  { ISFUNC, rl_insert },		/* s */
-  { ISFUNC, rl_insert },		/* t */
-  { ISFUNC, rl_insert },		/* u */
-  { ISFUNC, rl_insert },		/* v */
-  { ISFUNC, rl_insert },		/* w */
-  { ISFUNC, rl_insert },		/* x */
-  { ISFUNC, rl_insert },		/* y */
-  { ISFUNC, rl_insert },		/* z */
-
-  /* Final punctuation. */
-  { ISFUNC, rl_insert },		/* { */
-  { ISFUNC, rl_insert },		/* | */
-  { ISFUNC, rl_insert },		/* } */
-  { ISFUNC, rl_insert },		/* ~ */
-  { ISFUNC, rl_rubout }			/* RUBOUT */
-};
-
-KEYMAP_ENTRY_ARRAY vi_escape_keymap = {
-
-  /* The regular control keys come first. */
-  { ISFUNC, (Function *)0x0 },		/* Control-@ */
-  { ISFUNC, (Function *)0x0 },		/* Control-a */
-  { ISFUNC, (Function *)0x0 },		/* Control-b */
-  { ISFUNC, (Function *)0x0 },		/* Control-c */
-  { ISFUNC, (Function *)0x0 },		/* Control-d */
-  { ISFUNC, (Function *)0x0 },		/* Control-e */
-  { ISFUNC, (Function *)0x0 },		/* Control-f */
-  { ISFUNC, (Function *)0x0 },		/* Control-g */
-  { ISFUNC, (Function *)0x0 },		/* Control-h */
-  { ISFUNC, rl_tab_insert},		/* Control-i */
-  { ISFUNC, rl_emacs_editing_mode},	/* Control-j */
-  { ISFUNC, rl_kill_line },		/* Control-k */
-  { ISFUNC, (Function *)0x0 },		/* Control-l */
-  { ISFUNC, rl_emacs_editing_mode},	/* Control-m */
-  { ISFUNC, (Function *)0x0 },		/* Control-n */
-  { ISFUNC, (Function *)0x0 },		/* Control-o */
-  { ISFUNC, (Function *)0x0 },		/* Control-p */
-  { ISFUNC, (Function *)0x0 },		/* Control-q */
-  { ISFUNC, (Function *)0x0 },		/* Control-r */
-  { ISFUNC, (Function *)0x0 },		/* Control-s */
-  { ISFUNC, (Function *)0x0 },		/* Control-t */
-  { ISFUNC, (Function *)0x0 },		/* Control-u */
-  { ISFUNC, (Function *)0x0 },		/* Control-v */
-  { ISFUNC, (Function *)0x0 },		/* Control-w */
-  { ISFUNC, (Function *)0x0 },		/* Control-x */
-  { ISFUNC, (Function *)0x0 },		/* Control-y */
-  { ISFUNC, (Function *)0x0 },		/* Control-z */
-
-  { ISFUNC, rl_vi_movement_mode },	/* Control-[ */
-  { ISFUNC, (Function *)0x0 },		/* Control-\ */
-  { ISFUNC, (Function *)0x0 },		/* Control-] */
-  { ISFUNC, (Function *)0x0 },		/* Control-^ */
-  { ISFUNC, rl_undo_command },		/* Control-_ */
-
-  /* The start of printing characters. */
-  { ISFUNC, (Function *)0x0 },		/* SPACE */
-  { ISFUNC, (Function *)0x0 },		/* ! */
-  { ISFUNC, (Function *)0x0 },		/* " */
-  { ISFUNC, (Function *)0x0 },		/* # */
-  { ISFUNC, (Function *)0x0 },		/* $ */
-  { ISFUNC, (Function *)0x0 },		/* % */
-  { ISFUNC, (Function *)0x0 },		/* & */
-  { ISFUNC, (Function *)0x0 },		/* ' */
-  { ISFUNC, (Function *)0x0 },		/* ( */
-  { ISFUNC, (Function *)0x0 },		/* ) */
-  { ISFUNC, (Function *)0x0 },		/* * */
-  { ISFUNC, (Function *)0x0 },		/* + */
-  { ISFUNC, (Function *)0x0 },		/* , */
-  { ISFUNC, (Function *)0x0 },		/* - */
-  { ISFUNC, (Function *)0x0 },		/* . */
-  { ISFUNC, (Function *)0x0 },		/* / */
-
-  /* Regular digits. */
-  { ISFUNC, rl_vi_arg_digit },		/* 0 */
-  { ISFUNC, rl_vi_arg_digit },		/* 1 */
-  { ISFUNC, rl_vi_arg_digit },		/* 2 */
-  { ISFUNC, rl_vi_arg_digit },		/* 3 */
-  { ISFUNC, rl_vi_arg_digit },		/* 4 */
-  { ISFUNC, rl_vi_arg_digit },		/* 5 */
-  { ISFUNC, rl_vi_arg_digit },		/* 6 */
-  { ISFUNC, rl_vi_arg_digit },		/* 7 */
-  { ISFUNC, rl_vi_arg_digit },		/* 8 */
-  { ISFUNC, rl_vi_arg_digit },		/* 9 */
-
-  /* A little more punctuation. */
-  { ISFUNC, (Function *)0x0 },		/* : */
-  { ISFUNC, (Function *)0x0 },		/* ; */
-  { ISFUNC, (Function *)0x0 },		/* < */
-  { ISFUNC, (Function *)0x0 },		/* = */
-  { ISFUNC, (Function *)0x0 },		/* > */
-  { ISFUNC, (Function *)0x0 },		/* ? */
-  { ISFUNC, (Function *)0x0 },		/* @ */
-
-  /* Uppercase alphabet. */
-  { ISFUNC, rl_do_lowercase_version },	/* A */
-  { ISFUNC, rl_do_lowercase_version },	/* B */
-  { ISFUNC, rl_do_lowercase_version },	/* C */
-  { ISFUNC, rl_do_lowercase_version },	/* D */
-  { ISFUNC, rl_do_lowercase_version },	/* E */
-  { ISFUNC, rl_do_lowercase_version },	/* F */
-  { ISFUNC, rl_do_lowercase_version },	/* G */
-  { ISFUNC, rl_do_lowercase_version },	/* H */
-  { ISFUNC, rl_do_lowercase_version },	/* I */
-  { ISFUNC, rl_do_lowercase_version },	/* J */
-  { ISFUNC, rl_do_lowercase_version },	/* K */
-  { ISFUNC, rl_do_lowercase_version },	/* L */
-  { ISFUNC, rl_do_lowercase_version },	/* M */
-  { ISFUNC, rl_do_lowercase_version },	/* N */
-  { ISFUNC, rl_do_lowercase_version },	/* O */
-  { ISFUNC, rl_do_lowercase_version },	/* P */
-  { ISFUNC, rl_do_lowercase_version },	/* Q */
-  { ISFUNC, rl_do_lowercase_version },	/* R */
-  { ISFUNC, rl_do_lowercase_version },	/* S */
-  { ISFUNC, rl_do_lowercase_version },	/* T */
-  { ISFUNC, rl_do_lowercase_version },	/* U */
-  { ISFUNC, rl_do_lowercase_version },	/* V */
-  { ISFUNC, rl_do_lowercase_version },	/* W */
-  { ISFUNC, rl_do_lowercase_version },	/* X */
-  { ISFUNC, rl_do_lowercase_version },	/* Y */
-  { ISFUNC, rl_do_lowercase_version },	/* Z */
-
-  /* Some more punctuation. */
-  { ISFUNC, (Function *)0x0 },		/* [ */
-  { ISFUNC, (Function *)0x0 },		/* \ */
-  { ISFUNC, (Function *)0x0 },		/* ] */
-  { ISFUNC, (Function *)0x0 },		/* ^ */
-  { ISFUNC, (Function *)0x0 },		/* _ */
-  { ISFUNC, (Function *)0x0 },		/* ` */
-
-  /* Lowercase alphabet. */
-  { ISFUNC, (Function *)0x0 },		/* a */
-  { ISFUNC, (Function *)0x0 },		/* b */
-  { ISFUNC, (Function *)0x0 },		/* c */
-  { ISFUNC, (Function *)0x0 },		/* d */
-  { ISFUNC, (Function *)0x0 },		/* e */
-  { ISFUNC, (Function *)0x0 },		/* f */
-  { ISFUNC, (Function *)0x0 },		/* g */
-  { ISFUNC, (Function *)0x0 },		/* h */
-  { ISFUNC, (Function *)0x0 },		/* i */
-  { ISFUNC, (Function *)0x0 },		/* j */
-  { ISFUNC, (Function *)0x0 },		/* k */
-  { ISFUNC, (Function *)0x0 },		/* l */
-  { ISFUNC, (Function *)0x0 },		/* m */
-  { ISFUNC, (Function *)0x0 },		/* n */
-  { ISFUNC, (Function *)0x0 },		/* o */
-  { ISFUNC, (Function *)0x0 },		/* p */
-  { ISFUNC, (Function *)0x0 },		/* q */
-  { ISFUNC, (Function *)0x0 },		/* r */
-  { ISFUNC, (Function *)0x0 },		/* s */
-  { ISFUNC, (Function *)0x0 },		/* t */
-  { ISFUNC, (Function *)0x0 },		/* u */
-  { ISFUNC, (Function *)0x0 },		/* v */
-  { ISFUNC, (Function *)0x0 },		/* w */
-  { ISFUNC, (Function *)0x0 },		/* x */
-  { ISFUNC, (Function *)0x0 },		/* y */
-  { ISFUNC, (Function *)0x0 },		/* z */
-
-  /* Final punctuation. */
-  { ISFUNC, (Function *)0x0 },		/* { */
-  { ISFUNC, (Function *)0x0 },		/* | */
-  { ISFUNC, (Function *)0x0 },		/* } */
-  { ISFUNC, (Function *)0x0 },		/* ~ */
-  { ISFUNC, rl_backward_kill_word }	/* RUBOUT */
-};
End of readline/vi_keymap.c
echo readline/vi_mode.c 1>&2
sed 's/^-//' >readline/vi_mode.c <<'End of readline/vi_mode.c'
-/* vi_mode.c -- A vi emulation mode for Bash.
-
-   Derived from code written by Jeff Sparkes (jeff1@????).
- */
-
-
-/* **************************************************************** */
-/*								    */
-/*			VI Emulation Mode			    */
-/*								    */
-/* **************************************************************** */
-
-/* Last string searched for from `/' or `?'. */
-static char *vi_last_search = (char *)NULL;
-static int vi_histpos;
-
-/* Non-zero means enter insertion mode. */
-int vi_doing_insert = 0;
-
-/* *** UNCLEAN *** */
-/* Command keys which do movement for xxx_to commands. */
-static char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
-
-/* Keymap used for vi replace characters.  Created dynamically since
-   rarely used. */
-static Keymap vi_replace_map = (Keymap)NULL;
-
-/* The number of characters inserted in the last replace operation. */
-static vi_replace_count = 0;
-
-/* Yank the nth arg from the previous line into this line at point. */
-rl_vi_yank_arg (count)
-     int count;
-{
-  rl_yank_nth_arg (count, 0);
-}
-
-/* Search again for the last thing searched for. */
-rl_vi_search_again (ignore, key)
-     int ignore, key;
-{
-  switch (key)
-    {
-    case 'n':
-      rl_vi_dosearch (vi_last_search, -1);
-      break;
-
-    case 'N':
-      rl_vi_dosearch (vi_last_search, 1);
-      break;
-    }
-}
-
-/* Do a vi style search. */
-rl_vi_search (count, key)
-     int count, key;
-{
-  int dir, c, save_pos;
-  char *p;
-
-  switch (key)
-    {
-    case '?':
-      dir = 1;
-      break;
-
-    case '/':
-      dir = -1;
-      break;
-
-    default:
-      ding ();
-      return;
-    }
-
-  vi_histpos = where_history ();
-  maybe_save_line ();
-  save_pos = rl_point;
-
-  /* Reuse the line input buffer to read the search string. */
-  the_line[0] = 0;
-  rl_end = rl_point = 0;
-  p = (char *)alloca (2 + (rl_prompt ? strlen (rl_prompt) : 0));
-
-  sprintf (p, "%s%c", rl_prompt ? rl_prompt : "", key);
-
-  rl_message (p, 0, 0);
-
-  while (c = rl_read_key ())
-    {
-      switch (c)
-	{
-	case CTRL('H'):
-	case RUBOUT:
-	  if (rl_point == 0)
-	    {
-	      maybe_unsave_line ();
-	      rl_clear_message ();
-	      rl_point = save_pos;
-	      return;
-	    }
-
-	case CTRL('W'):
-	case CTRL('U'):
-	  rl_dispatch (c, keymap);
-	  break;
-
-	case ESC:
-	case RETURN:
-	case NEWLINE:
-	  goto dosearch;
-	  break;
-
-	case CTRL('C'):
-	  maybe_unsave_line ();
-	  rl_clear_message ();
-	  rl_point = 0;
-	  ding ();
-	  return;
-
-	default:
-	  rl_insert (1, c);
-	  break;
-	}
-      rl_redisplay ();
-    }
- dosearch:
-  if (vi_last_search)
-    free (vi_last_search);
-
-  vi_last_search = savestring (the_line);
-  rl_vi_dosearch (the_line, dir);
-}
-
-rl_vi_dosearch (string, dir)
-     char *string;
-     int dir;
-{
-#ifdef 0
-  int old, save = vi_histpos;
-  HIST_ENTRY *h;
-
-  if (string == 0 || *string == 0 || vi_histpos < 0)
-    {
-      ding ();
-      return;
-    }
-
-  if ((save = history_search_pos (string, dir, vi_histpos + dir)) == -1)
-    {
-      maybe_unsave_line ();
-      rl_clear_message ();
-      rl_point = 0;
-      ding ();
-      return;
-    }
-
-  vi_histpos = save;
-
-  old = where_history ();
-  history_set_pos (vi_histpos);
-  h = current_history ();
-  history_set_pos (old);
-
-  strcpy (the_line, h->line);
-  rl_undo_list = (UNDO_LIST *)h->data;
-  rl_end = strlen (the_line);
-  rl_point = 0;
-  rl_clear_message ();
-#endif
-}
-
-/* Completion, from vi's point of view. */
-rl_vi_complete (ignore, key)
-     int ignore, key;
-{
-  if (!whitespace (the_line[rl_point]))
-    {
-      if (!whitespace (the_line[rl_point + 1]))
-	rl_vi_end_word (1, 'E');
-      rl_point++;
-    }
-
-  if (key == '*')
-    rl_complete_internal ('*');
-  else
-    rl_complete (0, key);
-
-  rl_vi_insertion_mode ();
-}
-
-/* Previous word in vi mode. */
-rl_vi_prev_word (count, key)
-     int count, key;
-{
-  if (count < 0)
-    {
-      rl_vi_next_word (-count, key);
-      return;
-    }
-
-  if (uppercase_p (key))
-    rl_vi_bWord (count);
-  else
-    rl_vi_bword (count);
-}
-
-/* Next word in vi mode. */
-rl_vi_next_word (count, key)
-     int count;
-{
-  if (count < 0)
-    {
-      rl_vi_prev_word (-count, key);
-      return;
-    }
-
-  if (uppercase_p (key))
-    rl_vi_fWord (count);
-  else
-    rl_vi_fword (count);
-}
-
-/* Move to the end of the ?next? word. */
-rl_vi_end_word (count, key)
-     int count, key;
-{
-  if (count < 0)
-    {
-      ding ();
-      return;
-    }
-
-  if (uppercase_p (key))
-    rl_vi_eWord (count);
-  else
-    rl_vi_eword (count);
-}
-
-/* Move forward a word the way that 'W' does. */
-rl_vi_fWord (count)
-     int count;
-{
-  while (count-- && rl_point < (rl_end - 1))
-    {
-      /* Skip until whitespace. */
-      while (!whitespace (the_line[rl_point]) && rl_point < rl_end)
-	rl_point++;
-
-      /* Now skip whitespace. */
-      while (whitespace (the_line[rl_point]) && rl_point < rl_end)
-	rl_point++;
-    }
-}
-
-rl_vi_bWord (count)
-     int count;
-{
-  while (count-- && rl_point > 0)
-    {
-      while (rl_point-- >= 0 && whitespace (the_line[rl_point]));
-      while (rl_point >= 0 && !whitespace (the_line[rl_point]))
-	rl_point--;
-      rl_point++;
-    }
-}
-
-rl_vi_eWord (count)
-     int count;
-{
-  while (count -- && rl_point < (rl_end - 1))
-    {
-      while (rl_point++ < rl_end && whitespace (the_line[rl_point]));
-      while (rl_point++ < rl_end && !whitespace (the_line[rl_point]));
-      rl_point--;
-    }
-}
-
-rl_vi_fword (count)
-     int count;
-{
-  while (count -- && rl_point < (rl_end - 1))
-    {
-      if (isident (the_line[rl_point]))
-	{
-	  while (isident (the_line[rl_point]) && rl_point < rl_end)
-	    rl_point += 1;
-	}
-      else if (!whitespace (the_line[rl_point]))
-	{
-	  while (!isident (the_line[rl_point]) &&
-		 !whitespace (the_line[rl_point]) && rl_point < rl_end)
-	    rl_point += 1;
-	}
-
-      while (whitespace (the_line[rl_point]) && rl_point < rl_end)
-	rl_point++;
-    }
-}
-
-rl_vi_bword (count)
-     int count;
-{
-  while (count -- && rl_point > 0)
-    {
-      while (--rl_point > 0 && whitespace (the_line[rl_point]));
-      if (rl_point > 0)
-	{
-	  if (isident (the_line[rl_point]))
-	    while (--rl_point >= 0 && isident (the_line[rl_point]));
-	  else
-	    while (--rl_point >= 0 && !isident (the_line[rl_point]) &&
-		   !whitespace (the_line[rl_point]));
-	  rl_point++;
-	}
-    }
-}
-
-rl_vi_eword (count)
-     int count;
-{
-  while (count -- && rl_point < rl_end - 1)
-    {
-      while (++rl_point < rl_end && whitespace (the_line[rl_point]));
-
-      if (rl_point < rl_end)
-	{
-	  if (isident (the_line[rl_point]))
-	    while (++rl_point < rl_end && isident (the_line[rl_point]));
-	  else
-	    while (++rl_point < rl_end && !isident (the_line[rl_point])
-		   && !whitespace (the_line[rl_point]));
-	  rl_point--;
-	}
-    }
-}
-
-rl_vi_insert_beg ()
-{
-  rl_beg_of_line ();
-  rl_vi_insertion_mode ();
-  return 0;
-}
-
-rl_vi_append_mode ()
-{
-  if (rl_point < rl_end)
-    rl_point += 1;
-  rl_vi_insertion_mode ();
-  return 0;
-}
-
-rl_vi_append_eol ()
-{
-  rl_end_of_line ();
-  rl_vi_append_mode ();
-  return 0;
-}
-
-/* What to do in the case of C-d. */
-rl_vi_eof_maybe (count, c)
-     int count, c;
-{
-  rl_newline (1, '\n');
-}
-
-/* Insertion mode stuff. */
-
-/* Switching from one mode to the other really just involves
-   switching keymaps. */
-rl_vi_insertion_mode ()
-{
-  keymap = vi_insertion_keymap;
-}
-
-rl_vi_movement_mode ()
-{
-  if (rl_point > 0)
-    rl_backward (1);
-
-  keymap = vi_movement_keymap;
-  vi_done_inserting ();
-}
-
-vi_done_inserting ()
-{
-  if (vi_doing_insert)
-    {
-      rl_end_undo_group ();
-      vi_doing_insert = 0;
-    }
-}
-
-rl_vi_arg_digit (count, c)
-     int count, c;
-{
-  if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
-    rl_beg_of_line ();
-  else
-    rl_digit_argument (count, c);
-}
-
-/* Doesn't take an arg count in vi */
-rl_vi_change_case (ignore1, ignore2)
-     int ignore1, ignore2;
-{
-  char c = 0;
-
-  if (uppercase_p (the_line[rl_point]))
-    c = to_lower (the_line[rl_point]);
-  else if (lowercase_p (the_line[rl_point]))
-    c = to_upper (the_line[rl_point]);
-
-  /* Vi is kind of strange here. */
-  if (c)
-    {
-      rl_begin_undo_group ();
-      rl_delete (1, c);
-      rl_insert (1, c);
-      rl_end_undo_group ();
-      rl_vi_check ();
-    }
-  else
-    rl_forward (1);
-}
-
-rl_vi_put (count, key)
-     int count, key;
-{
-  if (!uppercase_p (key))
-    rl_forward (1);
-
-  rl_yank ();
-  rl_backward (1);
-}
-
-rl_vi_check ()
-{
-  if (rl_point && rl_point == rl_end)
-    rl_point--;
-}
-
-rl_vi_column (count)
-{
-  if (count > rl_end)
-    rl_end_of_line ();
-  else
-    rl_point = count - 1;
-}
-
-int
-rl_vi_domove (key, nextkey)
-     int key, *nextkey;
-{
-  int c, save;
-
-  rl_mark = rl_point;
-  c = rl_read_key ();
-  *nextkey = c;
-
-  if (!member (c, vi_motion))
-    {
-      if (digit (c))
-	{
-	  save = rl_numeric_arg;
-	  rl_digit_loop1 ();
-	  rl_numeric_arg *= save;
-	}
-      else if ((key == 'd' && c == 'd') ||
-	       (key == 'c' && c == 'c'))
-	{
-	  rl_mark = rl_end;
-	  rl_beg_of_line ();
-	  return (0);
-	}
-      else
-	return (-1);
-    }
-
-  rl_dispatch (c, keymap);
-
-  /* No change in position means the command failed. */
-  if (rl_mark == rl_point)
-    return (-1);
-
-  if ((c == 'w' || c == 'W') && rl_point < rl_end)
-    rl_point--;
-
-  if (rl_mark < rl_point)
-    exchange (rl_point, rl_mark);
-
-  return (0);
-}
-
-/* A simplified loop for vi. Don't dispatch key at end.
-   Don't recognize minus sign? */
-rl_digit_loop1 ()
-{
-  int key, c;
-
-  while (1)
-    {
-      rl_message ("(arg: %d) ", arg_sign * rl_numeric_arg, 0);
-      key = c = rl_read_key ();
-
-      if (keymap[c].type == ISFUNC &&
-	  keymap[c].function == rl_universal_argument)
-	{
-	  rl_numeric_arg *= 4;
-	  continue;
-	}
-      c = UNMETA (c);
-      if (numeric (c))
-	{
-	  if (rl_explicit_arg)
-	    rl_numeric_arg = (rl_numeric_arg * 10) + (c - '0');
-	  else
-	    rl_numeric_arg = (c - '0');
-	  rl_explicit_arg = 1;
-	}
-      else
-	{
-	  rl_clear_message ();
-	  rl_stuff_char (key);
-	}
-    }
-}
-
-rl_vi_delete_to (count, key)
-     int count, key;
-{
-  int c;
-
-  if (uppercase_p (key))
-    rl_stuff_char ('$');
-
-  if (rl_vi_domove (key, &c))
-    {
-      ding ();
-      return;
-    }
-
-  if ((c != '|') && (c != 'h') && rl_mark < rl_end)
-    rl_mark++;
-
-  rl_kill_text (rl_point, rl_mark);
-}
-
-rl_vi_change_to (count, key)
-     int count, key;
-{
-  int c;
-
-  if (uppercase_p (key))
-    rl_stuff_char ('$');
-
-  if (rl_vi_domove (key, &c))
-    {
-      ding ();
-      return;
-    }
-
-  if ((c != '|') && (c != 'h') && rl_mark < rl_end)
-    rl_mark++;
-
-  rl_begin_undo_group ();
-  vi_doing_insert = 1;
-  rl_kill_text (rl_point, rl_mark);
-  rl_vi_insertion_mode ();
-}
-
-rl_vi_yank_to (count, key)
-     int count, key;
-{
-  int c, save = rl_point;
-
-  if (uppercase_p (key))
-    rl_stuff_char ('$');
-
-  if (rl_vi_domove (key, &c))
-    {
-      ding ();
-      return;
-    }
-
-  rl_begin_undo_group ();
-  rl_kill_text (rl_point, rl_mark);
-  rl_end_undo_group ();
-  rl_do_undo ();
-  rl_point = save;
-}
-
-rl_vi_delete (count)
-{
-  if (rl_point >= rl_end - 1)
-    {
-      rl_delete (count, 0);
-      if (rl_point > 0)
-	rl_backward (1);
-    }
-  else
-    rl_delete (count, 0);
-}
-
-/* Turn the current line into a comment in shell history.  A ksh function */
-rl_vi_comment ()
-{
-  rl_beg_of_line ();
-  rl_insert_text (": ");	/* # doesn't work in interactive mode */
-  rl_redisplay ();
-  rl_newline (1, '\010');
-}
-
-rl_vi_first_print ()
-{
-  rl_back_to_indent ();
-}
-
-rl_back_to_indent (ignore1, ignore2)
-     int ignore1, ignore2;
-{
-  rl_beg_of_line ();
-  while (rl_point < rl_end && whitespace (the_line[rl_point]))
-    rl_point++;
-}
-
-/* NOTE: it is necessary that opposite directions are inverses */
-#define	FTO	 1		/* forward to */
-#define BTO	-1		/* backward to */
-#define FFIND	 2		/* forward find */
-#define BFIND	-2		/* backward find */
-
-rl_vi_char_search (count, key)
-     int count, key;
-{
-  static char target;
-  static int orig_dir, dir;
-  int pos;
-
-  if (key == ';' || key == ',')
-    dir = (key == ';' ? orig_dir : -orig_dir);
-  else
-    {
-      target = rl_getc (in_stream);
-
-      switch (key)
-	{
-	case 't':
-	  orig_dir = dir = FTO;
-	  break;
-
-	case 'T':
-	  orig_dir = dir = BTO;
-	  break;
-
-	case 'f':
-	  orig_dir = dir = FFIND;
-	  break;
-
-	case 'F':
-	  orig_dir = dir = BFIND;
-	  break;
-	}
-    }
-
-  pos = rl_point;
-
-  if (dir < 0)
-    {
-      pos--;
-      do
-	{
-	  if (the_line[pos] == target)
-	    {
-	      if (dir == BTO)
-		rl_point = pos + 1;
-	      else
-		rl_point = pos;
-	      return;
-	    }
-	}
-      while (pos--);
-
-      if (pos < 0)
-	{
-	  ding ();
-	  return;
-	}
-    }
-  else
-    {			/* dir > 0 */
-      pos++;
-      do
-	{
-	  if (the_line[pos] == target)
-	    {
-	      if (dir == FTO)
-		rl_point = pos - 1;
-	      else
-		rl_point = pos;
-	      return;
-	    }
-	}
-      while (++pos < rl_end);
-
-      if (pos >= (rl_end - 1))
-	ding ();
-    }
-}
-
-/* Match brackets */
-rl_vi_match ()
-{
-  int count = 1, brack, pos;
-
-  pos = rl_point;
-  if ((brack = rl_vi_bracktype (the_line[rl_point])) == 0)
-    {
-      while ((brack = rl_vi_bracktype (the_line[rl_point])) == 0 &&
-	     rl_point < rl_end - 1)
-	rl_forward (1);
-
-      if (brack <= 0)
-	{
-	  rl_point = pos;
-	  ding ();
-	  return;
-	}
-    }
-
-  pos = rl_point;
-
-  if (brack < 0)
-    {
-      while (count)
-	{
-	  if (--pos >= 0)
-	    {
-	      int b = rl_vi_bracktype (the_line[pos]);
-	      if (b == -brack)
-		count--;
-	      else if (b == brack)
-		count++;
-	    }
-	  else
-	    {
-	      ding ();
-	      return;
-	    }
-	}
-    }
-  else
-    {			/* brack > 0 */
-      while (count)
-	{
-	  if (++pos < rl_end)
-	    {
-	      int b = rl_vi_bracktype (the_line[pos]);
-	      if (b == -brack)
-		count--;
-	      else if (b == brack)
-		count++;
-	    }
-	  else
-	    {
-	      ding ();
-	      return;
-	    }
-	}
-    }
-  rl_point = pos;
-}
-
-int
-rl_vi_bracktype (c)
-     int c;
-{
-  switch (c)
-    {
-    case '(': return  1;
-    case ')': return -1;
-    case '[': return  2;
-    case ']': return -2;
-    case '{': return  3;
-    case '}': return -3;
-    default:  return  0;
-    }
-}
-
-rl_vi_change_char ()
-{
-  int c;
-
-  c = rl_getc (in_stream);
-
-  switch (c)
-    {
-    case '\033':
-    case CTRL('C'):
-      return;
-
-    default:
-      rl_begin_undo_group ();
-      rl_delete (1, c);
-      rl_insert (1, c);
-      rl_end_undo_group ();
-      break;
-    }
-}
-
-rl_vi_subst (count, key)
-     int count, key;
-{
-  rl_begin_undo_group ();
-  vi_doing_insert = 1;
-
-  if (uppercase_p (key))
-    {
-      rl_beg_of_line ();
-      rl_kill_line (1);
-    }
-  else
-    rl_delete (1, key);
-
-  rl_vi_insertion_mode ();
-}
-
-rl_vi_overstrike (count, key)
-     int count, key;
-{
-  int i;
-
-  if (vi_doing_insert == 0)
-    {
-      vi_doing_insert = 1;
-      rl_begin_undo_group ();
-    }
-
-  for (i = 0; i < count; i++)
-    {
-      vi_replace_count++;
-      rl_begin_undo_group ();
-
-      if (rl_point < rl_end)
-	{
-	  rl_delete (1, key);
-	  rl_insert (1, key);
-	}
-      else
-	rl_insert (1, key);
-
-      rl_end_undo_group ();
-    }
-}
-
-rl_vi_overstrike_delete (count)
-     int count;
-{
-  int i, s;
-
-  for (i = 0; i < count; i++)
-    {
-      if (vi_replace_count == 0)
-	{
-	  ding ();
-	  break;
-	}
-      s = rl_point;
-
-      if (rl_do_undo ())
-	vi_replace_count--;
-
-      if (rl_point == s)
-	rl_backward (1);
-    }
-
-  if (vi_replace_count == 0 && vi_doing_insert)
-    {
-      rl_end_undo_group ();
-      rl_do_undo ();
-      vi_doing_insert = 0;
-    }
-}
-
-rl_vi_replace ()
-{
-  int i;
-
-  vi_replace_count = 0;
-
-  vi_replace_map = rl_make_bare_keymap ();
-
-  for (i = ' '; i < 127; i++)
-    vi_replace_map[i].function = rl_vi_overstrike;
-
-  vi_replace_map[RUBOUT].function = rl_vi_overstrike_delete;
-  vi_replace_map[ESC].function = rl_vi_movement_mode;
-  vi_replace_map[RETURN].function = rl_newline;
-  vi_replace_map[NEWLINE].function = rl_newline;
-  keymap = vi_replace_map;
-}
-
-/*
- * Try to complete the word we are standing on or the word that ends with
- * the previous character. A space matches everything.
- * Word delimiters are space and ;.
- */
-rl_vi_possible_completions()
-{
-  int save_pos = rl_point;
-
-  if (!index (" ;", the_line[rl_point]))
-    {
-      while (!index(" ;", the_line[++rl_point]))
-	;
-    }
-  else if (the_line[rl_point-1] == ';')
-    {
-      ding ();
-      return (0);
-    }
-
-  rl_possible_completions ();
-  rl_point = save_pos;
-
-  return (0);
-}
End of readline/vi_mode.c
echo readline/Makefile 1>&2
sed 's/^-//' >readline/Makefile <<'End of readline/Makefile'
-## -*- text -*- ####################################################
-#								   #
-# Makefile for readline and history libraries.			   #
-#								   #
-####################################################################
-
-# Here is a rule for making .o files from .c files that doesn't force
-# the type of the machine (like -sun3) into the flags.
-.c.o:
-	$(CC) -c $(CFLAGS) $(LOCAL_INCLUDES) $(CPPFLAGS) $*.c
-
-# Destination installation directory.  The libraries are copied to DESTDIR
-# when you do a `make install', and the header files to INCDIR/readline/*.h.
-DESTDIR = /usr/gnu/lib
-INCDIR = /usr/gnu/include
-
-# Define TYPES as -DVOID_SIGHANDLER if your operating system uses
-# a return type of "void" for signal handlers.
-TYPES = -DVOID_SIGHANDLER
-
-# Define SYSV as -DSYSV if you are using a System V operating system.
-#SYSV = -DSYSV
-
-# HP-UX compilation requires the BSD library.
-#LOCAL_LIBS = -lBSD
-
-# Xenix compilation requires -ldir -lx
-#LOCAL_LIBS = -ldir -lx
-
-# Comment this out if you don't think that anyone will ever desire
-# the vi line editing mode and features.
-READLINE_DEFINES = -DVI_MODE
-
-DEBUG_FLAGS = 
-LDFLAGS = $(DEBUG_FLAGS) 
-CFLAGS = $(DEBUG_FLAGS) $(TYPE) $(SYSV) -I.
-
-# A good alternative is gcc -traditional.
-CC = gcc -traditional
-RANLIB = /usr/bin/ranlib
-AR = ar
-RM = rm
-CP = cp
-
-LOCAL_INCLUDES = -I../
-
-CSOURCES = readline.c history.c funmap.c keymaps.c vi_mode.c \
-	   emacs_keymap.c vi_keymap.c keymaps.c
-
-HSOURCES = readline.h chardefs.h history.h keymaps.h
-SOURCES  = $(CSOURCES) $(HSOURCES)
-
-DOCUMENTATION = readline.texinfo inc-readline.texinfo \
-		history.texinfo inc-history.texinfo
-
-SUPPORT = COPYING Makefile $(DOCUMENTATION) ChangeLog
-
-THINGS_TO_TAR = $(SOURCES) $(SUPPORT)
-
-##########################################################################
-
-all: readline.o funmap.o keymaps.o
-# all: libreadline.a
-
-libreadline.a:	readline.o history.o funmap.o keymaps.o
-		$(RM) -f libreadline.a
-		$(AR) clq libreadline.a readline.o history.o funmap.o keymaps.o
-		-if [ -f $(RANLIB) ]; then $(RANLIB) libreadline.a; fi
-
-readline.o:	readline.h chardefs.h  keymaps.h history.h readline.c vi_mode.c
-	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
-		$(LOCAL_INCLUDES) $*.c
-
-history.o:	history.c history.h
-	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
-		$(LOCAL_INCLUDES) $*.c
-
-funmap.o:	readline.h
-	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
-		$(LOCAL_INCLUDES) $*.c
-
-keymaps.o:	emacs_keymap.c vi_keymap.c keymaps.h chardefs.h keymaps.c
-	$(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
-		 $(LOCAL_INCLUDES) $*.c
-
-libtest:	libreadline.a libtest.c
-		$(CC) -o libtest $(CFLAGS) $(CPPFLAGS) -L. libtest.c -lreadline -ltermcap
-
-readline: readline.c history.o keymaps.o funmap.o readline.h chardefs.h
-	$(CC) $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
-		$(LOCAL_INCLUDES) -DTEST -o readline readline.c funmap.o \
-		 keymaps.o history.o -L. -ltermcap
-
-readline.tar:	$(THINGS_TO_TAR)
-		tar -cf readline.tar $(THINGS_TO_TAR)
-
-readline.tar.Z:	readline.tar
-		compress -f readline.tar
-
-install:	$(DESTDIR)/libreadline.a includes
-
-includes:
-		if [ ! -r $(INCDIR)/readline ]; then\
-		 mkdir $(INCDIR)/readline;\
-		 chmod a+r $(INCDIR)/readline;\
-		fi
-		$(CP) readline.h keymaps.h chardefs.h $(INCDIR)/readline/
-clean:
-		rm -f *.o *.a *.log *.cp *.tp *.vr *.fn *.aux *.pg *.toc
-
-$(DESTDIR)/libreadline.a: libreadline.a
-		-mv $(DESTDIR)/libreadline.a $(DESTDIR)/libreadline.old
-		cp libreadline.a $(DESTDIR)/libreadline.a
-		$(RANLIB) -t $(DESTDIR)/libreadline.a
End of readline/Makefile
echo zsh.h 1>&2
sed 's/^-//' >zsh.h <<'End of zsh.h'
-/*
-
-	zsh.h - the header file, basically
-
-	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 "config.h"
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/file.h>
-#include <signal.h>
-#ifdef TERMIOS
-#include <sys/termios.h>
-#else
-#include <sgtty.h>
-#endif
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#define VERSIONSTR "zsh v1.0"
-
-#define FOREVER for(;;)
-
-/* size of job table */
-
-#define MAXJOB 16
-
-void *realloc(void *,int),*malloc(int),*calloc(int,int);
-
-char *getenv(char *);
-
-/* the tokens */
-
-enum xfubar {
-	HQUOT = -127,	/* quote char used for history */
-	ALPOP,			/* marker, causes parser to pop alias stack */
-	HERR,				/* history error indicator */
-	Pound,			/* # */
-	String,			/* $ */
-	Hat,				/* ^ */
-	Star,				/* * */
-	Inpar,			/* ( */
-	Outpar,			/* ) */
-	Qstring,			/* $, in quotes */
-	Equals,			/* = (initial) */
-	Bar,				/* |, except when used as a pipe char */
-	Inbrace,			/* {, except when used for current shells */
-	Outbrace,		/* }, except when used for current shells */
-	Inbrack,			/* [ */
-	Outbrack,		/* ] */
-	Tick,				/* ` */
-	Inang,			/* <, except when used for redirection */
-	Outang,			/* >, except when used for redirection */
-	Quest,			/* ? */
-	Tilde,			/* ~ (initial) */
-	Qtick,			/* `, in quotes */
-	Comma,			/* , */
-	Nularg			/* marker, keeps explicit null arguments around,
-							does some other stuff */
-	};
-
-/* HQUOT separately defined in readline.c */
-
-/* returns true if X is a token */
-
-#define istok(X) (((char) (X)) <= Nularg)
-
-/* HQUOT in the form of a string */
-
-#define HQUOTS "\x81"
-
-/* ALPOP in the form of a string */
-
-#define ALPOPS " \x82"
-
-extern char **environ;
-
-/* list of tokens */
-
-extern char *tokens;
-
-/* tokens used in peek variable with gettok/matchit */
-/* do not confuse with above tokens; above tokens appear in strings,
-	following tokens possible values of 'peek' variable */
-
-enum xpeek {
-	EMPTY,			/* nothing gotten yet */
-	SEMI,				/* ; */
-	DSEMI,			/* ;; */
-	AMPER,			/* & */
-	DAMPER,			/* && */
-	NEWLIN,			/* \n */
-	INPAR,			/* ( */
-	INBRACE,			/* { */
-	OUTPAR,			/* ) */
-	OUTBRACE,		/* } */
-	OUTANG,			/* > */
-	OUTANGBANG,		/* >! */
-	DOUTANG,			/* >> */
-	DOUTANGBANG,	/* >>! */
-	INANG,			/* < */
-	DINANG,			/* << */
-	INANGAMP,		/* <& */
-	OUTANGAMP,		/* >& */
-	OUTANGAMPBANG,	/* >&! */
-	DOUTANGAMP,		/* >>& */
-	DOUTANGAMPBANG,	/* >>&! */
-	BAR,				/* | */
-	DBAR,				/* || */
-	BARAMP,			/* |& */
-	BANG,				/* ! */
-	STRING,			/* string of chars and tokens */
-	ENVSTRING,		/* string of chars and tokens with a = in it */
-						/* the below are all reserved words */
-	DO,
-	DONE,
-	ESAC,
-	THEN,
-	ELIF,
-	ELSE,
-	FI,
-	FOR,
-	CASE,
-	IF,
-	WHILE,
-	FUNC,
-	REPEAT,
-	TIME,
-	UNTIL,
-	EXEC,
-	COMMAND,
-	SELECT,
-	COPROC
-	};
-
-/* linked list data type */
-
-typedef struct xlist *table;
-typedef struct xnode *Node;
- 
-struct xnode {
-   Node next,last;
-   void *dat;
-   };
-struct xlist {
-   Node first,last;
-   };
-
-
-typedef struct pnode *pline;
-typedef struct lnode *list;
-typedef struct l2node *list2;
-typedef struct cnode *comm;
-typedef struct jobnode *job;
-
-/* tree element for lists */
-
-struct lnode {
-   struct l2node *left;
-   struct lnode *right;
-   int type;
-   };
-
-enum ltype {
-   SYNC,		/* ; */
-	ASYNC		/* & */
-   };
-
-/* tree element for sublists */
-
-struct l2node {
-	struct pnode *left;
-	struct l2node *right;
-	int type;
-	int flags; /* one of PFLAGS below; applies to pnode *left */
-	};
-
-enum l2type {
-	ORNEXT = 10,	/* || */
-	ANDNEXT			/* && */
-	};
-
-#define PFLAG_TIMED 4		/* time ... */
-#define PFLAG_NOT 1			/* ! ... */
-#define PFLAG_COPROC 32		/* coproc ... */
-
-/* tree element for pipes */
-
-struct pnode {
-   struct cnode *left;
-   struct pnode *right;
-   int type;
-   };
-
-enum ptype {
-   END,		/* pnode *right is null */
-	PIPE		/* pnode *right is the rest of the pipeline */
-   };
-
-/* tree element for commands */
-
-struct cnode {
-   struct lnode *left;	/* for SUBSH/CURSH/SHFUNC */
-   char *cmd;				/* command name */
-   table args;				/* argmument list (char *'s) */
-   table redir;			/* i/o redirections (struct fnode *'s) */
-	table vars;				/* parameter list (char *'s), can be null;
-									two entries in table for each parameter
-									assignment; "name" and "value" */
-   int type;
-	int flags;
-	void *info;				/* pointer to appropriate control structure,
-									if this is a CFOR, CWHILE, etc. */
-   };
-
-enum ctype {
-	SIMPLE,		/* simple command */
-	SUBSH,		/* ( left ) */
-	CURSH,		/* { left } */
-	SHFUNC,		/* converted to { left } in execcomm */
-	CFOR,
-	CWHILE,
-	CREPEAT,
-	CIF,
-	CCASE,
-	CSELECT
-	};
-#define CFLAG_EXEC 1			/* exec ... */
-#define CFLAG_COMMAND 2		/* command ... */
-
-struct fnode {
-	union {
-		char *name;		/* source/dest filename */
-		int fd2;			/* source/dest file descriptor */
-		} u;
-   int type;
-	int fd1;				/* affected file descriptor */
-   };
-
-enum ftype {
-	WRITE,			/* #> name */
-	WRITENOW,		/* #>! name */
-	APP,				/* #>> name */
-	APPNOW,			/* #>>! name */
-	READ,				/* #< name */
-	HEREDOC,			/* #<< fd2 */
-	MERGE,			/* #<& fd2 */
-	MERGEOUT,		/* #>& fd2 */
-	CLOSE,			/* #>&-, #<&- */
-	INPIPE,			/* #< name, where name is <(...) */
-	OUTPIPE,			/* #> name, where name is >(...)  */
-	NONE
-	};
-
-struct fornode {		/* for/select */
-	char *name;			/* parameter to assign values to */
-	list list;			/* list of names to loop through */
-	int inflag;			/* != 0 if 'in ...' was specified */
-	};
-struct casenode {		/* arg list of cnode struct contains word to test */
-	struct casenode *next;	/* next pattern */
-	char *pat;
-	list list;			/* list to execute */
-	};
-struct ifnode {
-	struct ifnode *next;
-	list ifl;		/* if/elif test list (can be null in case of else) */
-	list thenl;		/* then list */
-	};
-struct whilenode {
-	list cont;		/* condition */
-	list loop;		/* list to execute until condition met */
-	int cond;		/* 0 for while, 1 for until */
-	};
-struct repeatnode {
-	int count;		/* # of iterations */
-	list list;
-	};
-
-
-/* structure used for multiple i/o redirection */
-/* one for each fd open */
-
-struct mnode {
-	int ct;				/* # of redirections on this fd */
-	int rflag;			/* 0 if open for reading, 1 if open for writing */
-	int pipe;			/* fd of pipe if ct > 1 */
-	int fds[NOFILE];
-   }; 
-
-/* node used in command hash table */
-
-struct chnode 
-{
-	int type;
-	int globstat;		/* status of filename gen for this command */
-	union {
-		char *nam;		/* full pathname if type != BUILTIN */
-		int (*func)();	/* func to exec if type == BUILTIN */
-		} u;
-	};
-
-enum chtype {
-	EXCMD_PREDOT,		/* external command in PATH before . */
-	EXCMD_POSTDOT,		/* external command in PATH after . */
-	BUILTIN
-	};
-
-/* value for globstat field in chnode
-
-	sample command: foo -xyz -pdq bar ble boz */
-
-enum globx {
-	GLOB,			/* all args globbed */
-	MOSTGLOB,	/* ble, boz globbed */
-	NOGLOB		/* no args globbed */
-	};
-
-/* node used in parameter hash table */
-
-struct pmnode {
-	union {
-		char *str;		/* value */
-		long val;		/* value if declared integer */
-		} u;
-	int isint;			/* != 0 if declared integer */
-	};
-
-/* tty state structure */
-
-struct ttyinfo {
-#ifdef TERMIOS
-	struct termios termios;
-#else
-	struct sgttyb sgttyb;
-	struct tchars tchars;
-	struct ltchars ltchars;
-#endif
-	struct winsize winsize;
-	};
-
-extern struct ttyinfo shttyinfo;
-
-/* entry in job table */
-
-struct jobnode {
-	long gleader;					/* process group leader of this job */
-	int stat;
-	char *cwd;						/* current working dir of shell when
-											this job was spawned */
-	struct procnode *procs;		/* list of processes */
-	table filelist;				/* list of files to delete when done */
-	struct ttyinfo ttyinfo;		/* saved tty state */
-	};
-
-#define STAT_CHANGED 1		/* status changed and not reported */
-#define STAT_STOPPED 2		/* all procs stopped or exited */
-#define STAT_TIMED 4			/* job is being timed */
-#define STAT_DONE 8
-#define STAT_LOCKED 16		/* shell is finished creating this job,
-										may be deleted from job table */
-#define STAT_INUSE 64		/* this job entry is in use */
-
-#define SP_RUNNING -1		/* fake statusp for running jobs */
-
-/* node in job process lists */
-
-struct procnode {
-	struct procnode *next;
-	long pid;
-	char *text;						/* text to print when 'jobs' is run */
-	int statusp;					/* return code from wait3() */
-	int lastfg;						/* set if this procnode represents a
-											fragment of a pipeline run in a subshell
-											for commands like:
-
-											foo | bar | ble
-
-											where foo is a current shell function
-											or control structure.  The command
-											actually executed is:
-
-											foo | (bar | ble)
-
-											That's two procnodes in the parent
-											shell, the latter having this flag set. */
-	struct timeval ru_utime;
-	struct timeval ru_stime;
-	time_t bgtime;					/* time job was spawned */
-	time_t endtime;				/* time job exited */
-	};
-
-/* node in alias hash table */
-
-struct anode {
-	char *text;			/* expansion of alias */
-	int cmd;				/* one for regular aliases,
-								zero for -a aliases,
-								negative for reserved words */
-	int inuse;			/* alias is being expanded */
-	};
-
-/* node in sched list */
-
-struct schnode {
-	struct schnode *next;
-	char *cmd;		/* command to run */
-	time_t time;	/* when to run it */
-	};
-
-#define MAXAL 20	/* maximum number of aliases expanded at once */
-
-typedef struct xhtab *htable;
-
-/* node in hash table */
-
-struct hnode {
-	struct hnode *hchain;
-	char *nam;
-	void *dat;
-	};
-
-/* hash table structure */
-
-struct xhtab {
-	int hsize,ct;
-	struct hnode **nodes;	 /* array of size hsize */
-	};
-
-typedef struct xpath *qath;	/* used in globbing - see glob.c */
-typedef struct xcomp *comp;	/* "" */
-
-extern char *sys_errlist[];
-extern int errno;
-
-#define pushnode(X,Y) insnode(X,(Node) X,Y)
-
-#define OPT_INVALID 1	/* opt is invalid, like -$ */
-#define OPT_UNSET 0
-#define OPT_SET 2
-
-#define CLOBBER '1'
-#define NOBADPATTERN '2'
-#define NONOMATCH '3'
-#define GLOBDOTS '4'
-#define NOTIFY '5'
-#define ALLEXPORT 'a'
-#define ERREXIT 'e'
-#define BGNICE '6'
-#define IGNOREEOF '7'
-#define KEYWORD 'k'
-#define MARKDIRS '8'
-#define MONITOR 'm'
-#define NOEXEC 'n'
-#define NOGLOBOPT 'F'
-#define NORCS 'f'
-#define SHINSTDIN 's'
-#define NOUNSET 'u'
-#define VERBOSE 'v'
-#define XTRACE 'x'
-#define INTERACTIVE 'i'
-#define AUTOLIST '9'
-#define CORRECT '0'
-#define DEXTRACT 'A'
-#define NOBEEP 'B'
-#define PRINTEXITVALUE 'C'
-#define PUSHDTOHOME 'D'
-#define PUSHDSILENT 'E'
-#define NULLGLOB 'G'
-#define RMSTARSILENT 'H'
-#define IGNOREBRACES 'I'
-#define CDABLEVARS 'J'
-#define NOBANGHIST 'K'
-
-#define ALSTAT_MORE 1	/* last alias ended with ' ' */
-#define ALSTAT_JUNK 2	/* don't put word in history list */
-
-#undef isset
-#define isset(X) (opts[X])
-#define unset(X) (!opts[X])
-#define interact (isset(INTERACTIVE))
-#define jobbing (isset(MONITOR))
-#define nointr() signal(SIGINT,SIG_IGN)
-
-#define SIGCOUNT (SIGUSR2+1)
-#define SIGERR (SIGUSR2+1)
-#define SIGDEBUG (SIGUSR2+2)
-#define SIGEXIT 0
-
-#define SP(x) (*((union wait *) &(x)))
-
-#ifndef WEXITSTATUS
-#define	WEXITSTATUS(x)	(((union wait*)&(x))->w_retcode)
-#define	WTERMSIG(x)	(((union wait*)&(x))->w_termsig)
-#define	WSTOPSIG(x)	(((union wait*)&(x))->w_stopsig)
-#endif
-
-#ifndef S_ISBLK
-#define	_IFMT		0170000
-#define	_IFDIR	0040000
-#define	_IFCHR	0020000
-#define	_IFBLK	0060000
-#define	_IFREG	0100000
-#define	_IFLNK	0120000
-#define	_IFSOCK	0140000
-#define	_IFIFO	0010000
-#define	S_ISBLK(m)	(((m)&_IFMT) == _IFBLK)
-#define	S_ISCHR(m)	(((m)&_IFMT) == _IFCHR)
-#define	S_ISDIR(m)	(((m)&_IFMT) == _IFDIR)
-#define	S_ISFIFO(m)	(((m)&_IFMT) == _IFIFO)
-#define	S_ISREG(m)	(((m)&_IFMT) == _IFREG)
-#define	S_ISLNK(m)	(((m)&_IFMT) == _IFLNK)
-#define	S_ISSOCK(m)	(((m)&_IFMT) == _IFSOCK)
-#endif
-
-/* buffered shell input for non-interactive shells */
-
-extern FILE *bshin;
-
-/* null-terminated array of pointers to strings containing elements
-	of PATH and CDPATH */
-
-extern char **path,**cdpath;
-
-/* number of elements in aforementioned array */
-
-extern int pathct,cdpathct;
-
-/* error/break flag */
-
-extern int errflag;
-
-/* current history event number */
-
-extern int cev;
-
-/* if != 0, this is the first line of the command */
-
-extern int firstln;
-
-/* if != 0, this is the first char of the command (not including
-	white space */
-
-extern int firstch;
-
-/* first event number in the history table */
-
-extern int tfev;
-
-/* capacity of history table */
-
-extern int tevs;
-
-/* if = 1, we have performed history substitution on the current line
- 	if = 2, we have used the 'p' modifier */
-
-extern int hflag;
-
-/* default event (usually cev-1, that is, "!!") */
-
-extern int dev;
-
-/* != 0 if we are in the middle of parsing a command (== 0 if we
- 	have not yet parsed the command word */
-
-extern int incmd;
-
-/* the list of history events */
-
-extern table histlist;
-
-/* the current history event (can be NULL) */
-
-extern table curtab;
-
-/* the directory stack */
-
-extern table dirstack;
-
-/* a string containing all the ungot characters (hungetch()) */
-
-extern char *ungots;
-
-/* the pointer to the next character to read from ungots */
-
-extern char *ungotptr;
-
-/* the contents of the IFS parameter */
-
-extern char *ifs;
-
-/* != 0 if this is a subshell */
-
-extern int subsh;
-
-/* # of break levels (break builtin) */
-
-extern int breaks;
-
-/* != 0 if we have a return pending (return builtin) */
-
-extern int retflag;
-
-/* # of nested loops we are in */
-
-extern int loops;
-
-/* # of continue levels */
-
-extern int contflag;
-
-/* the job currently being created/waited for (not current job in the sense
- 	of '+' and '-', that's topjob */
-
-extern int curjob;
-
-/* the current job (+) */
-
-extern int topjob;
-
-/* the previous job (-) */
-
-extern int prevjob;
-
-/* hash table containing the aliases and reserved words */
-
-extern htable alhtab;
-
-/* hash table containing the parameters */
-
-extern htable parmhtab;
-
-/* hash table containing the builtins/hashed commands */
-
-extern htable chtab;
-
-/* hash table containing the shell functions */
-
-extern htable shfunchtab;
-
-/* the job table */
-
-extern struct jobnode jobtab[MAXJOB];
-
-/* the list of sched jobs pending */
-
-extern struct schnode *scheds;
-
-/* the last l for s/l/r/ history substitution */
-
-extern char *last;
-
-/* the last r for s/l/r/ history substitution */
-
-extern char *rast;
-
-/* if peek == STRING or ENVSTRING, the next token */
-
-extern char *tstr;
-
-/* who am i */
-
-extern char *username;
-
-/* the return code of the last command */
-
-extern int lastval;
-
-/* != 0 if this is a login shell */
-
-extern int islogin;
-
-/* the next token (enum xtok) */
-
-extern int peek;
-
-/* the file descriptor associated with the next token, if it
- 	is something like '<' or '>>', etc. */
-
-extern int peekfd;
-
-/* input fd from the coprocess */
-
-extern int spin;
-
-/* output fd from the coprocess */
-
-extern int spout;
-
-/* the last time we checked mail */
-
-extern time_t lastmailcheck;
-
-/* the last modified date on the mail file last time we checked */
-
-extern time_t lastmailval;
-
-/* the last time we checked the people in the WATCH variable */
-
-extern time_t lastwatch;
-
-/* the last time we did the periodic() shell function */
-
-extern time_t lastperiod;
-
-/* $SECONDS = time(NULL) - shtimer */
-
-extern time_t shtimer;
-
-/* the size of the mail file last time we checked */
-
-extern off_t lastmailsize;
-
-/* $$ */
-
-extern long procnum;
-
-/* $! (the pid of the last background command invoked */
-
-extern long proclast;
-
-/* the process group of the shell */
-
-extern long shpgrp;
-
-/* the current working directory */
-
-extern char *cwd;
-
-/* the hostname, truncated after the '.' */
-
-extern char *hostM;
-
-/* the hostname */
-
-extern char *hostm;
-
-/* the home directory */
-
-extern char *home;
-
-/* the positional parameters */
-
-extern table pparms;
-
-/* the list of local variables we have to destroy */
-
-extern table locallist;
-
-/* the shell input fd */
-
-extern int SHIN;
-
-/* the shell tty fd */
-
-extern int SHTTY;
-
-/* the stack of aliases we are expanding */
-
-extern struct anode *alstack[MAXAL];
-
-/* the alias stack pointer; also, the number of aliases currently
- 	being expanded */
-
-extern int alix;
-
-/* != 0 means we are reading input from a string */
-
-extern int strin;
-
-/* == 1 means we are doing TAB expansion
- 	== 2 means expansion has occurred during TAB expansion */
-
-extern int magic;
-
-/* period between periodic() commands, in seconds */
-
-extern int period;
-
-/* != 0 means history is turned off (through !" or setopt nobanghist) */
-
-extern int stophist;
-
-/* != 0 means we have removed the current event from the history list */
-
-extern int histremmed;
-
-/* the options; e.g. if opts['a'] is nonzero, -a is turned on */
-
-extern int opts[128];
-
-/* LINENO */
-
-extern int lineno;
-
-/* != 0 means we have called execlist() and then intend to exit(),
- 	so don't fork if not necessary */
-
-extern int exiting;
-
-/* the limits for child processes */
-
-extern struct rlimit limits[RLIM_NLIMITS];
-
-/* the tokens */
-
-extern char *tokens;
-
-/* the current word in the history list */
-
-extern char *hlastw;
-
-/* the pointer to the current character in the current word
- 	in the history list */
-
-extern char *hlastp;
-
-/* the size of the current word in the history list */
-
-extern int hlastsz;
-
-/* the alias expansion status - if == ALSTAT_MORE, we just finished
-extern 	expanding an alias ending with a space */
-
-extern int alstat;
-
-/* we have printed a 'you have stopped (running) jobs.' message */
-
-extern int stopmsg;
-
-/* the default tty state */
-
-extern struct ttyinfo shttyinfo;
-
-/* signal names */
-
-extern char *sigs[];
-
-/* signals that are trapped = 1, signals ignored =2 */
-
-extern int sigtrapped[];
-
End of zsh.h
echo proto 1>&2
sed 's/^-//' >proto <<'End of proto'
-#! /bin/sh
-#
-# proto - prototype generating script
-#
-# This file is part of zsh, the Z shell.
-#
-# zsh is free software etc etc.
-#
-for i
-do
-	rm $i.pro
-	grep -v '[{};:#]' $i.c | grep '^[A-Za-z]' |
-		grep -v '^[ 	]' |
-		grep -v static | sed 's/$/;/' >$i.pro
-done
-
End of proto
---cut here---cut here---cut here---