commit 53cf1b1c1c3f0c2b5067afccc2976b99a574a089
parent b87bfedf65c289bf0ee5338c9e10492b70b1e8e0
Author: tim <tim>
Date: Wed, 14 May 1997 15:30:41 +0000
Initial revision
Diffstat:
D | CHANGES | | | 278 | ------------------------------------------------------------------------------- |
D | COPYRIGHT | | | 26 | -------------------------- |
D | EXAMPLES | | | 749 | ------------------------------------------------------------------------------- |
D | Makefile.in | | | 80 | ------------------------------------------------------------------------------- |
D | README | | | 197 | ------------------------------------------------------------------------------- |
D | addon.c | | | 22 | ---------------------- |
D | addon.h | | | 38 | -------------------------------------- |
M | builtins.c | | | 44 | +++++++++++++++++++++++++------------------- |
D | config.h.in | | | 44 | -------------------------------------------- |
D | configure | | | 2541 | ------------------------------------------------------------------------------- |
D | configure.in | | | 287 | ------------------------------------------------------------------------------- |
D | cpp | | | 38 | -------------------------------------- |
D | except.c | | | 140 | ------------------------------------------------------------------------------- |
D | exec.c | | | 132 | ------------------------------------------------------------------------------- |
D | execve.c | | | 61 | ------------------------------------------------------------- |
D | fn.c | | | 257 | ------------------------------------------------------------------------------- |
D | footobar.c | | | 337 | ------------------------------------------------------------------------------- |
D | getopt.c | | | 50 | -------------------------------------------------- |
D | glob.c | | | 278 | ------------------------------------------------------------------------------- |
D | glom.c | | | 433 | ------------------------------------------------------------------------------- |
D | group.h | | | 9 | --------- |
D | hash.c | | | 304 | ------------------------------------------------------------------------------- |
D | heredoc.c | | | 156 | ------------------------------------------------------------------------------- |
D | history/history.1 | | | 234 | ------------------------------------------------------------------------------- |
D | history/history.c | | | 341 | ------------------------------------------------------------------------------- |
D | input.c | | | 363 | ------------------------------------------------------------------------------- |
D | install-sh | | | 250 | ------------------------------------------------------------------------------- |
D | jbwrap.h | | | 9 | --------- |
D | lex.c | | | 395 | ------------------------------------------------------------------------------- |
D | list.c | | | 57 | --------------------------------------------------------- |
D | main.c | | | 121 | ------------------------------------------------------------------------------- |
D | match.c | | | 99 | ------------------------------------------------------------------------------- |
D | mksignal | | | 76 | ---------------------------------------------------------------------------- |
D | nalloc.c | | | 139 | ------------------------------------------------------------------------------- |
D | open.c | | | 25 | ------------------------- |
D | parse.y | | | 174 | ------------------------------------------------------------------------------- |
D | print.c | | | 482 | ------------------------------------------------------------------------------- |
D | proto.h | | | 40 | ---------------------------------------- |
D | rc.1 | | | 1881 | ------------------------------------------------------------------------------- |
D | rc.h | | | 406 | ------------------------------------------------------------------------------- |
D | redir.c | | | 77 | ----------------------------------------------------------------------------- |
D | rlimit.h | | | 42 | ------------------------------------------ |
D | signal.c | | | 80 | ------------------------------------------------------------------------------- |
D | status.c | | | 147 | ------------------------------------------------------------------------------- |
D | tree.c | | | 172 | ------------------------------------------------------------------------------- |
D | trip.rc | | | 0 | |
D | utils.c | | | 116 | ------------------------------------------------------------------------------- |
D | var.c | | | 225 | ------------------------------------------------------------------------------- |
D | version.c | | | 1 | - |
D | wait.c | | | 129 | ------------------------------------------------------------------------------- |
D | walk.c | | | 358 | ------------------------------------------------------------------------------- |
D | which.c | | | 121 | ------------------------------------------------------------------------------- |
D | y.tab.c | | | 1070 | ------------------------------------------------------------------------------- |
D | y.tab.h | | | 33 | --------------------------------- |
54 files changed, 25 insertions(+), 14139 deletions(-)
diff --git a/CHANGES b/CHANGES
@@ -1,278 +0,0 @@
-Changes since 1.2: (Too many to count!)
-
-A memory stomping bug was fixed (provoked by assigning a variable
-to its old value plus something else).
-
-Better signal handling; a real signal handler which manages a queue
-of pending signals was added.
-
-rc now ignores SIGQUIT and traps SIGINT even in non-interactive
-mode. Thus,
-
- rc ed.sh
-
-will not do mysterious things if the shell script "ed.sh" calls a
-command like "ed" and then you hit ^C.
-
-rc now opens 0, 1, 2 on /dev/null if they are inherited closed.
-rc -o prevents this.
-
-A couple of stupid O(n^2) string appends were replaced with O(n)
-loops. This should make foo=`{cat /etc/termcap} bar=$^foo a little
-faster :-)
-
-Returning a list of signals from a function is now legal, so "return
-$status" should always work.
-
-The code has been revised, new printing routines have been added.
-
-rc no longer uses redundant braces when exporting functions.
-
-A first stab at a verification suite has been added (trip.rc).
-(someone, please help me make this comprehensive!)
-
-rc -p now does not initialize functions from the environment. This
-should make it easier to write shell scripts that don't need to
-assume anything about the environment.
-
-Inherited ignored signals are now ignored in the current shell and
-passed on ignored to the child processes. whatis -s also reflects
-this information.
-
-A file descriptor leak in the /dev/fd implementation of >{} was
-fixed.
-
-A variable set to '' was not imported from the environment; this
-has been fixed.
-
-Changes since 1.3beta:
-
-New Makefile/config.h setup.
-
-builtin echo may now be conditionally included out, to use a Goldwynism.
-
-builtin exit takes any legal exit status. If the status is not all zeros,
-rc exits with 1. (having "exit sigiot" produce a core dump would be going
-a little far, I think.)
-
-limit does not append a unit after a zero limit; 0g was too confusing.
-
-exec > /nonexistentfile does not cause rc to exit any more.
-
-If a noninteractive rc is started with sigint ignored, rc does not install
-its own signal handler.
-
-error messages produced by rc in a subshell were cleaned up. (rc erroneously
-reset the 'interactive' flag after a fork)
-
-print.c was cleaned up a little; no functionality was changed, but should
-be more portable now.
-
-a bug in rc-1.3beta (not previous versions) was fixed: setting the first
-element of $path to '' caused PATH to be exported as '':etc..
-
-getopt's "illegal option" message was gratuitously changed to something
-less abrupt.
-
-some dead code was removed from input.c
-
-%term was changed to %token in parse.y; apparently newer yacc's don't grok
-%term any more.
-
-a race condition in the signal handler was fixed.
-
-the variable in for() was getting evaluated each time through the loop
-(e.g., for (`{echo i;date>[1=2]} in 1 2 3)echo $i would print the date
-three times). This was cleaned up.
-
-a redundant fork() was removed from walk.c; this showed up when running
-a braced command with a redirection in the background. e.g., {a;b}>c&
-
-man pages for history and rc were cleaned up by david (thanks).
-
-rc set SIGQUIT and SIGTERM to SIG_DFL on background jobs---even when
-trying to do old-style backgrounding (i.e., don't use process groups,
-just ignore SIGINT & SIGQUIT & SIGTERM).
-
-$0 is now changed to the name of the signal when entering a signal
-handler. Thus it's possible to write code like
-
- fn sigint sigterm sigquit {
- switch ($0) {
- case sigint
- ...
- case sigterm
- ...
-
-wait with no arguments now prints the pid of any and all children
-that died with a signal. e.g.,
-
- ; wait
- 25321: terminated
- 25325: terminated
-
-as opposed to
-
- ; wait
- terminated
-
-An error saving/restoring state in the input stream code would
-cause rc to exit with the (erroneous) command:
-
- eval '|[a'
-
-FIFO's were not removed in a backgrounded command, e.g.,
-
- cat <{echo hi}&
-
-Changes since rc-1.4beta:
-
-getopt was renamed to rc_getopt to avoid libc collisions.
-
-$cdpath with a / in it caused a cd to sometimes have two //'s at the
-front of the path. This is reserved by POSIX, so I changed it to skip
-one of the /'s.
-
-signal handling now emulates sh in the way I described in a previous
-message: the race condition present in older rc's whereby some SIGINTs
-got lost is now gone; any SIGINT received during a wait() is acted upon
-at the end of the wait(), unless of course SIGINT is being deliberately
-ignored.
-
-getopt was renamed to avoid naming conflicts with libc. Also a sound
-move since rc_getopt is no longer quite libc-getopt compatible; I had
-to add in a mechanism for resetting getopt.
-
-signal handler code in fn.c was cleaned up; there were several bugs
-in rc-1.4beta, notably the shell sometimes spawned background jobs
-with SIGTERM ignored. I took the opportunity to make things a little
-cleaner here.
-
-a quasi-memory leak in the code for while() was fixed: a long-running
-while that had rc commands allocating memory in it could cause the
-shell to grow without bounds. I fixed this by placing the while loop
-(*and* test!) inside a new allocation arena each time through the loop.
-
-A new configuration parameter, NOJOB, was added to allow you to force
-v7-style backgrounding (no setpgrp, ignore SIGINT and SIGTERM).
-
-The FIFO code was reworked a little. It should be more robust now---
-FIFOs get removed at the end of the command of the argument list
-that they were on:
-
- fn foo {echo $*; cat $*}
- foo<{echo hi}
-
-now works as expected. Also FIFO names are pushed onto the exception
-stack so that their removal occurs in the face of exceptions and so
-on.
-
-A memory leak in treefree() was plugged up --- the root node of a
-function was not getting freed.
-
-Changes since rc-1.4:
-
-General changes:
-
- Some small memory leaks/uninit references revealed by Purify.
-
- $bqstatus for querying the exit status of a backquote.
-
- Globbing through unreadable directories.
-
- More options to whatis.
-
- History append which always re-opens the file (avoids
- inconsistencies over multiple NFS-mounted accesses to
- $history).
-
- Support "rc -s".
-
----------
-
-Makefile: Added comment referring to README for yacc/malloc problem.
-
-uiltins.c: Added more options to whatis, protected rlimit prototypes
- with #ifndef SYSVR4, renamed SIGCHK to sigchk.
-
-except.c: Patched nl_on_intr printing to happen only in interactive
- shells.
-
-exec.c: Added comment explaining nl_on_intr variable, renamed SIGCHK
- to sigchk.
-
-fn.c: Replaced by-hand consing of exception stack etc. for signal
- handler execution with call to funcall(). Replaced fun2str
- call with call on print routines.
-
-footobar.c: Got rid of memory leak in get_name(), parenthesize count,
- flat and var nodes for correctness in unparsing, removed
- list2str, made get_name use nalloc space, merge in a
- better parse_var from es.
-
-glob.c: Split out a test so that closedir is called correctly, renamed
- SIGCHK to sigchk.
-
-glom.c: Added bqstatus, renamed SIGCHK to sigchk, removed spurious
- setsigdefaults, patched uninit memory reference, rename
- "clear" to "memzero", wait for bq subproc to finish on EINTR.
-
-hash.c: Added options to function/variable print code.
-
-history/history.c: Added '@' to the list of chars which can precede an
- ignored '-'.
-
-input.c: Got rid of tiny memory leak in closefds, got rid of uninit
- memory reference in popinput, moved nul ignored check into
- realgchar(), changed history append to always reopen the
- history file, replaced SIGCHK with sigchk. Freed memory
- returned by call to readline().
-
-lex.c: Corrected typo in comment, moved nul character ignore code
- to input routines.
-
-main.c: Added -s flag.
-
-nalloc.c: Added convenience feature to erealloc. (Allow NULL parameter)
-
-print.c: Changed use of va_start so broken compilers can compile
- print code.
-
-proto.h: Added fake memset.
-
-rc.h: Replaced clear() function prototype with a macro call on
- memset(), removed SIGCHK, fixed prototypes.
-
-signal.c: Removed unconditional exit in catcher code, renamed SIGCHK
- to sigchk.
-
-status.c: Rewrite sgetstatus breaking out strstatus so that bqstatus
- can be set from glom routines.
-
-utils.c: Got rid of clear() (use memset from C library), rename SIGCHK
- to sigchk.
-
-var.c: Got rid of memory leak in listassign(), converted list2str()
- call to something using the print routines.
-
-version.c: New version string.
-
-wait.c: Got rid of memory leak in rc_fork, renamed SIGCHK to sigchk.
-
-walk.c: Fixed pre-redirection bug, removed spurious setsigdefaults(),
- renamed SIGCHK to sigchk.
-
-
-Changes since rc-1.5beta1
-
- Configuration: rc now uses GNU autoconf.
-
- Portability: mksignal works on HPUX 10.
-
- Portability: resources can be (quad_t).
-
- Bug: if rc was started with SIGCLD == SIG_IGN (e.g. by Solaris's
- rshd) it would loop. Fixed by resetting SIGCLD to SIG_DFL if it
- was SIG_IGN when rc was started.
-
- Portability: POSIXish systems don't have NGROUPS.
diff --git a/COPYRIGHT b/COPYRIGHT
@@ -1,26 +0,0 @@
-/*
- * Copyright 1991 Byron Rakitzis. All rights reserved.
- *
- * This software is not subject to any license of the American Telephone
- * and Telegraph Company or of the Regents of the University of California.
- *
- * Permission is granted to anyone to use this software for any purpose on
- * any computer system, and to alter it and redistribute it freely, subject
- * to the following restrictions:
- *
- * 1. The author is not responsible for the consequences of use of this
- * software, no matter how awful, even if they arise from flaws in it.
- *
- * 2. The origin of this software must not be misrepresented, either by
- * explicit claim or by omission. Since few users ever read sources,
- * credits must appear in the documentation.
- *
- * 3. Altered versions must be plainly marked as such, and must not be
- * misrepresented as being the original software. Since few users
- * ever read sources, credits must appear in the documentation.
- *
- * 4. This notice may not be removed or altered.
- *
- * [this copyright notice is adapted from Henry Spencer's
- * "awf" copyright notice.]
- */
diff --git a/EXAMPLES b/EXAMPLES
@@ -1,749 +0,0 @@
-There is no repository for useful rc code snippets as yet, so I'm including
-a (short) file in the distribution with some helpful/intriguing pieces of
-rc code.
-
-A sample .rcrc
---------------
-Here is the .rcrc I use on archone:
-
-umask 022
-path=(/bin /usr/bin /usr/ucb)
-ht=`/usr/arch/bin/hosttype
-h=$home
-history=$h/.history
-bin=$h/bin/$ht
-lib=$h/lib/$ht
-sh=$h/bin/sh
-include=$h/lib/include
-
-switch ($ht) {
-case sun*
- OBERON='. '$h/other/oberon
- p=/usr/ucb
- compiler='gcc -Wall -O -g'
- MANPATH=$h/man:/usr/arch/man:/usr/man
- if (! ~ $TERM ()) {
- stty dec
- /usr/arch/bin/msgs -q
- }
-case next
- p=(/usr/ucb /usr/bin /NextApps)
- compiler='cc -Wall -O -g -DNODIRENT'
- MANPATH=$h/man:/usr/arch/man:/usr/man
- if (! ~ $TERM ())
- stty dec
-case sgi
- p=(/usr/ucb /usr/sbin /usr/bin)
- compiler='gcc -Wall -O -g -DNOSIGCLD'
- MANPATH=$h/man:/usr/arch/man:/usr/catman
- if (!{~ $TERM () || ~ $TERM *iris*})
- stty line 1 intr '' erase '' kill ''
-case *
- echo .rcrc not configured for this machine
-}
-
-path=(. $sh $bin /usr/arch/bin $p /bin /usr/bin/X11 /etc /usr/etc)
-cdpath=(. .. $h $h/src $h/misc $h/other $h/adm)
-RNINIT=-d$h' -t -M -2400-h -2400+hfrom'; DOTDIR=$h/misc/news
-PRINTER=lw
-
-fn s {
- echo $status
-}
-fn cd {
- builtin cd $1 && \
- switch ($1) {
- case ()
- dir=$home
- case *
- dir=()
- }
-}
-fn pwd {
- if (~ $dir ())
- dir=`/bin/pwd
- echo $dir
-}
-fn x {
- if (~ `tty /dev/console)
- clear_colormap
- clear
- exit
-}
-fn p {
- if (~ $history ()) {
- echo '$history not set' >[1=2]
- return 1
- }
-
- if (! ~ $#* 0 1 2) {
- echo usage: $0 '[egrep pattern] [sed command]' >[1=2]
- return 1
- }
-
- command=`{
- egrep -v '^[ ]*p([ ]+|$)' $history | switch ($#*) {
- case 0
- cat
- case 1
- egrep $1
- case 2
- egrep $1 | sed $2
- } | tail -1
- }
-
- echo $command
- eval $command
-}
-
-if (~ $TERM dialup network) {
- TERM=vt100
- biff y
-}
-
-A front-end to NeXT's "openfile"
---------------------------------
-
-Named after the sam "B" command for opening a file, this script was written
-by Paul Haahr. (Assumes the "pick" command from Kernighan and Pike is also
-in your path.)
-
-#!/bin/rc
-if (~ $#* 0)
- exec openfile
-create = ()
-files = ()
-for (i in $*)
- if (test -f $i) {
- files = ($files $i)
- } else {
- create = ($create $i)
- }
-create = `{ pick $create }
-files = ($files $create)
-for (i in $create)
- > $i
-if (! ~ $#files 0)
- openfile $files
-
-A read function
----------------
-
-Unlike sh, rc doesn't have a read. This clever alternative returns an
-exit status as well as fetch a variable. Use as
-
- read foo
-
-to set $foo to a single line from the terminal.
-
-(due to John Mackin <john@syd.dit.csiro.au>)
-
-fn read {
- x=() {
- x = `` ($nl) { awk '{print; print 0; exit}' ^ $nl ^ \
- 'END {print 1; print 1}' }
- $1 = $x(1)
- return $x(2)
- }
-}
-
-From cs.wisc.edu!dws Fri Aug 2 18:16:14 1991
-
-#-------
-# ls front end
-#-------
-fn ls \
-{
- test -t 1 && * = (-FCb $*)
- builtin ls $*
-}
-#-------
-# nl - holds a newline, useful in certain command substitutions
-#-------
-nl='
-'
-#-------
-# show - tell me about a name
-#
-# Runs possibly dangerous things through cat -v in order to protect
-# me from the effects of control characters I might have in the
-# environment.
-#-------
-fn show \
-{
- * = `` $nl {whatis -- $*}
- for(itis)
- {
- switch($^itis)
- {
- case 'fn '* ; echo $itis | cat -v -t
- case builtin* ; echo $itis
- case /* ; file $itis; ls -ld $itis
- case *'='* ; echo $itis | cat -v -t
- case * ; echo $itis: UNKNOWN: update show
- }
- }
- itis = ()
-}
-#-------
-# Tell me automatically when a command has a nonzero status.
-#-------
-fn prompt \
-{
- Status = $status
- ~ $Status 0 || echo '[status '$Status']'
-}
-
-#-------
-# chop - echo the given list, less its final member
-#
-# e.g. chop (a b c) -> (a b)
-#-------
-fn chop {
- ~ $#* 0 1 && return 0
- ans = '' { # local variable
- ans = ()
- while(! ~ $#* 1)
- {
- ans = ($ans $1)
- shift
- }
- echo $ans
- }
-}
-
-From arnold@audiofax.com Thu May 30 08:49:51 1991
-
-# cd.rc --- souped up version of cd
-
-# this is designed to emulate the fancy version of cd in ksh,
-# so if you're a purist, feel free to gag
-
-_cwd=$home
-_oldcwd=$home
-
-fn cd {
- if (~ $#* 0) {
- if (~ $_cwd $home) { # do nothing
- } else {
- builtin cd && { _oldcwd=$_cwd ; _cwd=$home }
- }
- } else if (~ $#* 1) {
- if (~ $1 -) {
- _t=$_cwd
- builtin cd $_oldcwd && {
- _cwd=$_oldcwd
- _oldcwd=$_t
- echo $_cwd
- }
- _t=()
- } else {
- # if a cd happens through the cdpath, rc echos
- # the directory on its own. all we have to do
- # is track where we end up
- _dopwd = 1
- { ~ $1 /* } && _dopwd = 0 # absolute path
- builtin cd $1 && {
- _oldcwd=$_cwd
- _cwd=$1
- { ~ $_dopwd 1 } && _cwd=`/bin/pwd
- }
- _dopwd=()
- }
- } else if (~ $#* 2) {
- _t=`{ echo $_cwd | sed 's<'$1'<'$2'<' }
- builtin cd $_t && {
- _oldcwd=$_cwd
- _cwd=$_t
- echo $_cwd
- }
- _t=()
- } else {
- echo cd: takes 0, 1, or 2 arguments >[1=2]
- builtin cd $1 && { _oldcwd=$_cwd ; _cwd=`/bin/pwd ; echo $_cwd }
- }
-}
-
-fn pwd { echo $_cwd }
-
-From vlsi.cs.caltech.edu!drazen Tue Jan 21 16:03:14 1992
-
-# A kill builtin.
-
-#ifdef B_KILL
-#include <ctype.h>
-static void b_kill(char **av)
-{
- int signal = SIGTERM;
- int n = 1;
- pid_t pid;
- boolean res;
-
- if (!av[1]) {
- set(TRUE);
- return;
- }
-#undef STRCMP
-#define STRCMP strcmp
- if ( '-' == av[1][0]) {
- char *p = 1+av[1];
- if (0 == strcmp(av[1], "-l")){
- int r; const int nsig = NUMOFSIGNALS;
- const int C = 4, R = 1 + (int)((nsig-2)/C);
- for (r=1; r<=R; r++){
- int j;
- for (j=r; j<nsig; j+=R){
- fprint(1, "%s%d. %s\t", j<10?" ":"", j, signals[j][0]);
- }
- fprint(1,"\n");
- }
- set(TRUE);
- return;
- }
- n++;
- if ( (signal=a2u(p)) < 0){
- int i;
- for (i = 1; i < NUMOFSIGNALS; i++){
- char UPPER[31], *u=UPPER, *q;
- for (q=signals[i][0]; *q; q++, u++) *u = toupper(*q);
- *u = '\0';
-
- if (*signals[i][0] &&
- (!STRCMP(signals[i][0], p) || !STRCMP(3+signals[i][0],p)
- || !STRCMP(UPPER, p) || !STRCMP(3+UPPER, p) ) )
- {
- signal = i;
- break;
- }
- }
- if (signal < 0){
- fprint(2,"kill: bad signal %s\n", av[1]);
- set(FALSE);
- return;
- }
- }
- }
-#undef STRCMP
-
- for (res=TRUE; av[n]; n++){
- if( (pid = (pid_t) a2u(av[n])) < 0){
- fprint(2, "kill: bad process number %s\n", av[n]);
- res = FALSE;
- continue;
- }
- if (kill(pid,signal)){
- uerror("kill");
- res = FALSE;
- continue;
- }
- }
- set(res);
-}
-#endif
-From acc.stolaf.edu!quanstro Thu Apr 2 02:51:10 1992
-Received: from thor.acc.stolaf.edu ([130.71.192.1]) by archone.tamu.edu with SMTP id <45339>; Thu, 2 Apr 1992 02:50:56 -0600
-Received: by thor.acc.stolaf.edu; Thu, 2 Apr 92 02:49:31 -0600
-Date: Thu, 2 Apr 1992 02:49:31 -0600
-From: quanstro@acc.stolaf.edu
-Message-Id: <9204020849.AA26566@thor.acc.stolaf.edu>
-To: byron@archone.tamu.edu
-Subject: EXAMPLES in 1.4beta
-Status: RO
-
-
-I have a little bit of code which might be a little more general than
-the souped-up version that is already there. Here it is, if you are
-interested.
-
-# directory functions ###################################################
-fn pwd { echo $PWD; }
-
-fn pushd {
- dirs = ($PWD $dirs);
- builtin cd $*;
- PWD = `{builtin pwd};
-}
-
-fn popd {
- switch ($#*)
- {
- case 0
- ;
- case 1
- echo 'popd: argument '^$1^' ignored.' >[1=2];
- case *
- echo 'popd: usage: popd [n].';
- }
-
- if (! ~ $dirs ())
- {
- builtin cd $dirs(1);
- PWD = $dirs(1);
- echo $PWD;
- * = $dirs;
- shift
- dirs = $*;
- }
-}
-
-fn cd {
- ~ $* () && * = $home;
- !~ $#* 1 && echo 'cd: too many arguments' >[1=2] && return 1;
-
- if (test -r $* ) {
- pushd $*;
- } else {
- echo cd: $* does not exist. >[1=2]
- return 1;
- }
-}
-
-fn back { popd $*; }
-
-fn Back {
- cd $home;
- PWD = $home;
- dirs = ();
-}
-
-fn dirs {
- echo $dirs;
-}
-
-PWD = `{builtin pwd} ; dirs = $PWD # kickstart
-
-
-
-
-
-From acc.stolaf.edu!quanstro Thu Apr 2 02:53:40 1992
-Received: from thor.acc.stolaf.edu ([130.71.192.1]) by archone.tamu.edu with SMTP id <45339>; Thu, 2 Apr 1992 02:53:38 -0600
-Received: by thor.acc.stolaf.edu; Thu, 2 Apr 92 02:51:46 -0600
-Date: Thu, 2 Apr 1992 02:51:46 -0600
-From: quanstro@acc.stolaf.edu
-Message-Id: <9204020851.AA26573@thor.acc.stolaf.edu>
-To: byron@archone.tamu.edu
-Subject: EXAMPLES
-Status: RO
-
-
-Little yp hack which act's like ~ w/o syntatic sugar (for those who do
-not have the luxury of seting up symbolic links to all user's homes
-
-# user function #########################################################
-fn u user {
- info = ()
- info = `` (':') {ypmatch $1 passwd >[2] /dev/null }
-
- if (~ $info ()) {
- echo user $1 unknown >[1=2];
- return 1;
- } else {
- echo $info(6)
- if (~ $0 user)
- cd $info(6)
- }
-}
-
-
-From stolaf.edu!quanstro Sun Apr 5 04:53:34 1992
-Date: Sun, 5 Apr 1992 04:53:08 -0500
-From: quanstro@stolaf.edu (Erik Quanstrom)
-To: byron@archone.tamu.edu
-Subject: man written in rc
-Status: RO
-
-I whipped this up because the NeXTs here insist on using MANPAGER
-instead of PAGER and otherwise being obnoxious . . .
-
-Anyway ... I hope you approve
-
-#!/bin/rc
-#########################################################################
-# file: man #
-# #
-# object: display man pages #
-# #
-# bugs: * slow #
-# * does not know about fmt files #
-# #
-# Erik Quanstrom #
-# 11. Februar 1992 #
-#########################################################################
-PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:$PATH ;
-TROFF = (nroff -hq -Tcrt);
-macros=an;
-sections=(cat1 cat2 cat3 cat4 cat5 cat6 cat7 cat8 catl man1 man2 man3 man4 \
- man5 man6 man7 man8 manl)
-$nl='
-'
-fn sigint sighup sigquit sigalrm sigterm { rm -f $Bat; exit 2;}
-
-fn usage {
- echo usage: $0 [-] [-t] [-M path] [-T macros] [[section] title] ...>[1=2];
- exit 1;
-}
-
-n=();
-fn shiftn {
- n=($n 1)
-}
-
-~ $PAGER () && test -t 1 && PAGER=more; #default pager
-
-while (~ $1 -*)
- {
- switch ($1)
- {
- case -
- if (~ $PAGER troff)
- echo bad combination of flags >[1=2] && usage;
- PAGER=cat;
- case -t
- ~ TROFF () && TROFF = (troff -t);
- ~ TCAT () && PAGER=(lpr -t);
- case -M
- shift;
- ~ $1 () && usage;
-
- MANPATH=$1;
- case -T
- shift;
- ~ $1 () && usage;
- macros=$1;
- case -k
- fflag=(); kflag=1;
- shift;
- break;
- case -f
- # locate related too filenames
- kflag=(); fflag=1;
- shift;
- break;
- case -*
- echo bad flag '`'^$1^'''' >[1=2];
- usage;
- }
- shift;
- }
-
-if (!~ $#* 1) {
- ~ $1 [l1-8] && { sname=$1 ; sections=(cat man)^$1 ; shift }
- #hack for sun-style man pages
- ~ $1 [l1-8]? && { sname=$1 ; sections=(cat man)^`{echo $1| cut -c1} ; shift }
-}
-
-if (~ 1 $fflag $kflag) {
- dirlist=();
- for (d in ``(:$nl) {echo $MANPATH})
- test -s $d^/whatis && dirlist=($dirlist $d^/whatis);
-
- ~ $1 () && usage;
-
- if (~ $fflag 1) {
- while (!~ $1 ()) {
- cmd=`{echo $1 | sed 's/^.*\///g'}
- egrep -h '^'^$cmd' ' $dirlist;
- shift;
- }
- } else {
- while (!~ $1 ()) {
- grep -h $1 $dirlist;
- shift;
- }
- }
- exit 0;
-}
-
-s=0;
-while (!~ $1 ()) {
- for (dir in ``(:$nl) {echo $MANPATH}) {
- filelist=($filelist `{echo $dir/^$sections^/$1^.* |\
- tr ' ' '\12' | grep -v '*'})
-
- # coment this out if you don't care about speed, but
- # would rather find all the pages.
- ~ $filelist () || break;
- }
-
- if (~ $filelist ()) {
- if (~ $#sections 2) {
- echo no entry for $1 in section '`'$sname'''' of the manual >[1=2];
- } else {
- echo no entry for '`'$1'''' found. >[1=2];
- }
- s=1;
- } else {
-
- echo $filelist '(' $#filelist ')' >[1=2];
-
- for (file in $filelist) {
- if (~ $file */cat[1-8l]/*) {
- Cat = ($Cat $file);
- } else {
- # search for dups
- dont=()
- for (x in $Cat) {
- if (~ `{echo $x | sed 's/\/[mc]a[nt][1-8l]//'} \
- `{echo $file | sed 's/\/[mc]a[nt][1-8l]//'}) {
- dont=1;
- break;
- }
- }
-
- if (~ $dont ()) {
- cd `{echo $file | sed 's/man[1-8].*//'}
- echo -n Formatting ...
- $TROFF -m^$macros $file > /tmp/man^$pid^$#n && \
- Bat = ($Bat /tmp/man^$pid^$#n)
-
- shiftn;
- echo ' 'done.
- }
- }
- }
- }
- shift;
-}
-
-{ !~ () $Cat || !~ () $Bat } && $PAGER $Cat $Bat;
-
-rm -f $Bat;
-~ $s () || exit $s;
-
-exit 0;
-
-
-
-From osf.org!rsalz Thu Apr 23 16:22:32 1992
-Date: Thu, 23 Apr 1992 16:22:07 -0500
-From: rsalz@osf.org
-To: byron@archone.tamu.edu
-Subject: One for your EXAMPLES file
-Status: RO
-
-Use
- trimhist [-#lines]
-trims your history file back; useful for folks with dis quota's :-)
-fn trimhist { p1=-100 {
- cp $history $history^'~'
- ~ $#* 1 && p1=$1
- tail $p1 <$history^'~' >$history
- rm $history^'~'
-} }
-
-From Pa.dec.com!uucp Mon Apr 27 12:25:02 1992
-Date: Mon, 27 Apr 1992 12:15:18 -0500
-From: haahr@adobe.com
-To: Byron Rakitzis <byron@archone.tamu.edu>
-Subject: a neat little rc script
-
-what you have to know to understand this:
- $md for me is usually obj.$machine
- my mkfiles build *.o, *.a, and the a.outs in $md
- this is my acc script, which i use for compiling adobe routines
----
-#! /user/haahr/bin/next/rc
-
-cc = cc
-proto = '-DPROTOTYPES=1'
-
-switch ($md) {
-case noproto.$machine; proto = '-DPROTOTYPES=0'
-case gprof.$machine; cc = ($cc -pg)
-case prof.$machine; cc = ($cc -p)
-case lcomp.$machine; cc = lcomp
-}
-exec $cc $proto '-DPACKAGE_SPECS="package.h"' '-DISP=isp_mc68020' '-DOS=os_mach' $*
-
-From rc-owner Tue May 12 14:54:10 1992
-Received: from postman.osf.org ([130.105.1.152]) by archone.tamu.edu with SMTP id <45337>; Tue, 12 May 1992 14:38:16 -0500
-Received: from earth.osf.org by postman.osf.org (5.64+/OSF 1.0)
- id AA14480; Tue, 12 May 92 13:25:03 -0400
-Received: by earth.osf.org (5.64/4.7) id AA03499; Tue, 12 May 92 13:25:02 -0400
-Date: Tue, 12 May 1992 12:25:02 -0500
-From: rsalz@osf.org
-Message-Id: <9205121725.AA03499@earth.osf.org>
-To: rc@archone.tamu.edu
-Subject: Useful function
-Status: R
-
-It looks like line noise, but it turns things like
- /home/rsalz/foo/bar
-into
- ~/foo/bar
-
-Useful for when you put your current directory up in your icon title.
-By duplicating the $home section you can make things like
- /project/dce/build/dce1.0.1/src/rpc
-become
- $MYBT/src/rpc
-
-## If a pathname starts with $home, turn $home into ~. Uses all built-ins.
-fn tildepath { p1=() i=() {
- p1=$1
- switch ($p1) {
- case $home $home/*
- # Split arg into components
- *=`` (/) { echo -n $p1 }
- # Shift down by number of components in $home
- for (i in `` (/) { echo -n $home } ) shift
- # Glue back together
- p1='~'
- for (i) p1=$p1 ^ '/' ^ $i
- echo $p1
- case *
- echo $p1
- }
- return 0
-} }
-
-From osf.org!rsalz Tue May 12 15:47:12 1992
-Received: from postman.osf.org ([130.105.1.152]) by archone.tamu.edu with SMTP id <45316>; Tue, 12 May 1992 15:47:06 -0500
-Received: from earth.osf.org by postman.osf.org (5.64+/OSF 1.0)
- id AA21070; Tue, 12 May 92 16:46:58 -0400
-Received: by earth.osf.org (5.64/4.7) id AA09396; Tue, 12 May 92 16:46:56 -0400
-Date: Tue, 12 May 1992 15:46:56 -0500
-From: rsalz@osf.org
-Message-Id: <9205122046.AA09396@earth.osf.org>
-To: byron@archone.tamu.edu
-Subject: Re: Useful function
-Status: R
-
->wow. thanks, i'll add it to EXAMPLES.
-Glad you like. Getting something added to EXAMPLES has been a goal of mine...
-
-I've been thinking, a bit, about a more general way of doing it. I want
-a "prefix-sub" function, like this
- prefix $some_path var1 var2 var3 var4 var5
-That would take some_path and replace any leading $var1 (etc) values
-with the variable name. Return on the first match.
-
-Hmm -- come to think of it, that's very easy to do:
-
-# Use pathprefix filename var1 var2 var3
-# returns filename, with leading prefixes (in $var1...) turned into the
-# string $var1...
-fn pathprefix { p1=() i=() j=() {
- p1=$1 ; shift
- for (i) {
- ~ $p1 $$i $$i^/* && {
- *=`` (/) { echo -n $p1 }
- for (j in `` (/) { echo -n $$i } ) shift
- p1='$'^$i
- for (j) p1=$p1 ^ '/' ^ $j
- echo $p1
- return 0
- }
- }
- echo $p1
- return 0
-} }
-
-home=/user/users/rsalz
-z=/usr/users
-pathprefix /usr/users/rsalz home usr # --> $home
-pathprefix /usr/users/rsalz z # --> $z/rsalz
-pathprefix /usr/users/rsalz/foo z home # --> $z/rsalz/foo
-pathprefix /usr/users/rsalz/foo home # --> $home/foo
-
diff --git a/Makefile.in b/Makefile.in
@@ -1,80 +0,0 @@
-# Makefile.in for rc.
-
-SHELL=/bin/sh
-
-bindir=@bindir@
-exec_prefix=@exec_prefix@
-mandir=@mandir@
-prefix=@prefix@
-
-CC=@CC@
-CFLAGS=@CFLAGS@
-LDFLAGS=@CFLAGS@
-LIBS=@LIBS@
-
-INSTALL=@INSTALL@
-INSTALL_DATA=@INSTALL_DATA@
-INSTALL_PROGRAM=@INSTALL_PROGRAM@
-LN=@LN@
-YACC=@YACC@
-
-HISTORY=@HISTORY@
-
-OBJS=@ADDON@ builtins.o except.o exec.o @EXECVE@ fn.o footobar.o getopt.o \
- glob.o glom.o hash.o heredoc.o input.o lex.o list.o main.o match.o \
- nalloc.o open.o print.o redir.o sigmsgs.o signal.o status.o tree.o \
- utils.o var.o version.o wait.o walk.o which.o y.tab.o
-
-all: rc $(HISTORY)
-
-rc: $(OBJS)
- $(CC) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)
-
-sigmsgs.c: mksignal
- sh mksignal @SIGNAL_H@
-
-y.tab.c: parse.y
- $(YACC) -d parse.y
-
-trip: rc
- ./rc -p < trip.rc
-
-clean: force
- rm -f rc $(HISTORY) - *.o *.tab.* sigmsgs.* config.cache config.log
-
-cleaner: clean
- rm -f config.status config.h Makefile
-
-cleanest: cleaner
- rm -f configure
-
-history: force
- cd history; make CC="$(CC)" $(HISTORYMAKEFLAGS)
-
-install: all
- $(INSTALL_PROGRAM) rc $(bindir)
- $(INSTALL_DATA) rc.1 $(mandir)/man1/rc.1
- case "x$(HISTORY)" in \
- x) \
- ;; \
- *) \
- $(LN) $(HISTORY) - ;\
- $(INSTALL_PROGRAM) - $(bindir) ;\
- $(LN) $(bindir)/- $(bindir)/-- ;\
- $(LN) $(bindir)/- $(bindir)/-p ;\
- $(LN) $(bindir)/- $(bindir)/--p ;\
- $(INSTALL_DATA) history/history.1 $(mandir)/man1/history.1 \
- ;; \
- esac
-
-force:
-
-# dependencies:
-
-$(OBJS): config.h proto.h rc.h
-sigmsgs.h: sigmsgs.c
-lex.o y.tab.o: y.tab.c
-
-builtins.o except.o exec.o input.o signal.o utils.o wait.o walk.o: jbwrap.h
-builtins.o: rlimit.h
-builtins.o fn.o hash.o signal.o status.o: sigmsgs.h
diff --git a/README b/README
@@ -1,197 +0,0 @@
-This is release 1.5b2 of rc.
-
-Read COPYRIGHT for copying information. All files are
-
- Copyright 1991, 1997 Byron Rakitzis.
-
-COMPILING
-
-rc was written in portable ANSI C. If you don't have an ANSI compiler
-like gcc or something close (e.g., sgi's cc) read further down on
-how to convert rc's source to old C.
-
-The following commands are all you need to configure, build,
-test, and install rc.
-
- $ sh configure
- $ make
- $ make trip
- # make install
-
-There are lots of options you can give to configure to modify rc's
-behaviour. You can also select a command line history library to link
-against. For a summary of all options, run `sh configure --help'.
-
-You can specify Makefile variables by setting the corresponding
-environment variables. For example, you might want to set `CC=cc', to
-prevent configure looking for gcc, or set an initial value for `LIBS',
-as in the example below.
-
-Here are the configure options you may want to use, in approximately
-descending order of usefulness.
-
- --with-editline
-
- This option tells rc to use Simmule Turner's and Rich $alz's editline
- package, which you can get from the following location. This is
- essentially a lightweight version of GNU readline, providing EMACS
- style command line editing and history.
-
- ftp://ftp.pipex.net/people/tim/editline.tar.gz
-
- If the editline library is not installed in a standard place, you
- can tell configure where to find it by setting the environment
- variable LIBS. For example, the maintainer builds rc by copying
- libedit.a into the rc directory and then running this configure
- command.
-
- LIBS=-L. sh configure --with-editline
-
- --with-readline
-
- This option tells rc to use the GNU readline package, which is similar
- to editline, but has many more features. The readline package is over
- 6 times the size of editline (whether you count lines of code, or the
- library itself). You probably need to tell the compiler to link with
- the termcap library if you're using readline. For example, here is
- the configure command the maintainer uses to build rc with readline.
-
- LIBS=-ltermcap sh configure --with-readline
-
- --enable-history
-
- Use this option if you want to build and install the programs that
- support a crude history mechanism.
-
-You can't use `--with-editline' and `--with-readline' together, of course,
-and if you have either of those you probably don't want to bother with
-`--enable-history'.
-
- --prefix=/path
-
- By default, `prefix' is /usr/local, which means that `make install'
- installs rc (and possibly the history programs) in /usr/local/bin, and
- man pages in /usr/local/man/man1. Use this option to change where
- `make install' puts things.
-
- --disable-builtin-echo
-
- By default, the `echo' command is builtin to rc for efficiency reasons.
- It is the only builtin which is not essential, and purists may wish
- to omit it.
-
- --disable-def-interp
- --enable-def-interp=/bin/foo
-
- By default, a program that fails with "Exec format error" is handed to
- /bin/sh. This does the Right Thing for scripts that start with `:' to
- indicate that they are sh scripts. You can disable this behaviour
- entirely, or specify a different default interpreter.
-
- --disable-def-path
- --enable-def-path="/usr/local/bin","/usr/bin"
-
- By default, if rc is started with no PATH, it uses a default path.
- The default path is constructed at configure time, and consists
- of each of the following directories that exist, in order.
-
- /usr/local/bin /usr/bin /usr/ucb /bin .
-
- You can disable this, or specify a different default path. Note
- that the quote marks (") must be seen by configure; you will
- probably need to quote them to your shell. (Not if it's already
- rc, but then you will need to quote the `='.)
-
- --disable-job
-
- By default, rc puts backgrounded processes into a new process group,
- as though it were a job control shell (it isn't). This is usually
- needed to work around bugs in application programs which install
- signal handlers for the keyboard signals without checking whether the
- signal was being ignored. This option disables the default behaviour,
- making rc behave like a traditional sh. You are unlikely to want this
- option on any Unix system.
-
- --disable-protect-env
-
- By default, rc encodes special characters in environment variables.
- This is necessary on all known Unix systems to prevent sh either
- dying or discarding the variables. This option disables the default
- behaviour. You are unlikely to want this option on any Unix system.
-
-After you've built rc, you may wish to run it through a test script
-to see that everything is ok. Type `make trip' for this. This will
-produce some output, and end with "trip is complete". If the trip ends
-with "trip took a wrong turn..." please contact the maintainer. (If
-you've built in either of the command line history libraries, the trip
-will fail near the end with `trip took a wrong turn: dot -i'.)
-
-BUGS
-
-Send bug reports to <tim@uk.uu.net> (<tgoodwin@cygnus.co.uk> after
-1997-07-27). If a core dump is generated, sending a backtrace will
-help a great deal. You can get a backtrace like this.
-
- ; gdb rc core
- (gdb) where
- <<<BACKTRACE INFO>>>
- (gdb)
-
-Also, always report the machine, OS (`uname -a'), and compiler used to
-make rc; this information is extremely valuable.
-
-FEEPING CREATURISM
-
-See the end of the man page, under "INCOMPATABILITIES" for (known?)
-differences from the "real" rc. Most of these changes were necessary
-to get rc to work in a reasonable fashion on a real (i.e. commercial,
-non-Labs) Unix system; a few were changes motivated by concern about
-some inadequacies in the original design.
-
-YACC
-
-The yacc that Sun ships with SunOS 4.1.1 calls malloc() to allocate
-space for the state stack, and requires a call to YYACCEPT or YYABORT to
-free this memory. This means that if rc takes an interrupt while parsing
-a command (say, if ^C is typed), yacc will leak away this memory. The
-solution is to use a yacc which statically allocates this array, such
-as the yacc in the BSD distribution. Berkeley yacc-generated y.tab.c
-and y.tab.h are shipped with rc in case you cannot get hold of Berkeley
-yacc.
-
-OLD C
-
-If you need to convert rc's source into K&R C, you need to run the
-source through a filter called "unproto", posted in comp.sources.misc.
-A sample "cpp" shell script that I used to run unproto under SunOS is
-supplied with rc.
-
-CREDITS
-
-This shell was written by me, Byron Rakitzis, but kudos go to Paul Haahr
-for letting me know what a shell should do and for contributing certain
-bits and pieces to rc (notably the limits code, print.c, most of which.c
-and the backquote redirection code), and to Hugh Redelmeier for running
-rc through his fussy ANSI compiler and thereby provoking interesting
-discussions about portability, and also for providing many valuable
-suggestions for improving rc's code in general. Finally, many thanks
-go to David Sanderson, for reworking the man page to format well with
-troff, and for providing many suggestions both for rc and its man page.
-
-Thanks to Boyd Roberts for the original history.c, and to Hugh again for
-re-working parts of that code.
-
-Of course, without Tom Duff's design of the original rc, I could not
-have written this shell (though I probably would have written *a*
-shell). Almost of all of the features, with minor exceptions, have been
-implemented as described in the Unix v10 manuals. Hats off to td for
-designing a C-like, minimal but very useful shell.
-
-Tom Duff has kindly given permission for the paper he wrote for UKUUG to
-be distributed with this version of rc (called "plan9.ps" in the same
-ftp directory as the shell). Please read this paper bearing in mind that
-it describes a program that was written at AT&T and that the version of
-rc presented here differs in some respects.
-
-The current maintainer of rc is Tim Goodwin, <tim@uk.uu.net>
-(<tgoodwin@cygnus.co.uk> after 1997-07-27).
diff --git a/addon.c b/addon.c
@@ -1,22 +0,0 @@
-/*
- This file contains the implementations of any locally defined
- builtins.
-*/
-
-#ifdef DWS
-
-/*
- This is what DaviD Sanderson (dws@cs.wisc.edu) uses.
-*/
-
-#include <sys/types.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-
-#include "rc.h" /* for bool TRUE, FALSE */
-#include "addon.h"
-
-#include "addon/access.c"
-#include "addon/test.c"
-
-#endif
diff --git a/addon.h b/addon.h
@@ -1,38 +0,0 @@
-/*
- This file is the interface to the rest of rc for any locally
- defined addon builtins. By default there are none.
- The interface consists of the following macro.
-
- ADDONS A comma-separated list of pairs of function pointers
- and string literals.
-
- The addon functions must also have proper prototypes in this file.
- The builtins all have the form:
-
- void b_NAME(char **av);
-
- Builtins report their exit status using set(TRUE) or set(FALSE).
-
- Example:
-
- #define ADDONS { b_test, "test" },
- extern void b_test(char **av);
-*/
-
-#define ADDONS /* no addons by default */
-
-#ifdef DWS
-
-/*
- This is what DaviD Sanderson (dws@cs.wisc.edu) uses.
-*/
-
-#undef ADDONS
-#define ADDONS { b_access, "access" },\
- { b_test, "test" },\
- { b_test, "[" },
-
-extern void b_access(char **av);
-extern void b_test(char **av);
-
-#endif
diff --git a/builtins.c b/builtins.c
@@ -7,16 +7,17 @@
because of a bad umask.
*/
-#include "rc.h"
-
#include <sys/ioctl.h>
#include <setjmp.h>
#include <errno.h>
-
+#include "rc.h"
#include "jbwrap.h"
#include "sigmsgs.h"
+#ifndef NOLIMITS
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif
#include "addon.h"
-#include "rlimit.h"
extern int umask(int);
@@ -24,11 +25,10 @@ static void b_break(char **), b_cd(char **), b_eval(char **), b_exit(char **),
b_newpgrp(char **), b_return(char **), b_shift(char **), b_umask(char **),
b_wait(char **), b_whatis(char **);
-#if HAVE_SETRLIMIT
+#ifndef NOLIMITS
static void b_limit(char **);
#endif
-
-#if RC_ECHO
+#ifndef NOECHO
static void b_echo(char **);
#endif
@@ -39,13 +39,13 @@ static struct {
{ b_break, "break" },
{ b_builtin, "builtin" },
{ b_cd, "cd" },
-#if RC_ECHO
+#ifndef NOECHO
{ b_echo, "echo" },
#endif
{ b_eval, "eval" },
{ b_exec, "exec" },
{ b_exit, "exit" },
-#if HAVE_SETRLIMIT
+#ifndef NOLIMITS
{ b_limit, "limit" },
#endif
{ b_newpgrp, "newpgrp" },
@@ -100,7 +100,7 @@ static void badnum(char *num) {
extern void b_exec(char **av) {
}
-#if RC_ECHO
+#ifndef NOECHO
/* echo -n omits a newline. echo -- -n echos '-n' */
static void b_echo(char **av) {
@@ -121,7 +121,7 @@ static void b_echo(char **av) {
static void b_cd(char **av) {
List *s, nil;
char *path = NULL;
- size_t t, pathlen = 0;
+ SIZE_T t, pathlen = 0;
if (*++av == NULL) {
s = varlookup("home");
*av = (s == NULL) ? "/" : s->w;
@@ -250,8 +250,7 @@ extern void b_builtin(char **av) {
/* wait for a given process, or all outstanding processes */
static void b_wait(char **av) {
- int stat;
- pid_t pid;
+ int stat, pid;
if (av[1] == NULL) {
waitforall();
return;
@@ -415,13 +414,15 @@ static void b_newpgrp(char **av) {
arg_count("newpgrp");
return;
}
- setpgid(rc_pid, rc_pid); /* XXX check return value */
- tcsetpgrp(2, rc_pid); /* XXX check return value */
+ setpgrp(rc_pid, rc_pid);
+#ifdef TIOCSPGRP
+ ioctl(2, TIOCSPGRP, &rc_pid);
+#endif
}
/* Berkeley limit support was cleaned up by Paul Haahr. */
-#if HAVE_SETRLIMIT
+#ifndef NOLIMITS
typedef struct Suffix Suffix;
struct Suffix {
const Suffix *next;
@@ -463,9 +464,14 @@ static const Limit limits[] = {
{ NULL, 0, NULL }
};
+#ifndef SYSVR4
+extern int getrlimit(int, struct rlimit *);
+extern int setrlimit(int, struct rlimit *);
+#endif
+
static void printlimit(const Limit *limit, bool hard) {
struct rlimit rlim;
- rlim_t lim;
+ long lim;
getrlimit(limit->flag, &rlim);
if (hard)
lim = rlim.rlim_max;
@@ -480,11 +486,11 @@ static void printlimit(const Limit *limit, bool hard) {
lim /= suf->amount;
break;
}
- fprint(1, RLIM_FMT, limit->name, (RLIM_CONV)lim, (suf == NULL || lim == 0) ? "" : suf->name);
+ fprint(1, "%s \t%d%s\n", limit->name, lim, (suf == NULL || lim == 0) ? "" : suf->name);
}
}
-static rlim_t parselimit(const Limit *limit, char *s) {
+static long parselimit(const Limit *limit, char *s) {
char *t;
int len = strlen(s);
long lim = 1;
diff --git a/config.h.in b/config.h.in
@@ -1,44 +0,0 @@
-/* Header files */
-#undef STDC_HEADERS
-
-#undef HAVE_SYS_RESOURCE_H
-#undef RLIMIT_NEEDS_KERNEL
-#undef HAVE_SYS_TIME_H
-#undef HAVE_UNISTD_H
-
-#undef HAVE_DIRENT_H
-#undef HAVE_SYS_NDIR_H
-#undef HAVE_SYS_DIR_H
-#undef HAVE_NDIR_H
-
-/* Functions */
-#undef HAVE_GETGROUPS
-#undef HAVE_SETPGRP
-#undef HAVE_SETRLIMIT
-
-/* Types */
-#undef HAVE_GID_T
-#undef HAVE_RLIM_T
-#undef HAVE_QUAD_T
-#undef RLIM_T_IS_QUAD_T
-#undef GETGROUPS_T
-#undef gid_t
-#undef pid_t
-#undef size_t
-#undef uid_t
-
-/* OS features */
-#undef HASH_BANG
-#undef HAVE_DEV_FD
-#undef HAVE_FIFO
-#undef HAVE_PROC_SELF_FD
-#undef HAVE_RESTARTABLE_SYSCALLS
-#undef SETPGRP_VOID
-
-/* rc features */
-#undef DEFAULTINTERP
-#undef DEFAULTPATH
-#undef RC_ECHO
-#undef RC_JOB
-#undef PROTECT_ENV
-#undef READLINE
diff --git a/configure b/configure
@@ -1,2541 +0,0 @@
-#! /bin/sh
-
-# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.12
-# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
-#
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-
-# Defaults:
-ac_help=
-ac_default_prefix=/usr/local
-# Any additions from configure.in:
-ac_help="$ac_help
- --disable-builtin-echo Don't include \`echo' as a builtin"
-ac_help="$ac_help
- --disable-job Don't do job-control-style backgrounding"
-ac_help="$ac_help
- --disable-protect-env Don't protect environment names"
-ac_help="$ac_help
- --enable-def-interp=/bin/foo
- Use /bin/foo as default interpreter [/bin/sh]"
-ac_help="$ac_help
- --enable-def-path=\"/usr/local/bin/\",\"/usr/bin\"
- Default path [All of these that exist
- (/usr/local/bin /usr/bin /usr/ucb /bin .)]"
-ac_help="$ac_help
- --enable-history Build history subprograms"
-ac_help="$ac_help
- --with-addon Extra builtins, from addon.c "
-ac_help="$ac_help
- --with-editline Simmule Turner's line editing"
-ac_help="$ac_help
- --with-readline Bloated GNU line editing"
-
-# Initialize some variables set by options.
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-build=NONE
-cache_file=./config.cache
-exec_prefix=NONE
-host=NONE
-no_create=
-nonopt=NONE
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-target=NONE
-verbose=
-x_includes=NONE
-x_libraries=NONE
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
-
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-# Maximum number of lines to put in a shell here document.
-ac_max_here_lines=12
-
-ac_prev=
-for ac_option
-do
-
- # If the previous option needs an argument, assign it.
- if test -n "$ac_prev"; then
- eval "$ac_prev=\$ac_option"
- ac_prev=
- continue
- fi
-
- case "$ac_option" in
- -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
- *) ac_optarg= ;;
- esac
-
- # Accept the important Cygnus configure options, so we can diagnose typos.
-
- case "$ac_option" in
-
- -bindir | --bindir | --bindi | --bind | --bin | --bi)
- ac_prev=bindir ;;
- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir="$ac_optarg" ;;
-
- -build | --build | --buil | --bui | --bu)
- ac_prev=build ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build="$ac_optarg" ;;
-
- -cache-file | --cache-file | --cache-fil | --cache-fi \
- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
- ac_prev=cache_file ;;
- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file="$ac_optarg" ;;
-
- -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
- ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
- | --da=*)
- datadir="$ac_optarg" ;;
-
- -disable-* | --disable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- eval "enable_${ac_feature}=no" ;;
-
- -enable-* | --enable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "enable_${ac_feature}='$ac_optarg'" ;;
-
- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
- | --exec | --exe | --ex)
- ac_prev=exec_prefix ;;
- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
- | --exec=* | --exe=* | --ex=*)
- exec_prefix="$ac_optarg" ;;
-
- -gas | --gas | --ga | --g)
- # Obsolete; use --with-gas.
- with_gas=yes ;;
-
- -help | --help | --hel | --he)
- # Omit some internal or obsolete options to make the list less imposing.
- # This message is too long to be a string in the A/UX 3.1 sh.
- cat << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
- --cache-file=FILE cache test results in FILE
- --help print this message
- --no-create do not create output files
- --quiet, --silent do not print \`checking...' messages
- --version print the version of autoconf that created configure
-Directory and file names:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [same as prefix]
- --bindir=DIR user executables in DIR [EPREFIX/bin]
- --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
- --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data in DIR
- [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data in DIR
- [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
- --libdir=DIR object code libraries in DIR [EPREFIX/lib]
- --includedir=DIR C header files in DIR [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
- --infodir=DIR info documentation in DIR [PREFIX/info]
- --mandir=DIR man documentation in DIR [PREFIX/man]
- --srcdir=DIR find the sources in DIR [configure dir or ..]
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM
- run sed PROGRAM on installed program names
-EOF
- cat << EOF
-Host type:
- --build=BUILD configure for building on BUILD [BUILD=HOST]
- --host=HOST configure for HOST [guessed]
- --target=TARGET configure for TARGET [TARGET=HOST]
-Features and packages:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --x-includes=DIR X include files are in DIR
- --x-libraries=DIR X library files are in DIR
-EOF
- if test -n "$ac_help"; then
- echo "--enable and --with options recognized:$ac_help"
- fi
- exit 0 ;;
-
- -host | --host | --hos | --ho)
- ac_prev=host ;;
- -host=* | --host=* | --hos=* | --ho=*)
- host="$ac_optarg" ;;
-
- -includedir | --includedir | --includedi | --included | --include \
- | --includ | --inclu | --incl | --inc)
- ac_prev=includedir ;;
- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
- | --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir="$ac_optarg" ;;
-
- -infodir | --infodir | --infodi | --infod | --info | --inf)
- ac_prev=infodir ;;
- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir="$ac_optarg" ;;
-
- -libdir | --libdir | --libdi | --libd)
- ac_prev=libdir ;;
- -libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir="$ac_optarg" ;;
-
- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
- | --libexe | --libex | --libe)
- ac_prev=libexecdir ;;
- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
- | --libexe=* | --libex=* | --libe=*)
- libexecdir="$ac_optarg" ;;
-
- -localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst \
- | --locals | --local | --loca | --loc | --lo)
- ac_prev=localstatedir ;;
- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* \
- | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
- localstatedir="$ac_optarg" ;;
-
- -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
- ac_prev=mandir ;;
- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir="$ac_optarg" ;;
-
- -nfp | --nfp | --nf)
- # Obsolete; use --without-fp.
- with_fp=no ;;
-
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c)
- no_create=yes ;;
-
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
- no_recursion=yes ;;
-
- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
- | --oldin | --oldi | --old | --ol | --o)
- ac_prev=oldincludedir ;;
- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir="$ac_optarg" ;;
-
- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
- ac_prev=prefix ;;
- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix="$ac_optarg" ;;
-
- -program-prefix | --program-prefix | --program-prefi | --program-pref \
- | --program-pre | --program-pr | --program-p)
- ac_prev=program_prefix ;;
- -program-prefix=* | --program-prefix=* | --program-prefi=* \
- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix="$ac_optarg" ;;
-
- -program-suffix | --program-suffix | --program-suffi | --program-suff \
- | --program-suf | --program-su | --program-s)
- ac_prev=program_suffix ;;
- -program-suffix=* | --program-suffix=* | --program-suffi=* \
- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix="$ac_optarg" ;;
-
- -program-transform-name | --program-transform-name \
- | --program-transform-nam | --program-transform-na \
- | --program-transform-n | --program-transform- \
- | --program-transform | --program-transfor \
- | --program-transfo | --program-transf \
- | --program-trans | --program-tran \
- | --progr-tra | --program-tr | --program-t)
- ac_prev=program_transform_name ;;
- -program-transform-name=* | --program-transform-name=* \
- | --program-transform-nam=* | --program-transform-na=* \
- | --program-transform-n=* | --program-transform-=* \
- | --program-transform=* | --program-transfor=* \
- | --program-transfo=* | --program-transf=* \
- | --program-trans=* | --program-tran=* \
- | --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name="$ac_optarg" ;;
-
- -q | -quiet | --quiet | --quie | --qui | --qu | --q \
- | -silent | --silent | --silen | --sile | --sil)
- silent=yes ;;
-
- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
- ac_prev=sbindir ;;
- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
- | --sbi=* | --sb=*)
- sbindir="$ac_optarg" ;;
-
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
- | --sha | --sh)
- ac_prev=sharedstatedir ;;
- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
- | --sha=* | --sh=*)
- sharedstatedir="$ac_optarg" ;;
-
- -site | --site | --sit)
- ac_prev=site ;;
- -site=* | --site=* | --sit=*)
- site="$ac_optarg" ;;
-
- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
- ac_prev=srcdir ;;
- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir="$ac_optarg" ;;
-
- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
- | --syscon | --sysco | --sysc | --sys | --sy)
- ac_prev=sysconfdir ;;
- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir="$ac_optarg" ;;
-
- -target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target ;;
- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target="$ac_optarg" ;;
-
- -v | -verbose | --verbose | --verbos | --verbo | --verb)
- verbose=yes ;;
-
- -version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.12"
- exit 0 ;;
-
- -with-* | --with-*)
- ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
- *) ac_optarg=yes ;;
- esac
- eval "with_${ac_package}='$ac_optarg'" ;;
-
- -without-* | --without-*)
- ac_package=`echo $ac_option|sed -e 's/-*without-//'`
- # Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- eval "with_${ac_package}=no" ;;
-
- --x)
- # Obsolete; use --with-x.
- with_x=yes ;;
-
- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
- | --x-incl | --x-inc | --x-in | --x-i)
- ac_prev=x_includes ;;
- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes="$ac_optarg" ;;
-
- -x-libraries | --x-libraries | --x-librarie | --x-librari \
- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
- ac_prev=x_libraries ;;
- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries="$ac_optarg" ;;
-
- -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
- ;;
-
- *)
- if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
- echo "configure: warning: $ac_option: invalid host type" 1>&2
- fi
- if test "x$nonopt" != xNONE; then
- { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
- fi
- nonopt="$ac_option"
- ;;
-
- esac
-done
-
-if test -n "$ac_prev"; then
- { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-fi
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
- exec 6>/dev/null
-else
- exec 6>&1
-fi
-exec 5>./config.log
-
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
-
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
-do
- case "$ac_arg" in
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c) ;;
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
- ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- *) ac_configure_args="$ac_configure_args $ac_arg" ;;
- esac
-done
-
-# NLS nuisances.
-# Only set these to C if already set. These must not be set unconditionally
-# because not all systems understand e.g. LANG=C (notably SCO).
-# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
-# Non-C LC_CTYPE values break the ctype check.
-if test "${LANG+set}" = set; then LANG=C; export LANG; fi
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
-if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo > confdefs.h
-
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=rc.h
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
- ac_srcdir_defaulted=yes
- # Try the directory containing this script, then its parent.
- ac_prog=$0
- ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
- test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
- srcdir=$ac_confdir
- if test ! -r $srcdir/$ac_unique_file; then
- srcdir=..
- fi
-else
- ac_srcdir_defaulted=no
-fi
-if test ! -r $srcdir/$ac_unique_file; then
- if test "$ac_srcdir_defaulted" = yes; then
- { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
- else
- { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
- fi
-fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
-
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
- if test "x$prefix" != xNONE; then
- CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
- else
- CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
- fi
-fi
-for ac_site_file in $CONFIG_SITE; do
- if test -r "$ac_site_file"; then
- echo "loading site script $ac_site_file"
- . "$ac_site_file"
- fi
-done
-
-if test -r "$cache_file"; then
- echo "loading cache $cache_file"
- . $cache_file
-else
- echo "creating cache $cache_file"
- > $cache_file
-fi
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
- # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
- if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
- ac_n= ac_c='
-' ac_t=' '
- else
- ac_n=-n ac_c= ac_t=
- fi
-else
- ac_n= ac_c='\c' ac_t=
-fi
-
-
-
-
-
-# Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:549: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="gcc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-if test -z "$CC"; then
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:578: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$CC"; then
- ac_cv_prog_CC="$CC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- ac_prog_rejected=no
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- break
- fi
- done
- IFS="$ac_save_ifs"
-if test $ac_prog_rejected = yes; then
- # We found a bogon in the path, so make sure we never use it.
- set dummy $ac_cv_prog_CC
- shift
- if test $# -gt 0; then
- # We chose a different compiler from the bogus one.
- # However, it has the same basename, so the bogon will be chosen
- # first if we set CC to just the basename; use the full file name.
- shift
- set dummy "$ac_dir/$ac_word" "$@"
- shift
- ac_cv_prog_CC="$@"
- fi
-fi
-fi
-fi
-CC="$ac_cv_prog_CC"
-if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
- test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:626: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-cat > conftest.$ac_ext <<EOF
-#line 636 "configure"
-#include "confdefs.h"
-main(){return(0);}
-EOF
-if { (eval echo configure:640: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- ac_cv_prog_cc_works=yes
- # If we can't run a trivial program, we are probably using a cross compiler.
- if (./conftest; exit) 2>/dev/null; then
- ac_cv_prog_cc_cross=no
- else
- ac_cv_prog_cc_cross=yes
- fi
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- ac_cv_prog_cc_works=no
-fi
-rm -fr conftest*
-
-echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
-if test $ac_cv_prog_cc_works = no; then
- { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
-fi
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:660: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:665: checking whether we are using GNU C" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.c <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:674: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gcc=yes
-else
- ac_cv_prog_gcc=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
-
-if test $ac_cv_prog_gcc = yes; then
- GCC=yes
- ac_test_CFLAGS="${CFLAGS+set}"
- ac_save_CFLAGS="$CFLAGS"
- CFLAGS=
- echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:689: checking whether ${CC-cc} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
- ac_cv_prog_cc_g=yes
-else
- ac_cv_prog_cc_g=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
- if test "$ac_test_CFLAGS" = set; then
- CFLAGS="$ac_save_CFLAGS"
- elif test $ac_cv_prog_cc_g = yes; then
- CFLAGS="-g -O2"
- else
- CFLAGS="-O2"
- fi
-else
- GCC=
- test "${CFLAGS+set}" = set || CFLAGS="-g"
-fi
-
-case "x$GCC" in
-xyes)
- CFLAGS="-Wall $CFLAGS"
- ;;
-esac
-
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
- if test -f $ac_dir/install-sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f $ac_dir/install.sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
-# Find a good install program. We prefer a C program (faster),
-# so one script is as good as another. But avoid the broken or
-# incompatible versions:
-# SysV /etc/install, /usr/sbin/install
-# SunOS /usr/etc/install
-# IRIX /sbin/install
-# AIX /bin/install
-# AFS /usr/afsws/bin/install, which mishandles nonexistent args
-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
-# ./install, which can be erroneously created by make from ./install.sh.
-echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:752: checking for a BSD compatible install" >&5
-if test -z "$INSTALL"; then
-if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- # Account for people who put trailing slashes in PATH elements.
- case "$ac_dir/" in
- /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
- *)
- # OSF1 and SCO ODT 3.0 have their own names for install.
- for ac_prog in ginstall installbsd scoinst install; do
- if test -f $ac_dir/$ac_prog; then
- if test $ac_prog = install &&
- grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
- # AIX install. It has an incompatible calling convention.
- # OSF/1 installbsd also uses dspmsg, but is usable.
- :
- else
- ac_cv_path_install="$ac_dir/$ac_prog -c"
- break 2
- fi
- fi
- done
- ;;
- esac
- done
- IFS="$ac_save_IFS"
-
-fi
- if test "${ac_cv_path_install+set}" = set; then
- INSTALL="$ac_cv_path_install"
- else
- # As a last resort, use the slow shell script. We don't cache a
- # path for INSTALL within a source directory, because that will
- # break other packages using the cache if that directory is
- # removed, or if the path is relative.
- INSTALL="$ac_install_sh"
- fi
-fi
-echo "$ac_t""$INSTALL" 1>&6
-
-# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
-# It thinks the first close brace ends the variable substitution.
-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-
-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-
-for ac_prog in 'bison -y' byacc
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:806: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$YACC"; then
- ac_cv_prog_YACC="$YACC" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_YACC="$ac_prog"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-YACC="$ac_cv_prog_YACC"
-if test -n "$YACC"; then
- echo "$ac_t""$YACC" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-test -n "$YACC" && break
-done
-test -n "$YACC" || YACC="yacc"
-
-for ac_prog in ln cp
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:840: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_LN'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$LN"; then
- ac_cv_prog_LN="$LN" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_LN="$ac_prog"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-LN="$ac_cv_prog_LN"
-if test -n "$LN"; then
- echo "$ac_t""$LN" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-test -n "$LN" && break
-done
-
-
-echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:870: checking how to run the C preprocessor" >&5
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- # This must be in double quotes, not single quotes, because CPP may get
- # substituted into the Makefile and "${CC-cc}" will confuse make.
- CPP="${CC-cc} -E"
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp.
- cat > conftest.$ac_ext <<EOF
-#line 885 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:891: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -E -traditional-cpp"
- cat > conftest.$ac_ext <<EOF
-#line 902 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:908: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP=/lib/cpp
-fi
-rm -f conftest*
-fi
-rm -f conftest*
- ac_cv_prog_CPP="$CPP"
-fi
- CPP="$ac_cv_prog_CPP"
-else
- ac_cv_prog_CPP="$CPP"
-fi
-echo "$ac_t""$CPP" 1>&6
-
-for ac_hdr in sys/resource.h sys/time.h sys/types.h unistd.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:934: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 939 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:944: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-ac_header_dirent=no
-for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-echo "configure:975: checking for $ac_hdr that defines DIR" >&5
-if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 980 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#include <$ac_hdr>
-int main() {
-DIR *dirp = 0;
-; return 0; }
-EOF
-if { (eval echo configure:988: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- eval "ac_cv_header_dirent_$ac_safe=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_dirent_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
- ac_header_dirent=$ac_hdr; break
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
-if test $ac_header_dirent = dirent.h; then
-echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
-echo "configure:1013: checking for opendir in -ldir" >&5
-ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-ldir $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1021 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char opendir();
-
-int main() {
-opendir()
-; return 0; }
-EOF
-if { (eval echo configure:1032: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- LIBS="$LIBS -ldir"
-else
- echo "$ac_t""no" 1>&6
-fi
-
-else
-echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:1054: checking for opendir in -lx" >&5
-ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lx $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 1062 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char opendir();
-
-int main() {
-opendir()
-; return 0; }
-EOF
-if { (eval echo configure:1073: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- LIBS="$LIBS -lx"
-else
- echo "$ac_t""no" 1>&6
-fi
-
-fi
-
-echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1096: checking for ANSI C header files" >&5
-if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1101 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1109: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- ac_cv_header_stdc=yes
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1126 "configure"
-#include "confdefs.h"
-#include <string.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "memchr" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 1144 "configure"
-#include "confdefs.h"
-#include <stdlib.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "free" >/dev/null 2>&1; then
- :
-else
- rm -rf conftest*
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-if test "$cross_compiling" = yes; then
- :
-else
- cat > conftest.$ac_ext <<EOF
-#line 1165 "configure"
-#include "confdefs.h"
-#include <ctype.h>
-#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int main () { int i; for (i = 0; i < 256; i++)
-if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
-exit (0); }
-
-EOF
-if { (eval echo configure:1176: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- :
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_header_stdc=no
-fi
-rm -fr conftest*
-fi
-
-fi
-fi
-
-echo "$ac_t""$ac_cv_header_stdc" 1>&6
-if test $ac_cv_header_stdc = yes; then
- cat >> confdefs.h <<\EOF
-#define STDC_HEADERS 1
-EOF
-
-fi
-
-
-echo $ac_n "checking for signal names in <sys/signal.h>""... $ac_c" 1>&6
-echo "configure:1201: checking for signal names in <sys/signal.h>" >&5
-if eval "test \"`echo '$''{'rc_cv_sys_signal_h'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if grep SIGINT /usr/include/sys/signal.h >/dev/null 2>&1; then
- rc_cv_sys_signal_h=yes
- else
- rc_cv_sys_signal_h=no
- fi
-fi
-
-echo "$ac_t""$rc_cv_sys_signal_h" 1>&6
-
-case "x$rc_cv_sys_signal_h" in
-xyes)
- SIGNAL_H=/usr/include/sys/signal.h
- ;;
-xno)
- echo $ac_n "checking for signal names in <asm/signal.h>""... $ac_c" 1>&6
-echo "configure:1220: checking for signal names in <asm/signal.h>" >&5
-if eval "test \"`echo '$''{'rc_cv_asm_signal_h'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if grep SIGINT /usr/include/asm/signal.h >/dev/null 2>&1; then
- rc_cv_asm_signal_h=yes
- else
- rc_cv_asm_signal_h=no
- fi
-fi
-
-echo "$ac_t""$rc_cv_asm_signal_h" 1>&6
-
- case "x$rc_cv_asm_signal_h" in
- xyes)
- SIGNAL_H=/usr/include/asm/signal.h
- ;;
- xno)
- { echo "configure: error: Can't find signal names in <sys/signal.h> or <asm/signal.h>" 1>&2; exit 1; }
- ;;
- esac
- ;;
-esac
-
-
-echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:1246: checking for uid_t in sys/types.h" >&5
-if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1251 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "uid_t" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_uid_t=yes
-else
- rm -rf conftest*
- ac_cv_type_uid_t=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_type_uid_t" 1>&6
-if test $ac_cv_type_uid_t = no; then
- cat >> confdefs.h <<\EOF
-#define uid_t int
-EOF
-
- cat >> confdefs.h <<\EOF
-#define gid_t int
-EOF
-
-fi
-
-echo $ac_n "checking type of array argument to getgroups""... $ac_c" 1>&6
-echo "configure:1280: checking type of array argument to getgroups" >&5
-if eval "test \"`echo '$''{'ac_cv_type_getgroups'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_type_getgroups=cross
-else
- cat > conftest.$ac_ext <<EOF
-#line 1288 "configure"
-#include "confdefs.h"
-
-/* Thanks to Mike Rendell for this test. */
-#include <sys/types.h>
-#define NGID 256
-#undef MAX
-#define MAX(x, y) ((x) > (y) ? (x) : (y))
-main()
-{
- gid_t gidset[NGID];
- int i, n;
- union { gid_t gval; long lval; } val;
-
- val.lval = -1;
- for (i = 0; i < NGID; i++)
- gidset[i] = val.gval;
- n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1,
- gidset);
- /* Exit non-zero if getgroups seems to require an array of ints. This
- happens when gid_t is short but getgroups modifies an array of ints. */
- exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0);
-}
-
-EOF
-if { (eval echo configure:1313: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- ac_cv_type_getgroups=gid_t
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_type_getgroups=int
-fi
-rm -fr conftest*
-fi
-
-if test $ac_cv_type_getgroups = cross; then
- cat > conftest.$ac_ext <<EOF
-#line 1327 "configure"
-#include "confdefs.h"
-#include <unistd.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "getgroups.*int.*gid_t" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_getgroups=gid_t
-else
- rm -rf conftest*
- ac_cv_type_getgroups=int
-fi
-rm -f conftest*
-
-fi
-fi
-
-echo "$ac_t""$ac_cv_type_getgroups" 1>&6
-cat >> confdefs.h <<EOF
-#define GETGROUPS_T $ac_cv_type_getgroups
-EOF
-
-
-echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:1351: checking for pid_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1356 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_pid_t=yes
-else
- rm -rf conftest*
- ac_cv_type_pid_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_pid_t" 1>&6
-if test $ac_cv_type_pid_t = no; then
- cat >> confdefs.h <<\EOF
-#define pid_t int
-EOF
-
-fi
-
-echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:1384: checking for size_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1389 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_size_t=yes
-else
- rm -rf conftest*
- ac_cv_type_size_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_size_t" 1>&6
-if test $ac_cv_type_size_t = no; then
- cat >> confdefs.h <<\EOF
-#define size_t unsigned
-EOF
-
-fi
-
-echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:1417: checking for uid_t in sys/types.h" >&5
-if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1422 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "uid_t" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_uid_t=yes
-else
- rm -rf conftest*
- ac_cv_type_uid_t=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_type_uid_t" 1>&6
-if test $ac_cv_type_uid_t = no; then
- cat >> confdefs.h <<\EOF
-#define uid_t int
-EOF
-
- cat >> confdefs.h <<\EOF
-#define gid_t int
-EOF
-
-fi
-
-
-for ac_func in getgroups setpgrp setrlimit
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1454: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1459 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:1482: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-echo $ac_n "checking whether setpgrp takes no argument""... $ac_c" 1>&6
-echo "configure:1508: checking whether setpgrp takes no argument" >&5
-if eval "test \"`echo '$''{'ac_cv_func_setpgrp_void'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- { echo "configure: error: cannot check setpgrp if cross compiling" 1>&2; exit 1; }
-else
- cat > conftest.$ac_ext <<EOF
-#line 1516 "configure"
-#include "confdefs.h"
-
-/*
- * If this system has a BSD-style setpgrp, which takes arguments, exit
- * successfully.
- */
-main()
-{
- if (setpgrp(1,1) == -1)
- exit(0);
- else
- exit(1);
-}
-
-EOF
-if { (eval echo configure:1532: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- ac_cv_func_setpgrp_void=no
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_func_setpgrp_void=yes
-fi
-rm -fr conftest*
-fi
-
-
-fi
-
-echo "$ac_t""$ac_cv_func_setpgrp_void" 1>&6
-if test $ac_cv_func_setpgrp_void = yes; then
- cat >> confdefs.h <<\EOF
-#define SETPGRP_VOID 1
-EOF
-
-fi
-
-
-echo $ac_n "checking if _KERNEL is required for RLIMIT defines""... $ac_c" 1>&6
-echo "configure:1557: checking if _KERNEL is required for RLIMIT defines" >&5
-if eval "test \"`echo '$''{'rc_cv_kernel_rlimit'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1562 "configure"
-#include "confdefs.h"
-
-#include <sys/types.h>
-#include <sys/resource.h>
-
-int main() {
-
-int f;
-f = RLIMIT_DATA;
-
-; return 0; }
-EOF
-if { (eval echo configure:1575: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- rc_cv_kernel_rlimit=no
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- cat > conftest.$ac_ext <<EOF
-#line 1583 "configure"
-#include "confdefs.h"
-
-#include <sys/types.h>
-#define _KERNEL
-#include <sys/resource.h>
-#undef _KERNEL
-
-int main() {
-
-int f;
-f = RLIMIT_DATA;
-
-; return 0; }
-EOF
-if { (eval echo configure:1598: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- rc_cv_kernel_rlimit=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- rc_cv_kernel_rlimit=no
-fi
-rm -f conftest*
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$rc_cv_kernel_rlimit" 1>&6
-case "x$rc_cv_kernel_rlimit" in
-xyes)
- cat >> confdefs.h <<\EOF
-#define RLIMIT_NEEDS_KERNEL 1
-EOF
-
- ;;
-esac
-
-echo $ac_n "checking for rlim_t""... $ac_c" 1>&6
-echo "configure:1623: checking for rlim_t" >&5
-if eval "test \"`echo '$''{'rc_cv_have_rlim_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1628 "configure"
-#include "confdefs.h"
-
-#include <sys/types.h>
-#if RLIMIT_NEEDS_KERNEL
-#define _KERNEL
-#endif
-#include <sys/resource.h>
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "rlim_t" >/dev/null 2>&1; then
- rm -rf conftest*
- rc_cv_have_rlim_t=yes
-else
- rm -rf conftest*
- rc_cv_have_rlim_t=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$rc_cv_have_rlim_t" 1>&6
-
-case "x$rc_cv_have_rlim_t" in
-xyes)
- cat >> confdefs.h <<\EOF
-#define HAVE_RLIM_T 1
-EOF
-
- ;;
-xno)
- echo $ac_n "checking for native quad_t""... $ac_c" 1>&6
-echo "configure:1661: checking for native quad_t" >&5
-if eval "test \"`echo '$''{'rc_cv_have_quad_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
- cat > conftest.$ac_ext <<EOF
-#line 1669 "configure"
-#include "confdefs.h"
-
-#include <sys/types.h>
-main() {
- quad_t q;
- q = 0;
- exit((int) q);
-}
-
-EOF
-if { (eval echo configure:1680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- rc_cv_have_quad_t=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- rc_cv_have_quad_t=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$rc_cv_have_quad_t" 1>&6
-
- case "x$rc_cv_have_quad_t" in
- xyes)
- cat >> confdefs.h <<\EOF
-#define HAVE_QUAD_T 1
-EOF
-
-
- echo $ac_n "checking if rlimit values are quad_t""... $ac_c" 1>&6
-echo "configure:1704: checking if rlimit values are quad_t" >&5
-if eval "test \"`echo '$''{'rc_cv_rlim_t_is_quad_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- $ac_cv_type_quad_t
-else
- cat > conftest.$ac_ext <<EOF
-#line 1712 "configure"
-#include "confdefs.h"
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#if RLIMIT_NEEDS_KERNEL
-#define _KERNEL
-#endif
-#include <sys/resource.h>
-#if RLIMIT_NEEDS_KERNEL
-#undef _KERNEL
-#endif
-main(){
- struct rlimit rl;
- exit(sizeof rl.rlim_cur != sizeof(quad_t));
-}
-
-EOF
-if { (eval echo configure:1731: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- rc_cv_rlim_t_is_quad_t=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- rc_cv_rlim_t_is_quad_t=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$rc_cv_rlim_t_is_quad_t" 1>&6
-
- case "x$rc_cv_rlim_t_is_quad_t" in
- xyes)
- cat >> confdefs.h <<\EOF
-#define RLIM_T_IS_QUAD_T 1
-EOF
-
- ;;
- esac
- ;;
- esac
- ;;
-esac
-
-echo $ac_n "checking for restartable system calls""... $ac_c" 1>&6
-echo "configure:1761: checking for restartable system calls" >&5
-if eval "test \"`echo '$''{'ac_cv_sys_restartable_syscalls'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
- cat > conftest.$ac_ext <<EOF
-#line 1769 "configure"
-#include "confdefs.h"
-/* Exit 0 (true) if wait returns something other than -1,
- i.e. the pid of the child, which means that wait was restarted
- after getting the signal. */
-#include <sys/types.h>
-#include <signal.h>
-ucatch (isig) { }
-main () {
- int i = fork (), status;
- if (i == 0) { sleep (3); kill (getppid (), SIGINT); sleep (3); exit (0); }
- signal (SIGINT, ucatch);
- status = wait(&i);
- if (status == -1) wait(&i);
- exit (status == -1);
-}
-
-EOF
-if { (eval echo configure:1787: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- ac_cv_sys_restartable_syscalls=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_sys_restartable_syscalls=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$ac_cv_sys_restartable_syscalls" 1>&6
-if test $ac_cv_sys_restartable_syscalls = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_RESTARTABLE_SYSCALLS 1
-EOF
-
-fi
-
-
-# Pull the hash mark out of the macro call to avoid m4 problems.
-ac_msg="whether #! works in shell scripts"
-echo $ac_n "checking $ac_msg""... $ac_c" 1>&6
-echo "configure:1813: checking $ac_msg" >&5
-if eval "test \"`echo '$''{'ac_cv_sys_interpreter'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- echo '#! /bin/cat
-exit 69
-' > conftest
-chmod u+x conftest
-(SHELL=/bin/sh; export SHELL; ./conftest >/dev/null)
-if test $? -ne 69; then
- ac_cv_sys_interpreter=yes
-else
- ac_cv_sys_interpreter=no
-fi
-rm -f conftest
-fi
-
-echo "$ac_t""$ac_cv_sys_interpreter" 1>&6
-
-case "x$ac_cv_sys_interpreter" in
-xyes)
- cat >> confdefs.h <<\EOF
-#define HASH_BANG 1
-EOF
-
- EXECVE=''
- ;;
-xno)
- EXECVE=execve.o
-esac
-
-
-echo $ac_n "checking for /dev/fd""... $ac_c" 1>&6
-echo "configure:1846: checking for /dev/fd" >&5
-if eval "test \"`echo '$''{'rc_cv_sys_dev_fd'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -d /dev/fd && test -r /dev/fd/0; then
- rc_cv_sys_dev_fd=yes
- elif test -d /proc/self/fd && test -r /proc/self/fd/0; then
- rc_cv_sys_dev_fd=odd
- else
- rc_cv_sys_dev_fd=no
- fi
-fi
-
-echo "$ac_t""$rc_cv_sys_dev_fd" 1>&6
-
-case "x$rc_cv_sys_dev_fd" in
-xyes)
- cat >> confdefs.h <<\EOF
-#define HAVE_DEV_FD 1
-EOF
-
- ;;
-xodd)
- cat >> confdefs.h <<\EOF
-#define HAVE_PROC_SELF_FD 1
-EOF
-
- ;;
-xno)
- echo $ac_n "checking for named pipes""... $ac_c" 1>&6
-echo "configure:1876: checking for named pipes" >&5
-if eval "test \"`echo '$''{'rc_cv_sys_fifo'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat >> confdefs.h <<EOF
-#define TMPNAM "/tmp/rc$$.0"
-EOF
-
- if test "$cross_compiling" = yes; then
- rc_cv_sys_fifo=no
-else
- cat > conftest.$ac_ext <<EOF
-#line 1888 "configure"
-#include "confdefs.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-main() {
- exit(mknod(TMPNAM, S_IFIFO | 0666, 0) != 0);
-}
-
-EOF
-if { (eval echo configure:1899: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- rc_cv_sys_fifo=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- rc_cv_sys_fifo=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$rc_cv_sys_fifo" 1>&6
- case "x$rc_cv_sys_fifo" in
- xyes)
- cat >> confdefs.h <<\EOF
-#define HAVE_FIFO 1
-EOF
-
- ;;
- esac
-esac
-
-# Check whether --enable-builtin-echo or --disable-builtin-echo was given.
-if test "${enable_builtin_echo+set}" = set; then
- enableval="$enable_builtin_echo"
- test "x$enableval" != "xno" && cat >> confdefs.h <<\EOF
-#define RC_ECHO 1
-EOF
-
-else
- cat >> confdefs.h <<\EOF
-#define RC_ECHO 1
-EOF
-
-fi
-
-
-# Check whether --enable-job or --disable-job was given.
-if test "${enable_job+set}" = set; then
- enableval="$enable_job"
- test "x$enableval" != "xno" && cat >> confdefs.h <<\EOF
-#define RC_JOB 1
-EOF
-
-else
- cat >> confdefs.h <<\EOF
-#define RC_JOB 1
-EOF
-
-fi
-
-
-# Check whether --enable-protect-env or --disable-protect-env was given.
-if test "${enable_protect_env+set}" = set; then
- enableval="$enable_protect_env"
- test "x$enableval" != "xno" && cat >> confdefs.h <<\EOF
-#define PROTECT_ENV 1
-EOF
-
-else
- cat >> confdefs.h <<\EOF
-#define PROTECT_ENV 1
-EOF
-
-fi
-
-
-# Check whether --enable-def-interp or --disable-def-interp was given.
-if test "${enable_def_interp+set}" = set; then
- enableval="$enable_def_interp"
-
- case "x$enableval" in
- xno)
- ;;
- xyes)
- cat >> confdefs.h <<\EOF
-#define DEFAULTINTERP "/bin/sh"
-EOF
-
- ;;
- *)
- cat >> confdefs.h <<EOF
-#define DEFAULTINTERP "$enableval"
-EOF
-
- esac
-
-else
- cat >> confdefs.h <<\EOF
-#define DEFAULTINTERP "/bin/sh"
-EOF
-
-fi
-
-
-# Check whether --enable-def-path or --disable-def-path was given.
-if test "${enable_def_path+set}" = set; then
- enableval="$enable_def_path"
-
- case "x$enableval" in
- xno|xyes)
- ;;
- *)
- cat >> confdefs.h <<EOF
-#define DEFAULTPATH $enableval
-EOF
-
- esac
-
-else
- enable_def_path=yes
-fi
-
-
-case "x$enable_def_path" in
-xyes)
- echo $ac_n "checking extant directories for default path""... $ac_c" 1>&6
-echo "configure:2019: checking extant directories for default path" >&5
-if eval "test \"`echo '$''{'rc_cv_def_path'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
- rc_cv_def_path=''
- for i in /usr/local/bin /usr/bin /usr/ucb /bin .; do
- if test -d $i; then
- case "x$rc_cv_def_path" in
- x)
- rc_cv_def_path=\"$i\"
- ;;
- *)
- rc_cv_def_path=$rc_cv_def_path,\"$i\"
- ;;
- esac
- fi
- done
- cat >> confdefs.h <<EOF
-#define DEFAULTPATH $rc_cv_def_path
-EOF
-
-
-fi
-
-echo "$ac_t""$rc_cv_def_path" 1>&6
- ;;
-esac
-
-# Check whether --enable-history or --disable-history was given.
-if test "${enable_history+set}" = set; then
- enableval="$enable_history"
- test "x$enableval" != "xno" && rc_history=yes
-else
- rc_history=no
-fi
-
-case "x$rc_history" in
-xyes)
- HISTORY=history/history
- ;;
-esac
-
-
-# Check whether --with-addon or --without-addon was given.
-if test "${with_addon+set}" = set; then
- withval="$with_addon"
-
- case "x$withval" in
- xyes)
- ADDON=addon.o
- ;;
- xno)
- ADDON=''
- ;;
- *)
- ADDON=$withval
- ;;
- esac
-
-fi
-
-
-
-# Check whether --with-editline or --without-editline was given.
-if test "${with_editline+set}" = set; then
- withval="$with_editline"
- echo $ac_n "checking for readline in -ledit""... $ac_c" 1>&6
-echo "configure:2087: checking for readline in -ledit" >&5
-ac_lib_var=`echo edit'_'readline | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-ledit $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 2095 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char readline();
-
-int main() {
-readline()
-; return 0; }
-EOF
-if { (eval echo configure:2106: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<\EOF
-#define READLINE 1
-EOF
- LIBS="$LIBS -ledit"
-else
- echo "$ac_t""no" 1>&6
-echo "configure: warning: editline library not found" 1>&2
-fi
-
-fi
-
-
-# Check whether --with-readline or --without-readline was given.
-if test "${with_readline+set}" = set; then
- withval="$with_readline"
- echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6
-echo "configure:2137: checking for readline in -lreadline" >&5
-ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lreadline $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 2145 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char readline();
-
-int main() {
-readline()
-; return 0; }
-EOF
-if { (eval echo configure:2156: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<\EOF
-#define READLINE 1
-EOF
- LIBS="$LIBS -lreadline -ltermcap"
-else
- echo "$ac_t""no" 1>&6
-echo "configure: warning: readline library not found" 1>&2
-fi
-
-fi
-
-
-trap '' 1 2 15
-cat > confcache <<\EOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs. It is not useful on other systems.
-# If it contains results you don't want to keep, you may remove or edit it.
-#
-# By default, configure uses ./config.cache as the cache file,
-# creating it if it does not exist already. You can give configure
-# the --cache-file=FILE option to use a different cache file; that is
-# what configure does when it calls configure scripts in
-# subdirectories, so they share the cache.
-# Giving --cache-file=/dev/null disables caching, for debugging configure.
-# config.status only pays attention to the cache file if you give it the
-# --recheck option to rerun configure.
-#
-EOF
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-(set) 2>&1 |
- case `(ac_space=' '; set) 2>&1` in
- *ac_space=\ *)
- # `set' does not quote correctly, so add quotes (double-quote substitution
- # turns \\\\ into \\, and sed turns \\ into \).
- sed -n \
- -e "s/'/'\\\\''/g" \
- -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
- ;;
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
- ;;
- esac >> confcache
-if cmp -s $cache_file confcache; then
- :
-else
- if test -w $cache_file; then
- echo "updating cache $cache_file"
- cat confcache > $cache_file
- else
- echo "not updating unwritable cache $cache_file"
- fi
-fi
-rm -f confcache
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# Any assignment to VPATH causes Sun make to only execute
-# the first set of double-colon rules, so remove it if not needed.
-# If there is a colon in the path, we need to keep it.
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
-fi
-
-trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
-DEFS=-DHAVE_CONFIG_H
-
-# Without the "./", some shells look in PATH for config.status.
-: ${CONFIG_STATUS=./config.status}
-
-echo creating $CONFIG_STATUS
-rm -f $CONFIG_STATUS
-cat > $CONFIG_STATUS <<EOF
-#! /bin/sh
-# Generated automatically by configure.
-# Run this file to recreate the current configuration.
-# This directory was configured as follows,
-# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-#
-# $0 $ac_configure_args
-#
-# Compiler output produced by configure, useful for debugging
-# configure, is in ./config.log if it exists.
-
-ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-for ac_option
-do
- case "\$ac_option" in
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
- exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
- -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.12"
- exit 0 ;;
- -help | --help | --hel | --he | --h)
- echo "\$ac_cs_usage"; exit 0 ;;
- *) echo "\$ac_cs_usage"; exit 1 ;;
- esac
-done
-
-ac_given_srcdir=$srcdir
-ac_given_INSTALL="$INSTALL"
-
-trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-$ac_vpsub
-$extrasub
-s%@CFLAGS@%$CFLAGS%g
-s%@CPPFLAGS@%$CPPFLAGS%g
-s%@CXXFLAGS@%$CXXFLAGS%g
-s%@DEFS@%$DEFS%g
-s%@LDFLAGS@%$LDFLAGS%g
-s%@LIBS@%$LIBS%g
-s%@exec_prefix@%$exec_prefix%g
-s%@prefix@%$prefix%g
-s%@program_transform_name@%$program_transform_name%g
-s%@bindir@%$bindir%g
-s%@sbindir@%$sbindir%g
-s%@libexecdir@%$libexecdir%g
-s%@datadir@%$datadir%g
-s%@sysconfdir@%$sysconfdir%g
-s%@sharedstatedir@%$sharedstatedir%g
-s%@localstatedir@%$localstatedir%g
-s%@libdir@%$libdir%g
-s%@includedir@%$includedir%g
-s%@oldincludedir@%$oldincludedir%g
-s%@infodir@%$infodir%g
-s%@mandir@%$mandir%g
-s%@CC@%$CC%g
-s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
-s%@INSTALL_DATA@%$INSTALL_DATA%g
-s%@YACC@%$YACC%g
-s%@LN@%$LN%g
-s%@CPP@%$CPP%g
-s%@SIGNAL_H@%$SIGNAL_H%g
-s%@EXECVE@%$EXECVE%g
-s%@HISTORY@%$HISTORY%g
-s%@ADDON@%$ADDON%g
-
-CEOF
-EOF
-
-cat >> $CONFIG_STATUS <<\EOF
-
-# Split the substitutions into bite-sized pieces for seds with
-# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
-ac_file=1 # Number of current file.
-ac_beg=1 # First line for current file.
-ac_end=$ac_max_sed_cmds # Line after last line for current file.
-ac_more_lines=:
-ac_sed_cmds=""
-while $ac_more_lines; do
- if test $ac_beg -gt 1; then
- sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
- else
- sed "${ac_end}q" conftest.subs > conftest.s$ac_file
- fi
- if test ! -s conftest.s$ac_file; then
- ac_more_lines=false
- rm -f conftest.s$ac_file
- else
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds="sed -f conftest.s$ac_file"
- else
- ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
- fi
- ac_file=`expr $ac_file + 1`
- ac_beg=$ac_end
- ac_end=`expr $ac_end + $ac_max_sed_cmds`
- fi
-done
-if test -z "$ac_sed_cmds"; then
- ac_sed_cmds=cat
-fi
-EOF
-
-cat >> $CONFIG_STATUS <<EOF
-
-CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
-
- # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
-
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dir_suffix.
- ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
- else
- ac_dir_suffix= ac_dots=
- fi
-
- case "$ac_given_srcdir" in
- .) srcdir=.
- if test -z "$ac_dots"; then top_srcdir=.
- else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
- /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
- *) # Relative path.
- srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
- top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
-
- case "$ac_given_INSTALL" in
- [/$]*) INSTALL="$ac_given_INSTALL" ;;
- *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
- esac
-
- echo creating "$ac_file"
- rm -f "$ac_file"
- configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
- case "$ac_file" in
- *Makefile*) ac_comsub="1i\\
-# $configure_input" ;;
- *) ac_comsub= ;;
- esac
-
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- sed -e "$ac_comsub
-s%@configure_input@%$configure_input%g
-s%@srcdir@%$srcdir%g
-s%@top_srcdir@%$top_srcdir%g
-s%@INSTALL@%$INSTALL%g
-" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
-fi; done
-rm -f conftest.s*
-
-# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
-# NAME is the cpp macro being defined and VALUE is the value it is being given.
-#
-# ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
-ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
-ac_dC='\3'
-ac_dD='%g'
-# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
-ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_uB='\([ ]\)%\1#\2define\3'
-ac_uC=' '
-ac_uD='\4%g'
-# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_eB='$%\1#\2define\3'
-ac_eC=' '
-ac_eD='%g'
-
-if test "${CONFIG_HEADERS+set}" != set; then
-EOF
-cat >> $CONFIG_STATUS <<EOF
- CONFIG_HEADERS="config.h"
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-fi
-for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
- esac
-
- echo creating $ac_file
-
- rm -f conftest.frag conftest.in conftest.out
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- cat $ac_file_inputs > conftest.in
-
-EOF
-
-# Transform confdefs.h into a sed script conftest.vals that substitutes
-# the proper values into config.h.in to produce config.h. And first:
-# Protect against being on the right side of a sed subst in config.status.
-# Protect against being in an unquoted here document in config.status.
-rm -f conftest.vals
-cat > conftest.hdr <<\EOF
-s/[\\&%]/\\&/g
-s%[\\$`]%\\&%g
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
-s%ac_d%ac_u%gp
-s%ac_u%ac_e%gp
-EOF
-sed -n -f conftest.hdr confdefs.h > conftest.vals
-rm -f conftest.hdr
-
-# This sed command replaces #undef with comments. This is necessary, for
-# example, in the case of _POSIX_SOURCE, which is predefined and required
-# on some systems where configure will not decide to define it.
-cat >> conftest.vals <<\EOF
-s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
-EOF
-
-# Break up conftest.vals because some shells have a limit on
-# the size of here documents, and old seds have small limits too.
-
-rm -f conftest.tail
-while :
-do
- ac_lines=`grep -c . conftest.vals`
- # grep -c gives empty output for an empty file on some AIX systems.
- if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
- # Write a limited-size here document to conftest.frag.
- echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
- sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
- echo 'CEOF
- sed -f conftest.frag conftest.in > conftest.out
- rm -f conftest.in
- mv conftest.out conftest.in
-' >> $CONFIG_STATUS
- sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
- rm -f conftest.vals
- mv conftest.tail conftest.vals
-done
-rm -f conftest.vals
-
-cat >> $CONFIG_STATUS <<\EOF
- rm -f conftest.frag conftest.h
- echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
- cat conftest.in >> conftest.h
- rm -f conftest.in
- if cmp -s $ac_file conftest.h 2>/dev/null; then
- echo "$ac_file is unchanged"
- rm -f conftest.h
- else
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- fi
- rm -f $ac_file
- mv conftest.h $ac_file
- fi
-fi; done
-
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-
-exit 0
-EOF
-chmod +x $CONFIG_STATUS
-rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
-
diff --git a/configure.in b/configure.in
@@ -1,287 +0,0 @@
-AC_INIT(rc.h)
-
-AC_CONFIG_HEADER(config.h)
-
-AC_PROG_CC
-case "x$GCC" in
-xyes)
- CFLAGS="-Wall $CFLAGS"
- ;;
-esac
-
-AC_PROG_INSTALL
-AC_PROG_YACC
-AC_CHECK_PROGS(LN, ln cp)
-
-AC_CHECK_HEADERS(sys/resource.h sys/time.h sys/types.h unistd.h)
-AC_HEADER_DIRENT
-AC_HEADER_STDC
-
-dnl Linux puts real signal names in /usr/include/asm/signal.h.
-AC_CACHE_CHECK(for signal names in <sys/signal.h>, rc_cv_sys_signal_h,
- if grep SIGINT /usr/include/sys/signal.h >/dev/null 2>&1; then
- rc_cv_sys_signal_h=yes
- else
- rc_cv_sys_signal_h=no
- fi)
-
-case "x$rc_cv_sys_signal_h" in
-xyes)
- SIGNAL_H=/usr/include/sys/signal.h
- ;;
-xno)
- AC_CACHE_CHECK(for signal names in <asm/signal.h>, rc_cv_asm_signal_h,
- if grep SIGINT /usr/include/asm/signal.h >/dev/null 2>&1; then
- rc_cv_asm_signal_h=yes
- else
- rc_cv_asm_signal_h=no
- fi)
-
- case "x$rc_cv_asm_signal_h" in
- xyes)
- SIGNAL_H=/usr/include/asm/signal.h
- ;;
- xno)
- AC_MSG_ERROR(Can't find signal names in <sys/signal.h> or <asm/signal.h>)
- ;;
- esac
- ;;
-esac
-AC_SUBST(SIGNAL_H)
-
-AC_TYPE_GETGROUPS
-AC_TYPE_PID_T
-AC_TYPE_SIZE_T
-AC_TYPE_UID_T
-
-AC_CHECK_FUNCS(getgroups setpgrp setrlimit)
-
-AC_FUNC_SETPGRP
-
-dnl HPUX needs _KERNEL defined to pick up RLIMIT_foo defines. (Why?)
-AC_CACHE_CHECK(if _KERNEL is required for RLIMIT defines, rc_cv_kernel_rlimit,
- AC_TRY_COMPILE([
-#include <sys/types.h>
-#include <sys/resource.h>
- ], [
-int f;
-f = RLIMIT_DATA;
- ], rc_cv_kernel_rlimit=no, [ AC_TRY_COMPILE([
-#include <sys/types.h>
-#define _KERNEL
-#include <sys/resource.h>
-#undef _KERNEL
- ], [
-int f;
-f = RLIMIT_DATA;
- ], rc_cv_kernel_rlimit=yes, rc_cv_kernel_rlimit=no)]))
-case "x$rc_cv_kernel_rlimit" in
-xyes)
- AC_DEFINE(RLIMIT_NEEDS_KERNEL)
- ;;
-esac
-
-dnl Look for rlim_t in sys/types.h and sys/resource.h
-AC_CACHE_CHECK(for rlim_t, rc_cv_have_rlim_t,
- AC_EGREP_CPP(rlim_t, [
-#include <sys/types.h>
-#if RLIMIT_NEEDS_KERNEL
-#define _KERNEL
-#endif
-#include <sys/resource.h>
- ], rc_cv_have_rlim_t=yes, rc_cv_have_rlim_t=no))
-
-case "x$rc_cv_have_rlim_t" in
-xyes)
- AC_DEFINE(HAVE_RLIM_T)
- ;;
-xno)
- AC_CACHE_CHECK(for native quad_t, rc_cv_have_quad_t,
- AC_TRY_RUN([
-#include <sys/types.h>
-main() {
- quad_t q;
- q = 0;
- exit((int) q);
-}
- ], rc_cv_have_quad_t=yes, rc_cv_have_quad_t=no))
-
- case "x$rc_cv_have_quad_t" in
- xyes)
- AC_DEFINE(HAVE_QUAD_T)
-
- AC_CACHE_CHECK(if rlimit values are quad_t, rc_cv_rlim_t_is_quad_t,
- AC_TRY_RUN([
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#if RLIMIT_NEEDS_KERNEL
-#define _KERNEL
-#endif
-#include <sys/resource.h>
-#if RLIMIT_NEEDS_KERNEL
-#undef _KERNEL
-#endif
-main(){
- struct rlimit rl;
- exit(sizeof rl.rlim_cur != sizeof(quad_t));
-}
- ], rc_cv_rlim_t_is_quad_t=yes, rc_cv_rlim_t_is_quad_t=no, $ac_cv_type_quad_t))
-
- case "x$rc_cv_rlim_t_is_quad_t" in
- xyes)
- AC_DEFINE(RLIM_T_IS_QUAD_T)
- ;;
- esac
- ;;
- esac
- ;;
-esac
-
-AC_SYS_RESTARTABLE_SYSCALLS
-
-dnl Does the kernel handle `#! /interpreter'?
-AC_SYS_INTERPRETER
-case "x$ac_cv_sys_interpreter" in
-xyes)
- AC_DEFINE(HASH_BANG)
- EXECVE=''
- ;;
-xno)
- EXECVE=execve.o
-esac
-AC_SUBST(EXECVE)
-
-AC_CACHE_CHECK(for /dev/fd, rc_cv_sys_dev_fd,
- if test -d /dev/fd && test -r /dev/fd/0; then
- rc_cv_sys_dev_fd=yes
- elif test -d /proc/self/fd && test -r /proc/self/fd/0; then
- rc_cv_sys_dev_fd=odd
- else
- rc_cv_sys_dev_fd=no
- fi)
-
-case "x$rc_cv_sys_dev_fd" in
-xyes)
- AC_DEFINE(HAVE_DEV_FD)
- ;;
-xodd)
- AC_DEFINE(HAVE_PROC_SELF_FD)
- ;;
-xno)
- AC_CACHE_CHECK(for named pipes, rc_cv_sys_fifo,
- AC_DEFINE_UNQUOTED(TMPNAM, "/tmp/rc$$.0")
- AC_TRY_RUN([
-#include <sys/types.h>
-#include <sys/stat.h>
-
-main() {
- exit(mknod(TMPNAM, S_IFIFO | 0666, 0) != 0);
-}
- ], rc_cv_sys_fifo=yes, rc_cv_sys_fifo=no, rc_cv_sys_fifo=no))
- case "x$rc_cv_sys_fifo" in
- xyes)
- AC_DEFINE(HAVE_FIFO)
- ;;
- esac
-esac
-
-AC_ARG_ENABLE(builtin-echo, [ --disable-builtin-echo Don't include \`echo' as a builtin],
- test "x$enableval" != "xno" && AC_DEFINE(RC_ECHO),
- AC_DEFINE(RC_ECHO))
-
-AC_ARG_ENABLE(job, [ --disable-job Don't do job-control-style backgrounding],
- test "x$enableval" != "xno" && AC_DEFINE(RC_JOB),
- AC_DEFINE(RC_JOB))
-
-AC_ARG_ENABLE(protect-env, [ --disable-protect-env Don't protect environment names],
- test "x$enableval" != "xno" && AC_DEFINE(PROTECT_ENV),
- AC_DEFINE(PROTECT_ENV))
-
-AC_ARG_ENABLE(def-interp,
-[ --enable-def-interp=/bin/foo
- Use /bin/foo as default interpreter [/bin/sh]],
-[
- case "x$enableval" in
- xno)
- ;;
- xyes)
- AC_DEFINE(DEFAULTINTERP, "/bin/sh")
- ;;
- *)
- AC_DEFINE_UNQUOTED(DEFAULTINTERP, "$enableval")
- esac
-],
- AC_DEFINE(DEFAULTINTERP, "/bin/sh"))
-
-AC_ARG_ENABLE(def-path,
-[ --enable-def-path=\"/usr/local/bin/\",\"/usr/bin\"
- Default path [All of these that exist
- (/usr/local/bin /usr/bin /usr/ucb /bin .)]],
-[
- case "x$enableval" in
- xno|xyes)
- ;;
- *)
- AC_DEFINE_UNQUOTED(DEFAULTPATH, $enableval)
- esac
-],
- enable_def_path=yes)
-
-case "x$enable_def_path" in
-xyes)
- AC_CACHE_CHECK(extant directories for default path, rc_cv_def_path,[
- rc_cv_def_path=''
- for i in /usr/local/bin /usr/bin /usr/ucb /bin .; do
- if test -d $i; then
- case "x$rc_cv_def_path" in
- x)
- rc_cv_def_path=\"$i\"
- ;;
- *)
- rc_cv_def_path=$rc_cv_def_path,\"$i\"
- ;;
- esac
- fi
- done
- AC_DEFINE_UNQUOTED(DEFAULTPATH, $rc_cv_def_path)
- ])
- ;;
-esac
-
-AC_ARG_ENABLE(history, [ --enable-history Build history subprograms],
- test "x$enableval" != "xno" && rc_history=yes,
- rc_history=no)
-case "x$rc_history" in
-xyes)
- HISTORY=history/history
- ;;
-esac
-AC_SUBST(HISTORY)
-
-AC_ARG_WITH(addon, [ --with-addon Extra builtins, from addon.c ],[
- case "x$withval" in
- xyes)
- ADDON=addon.o
- ;;
- xno)
- ADDON=''
- ;;
- *)
- ADDON=$withval
- ;;
- esac
- ])
-AC_SUBST(ADDON)
-
-AC_ARG_WITH(editline, [ --with-editline Simmule Turner's line editing],
- AC_CHECK_LIB(edit, readline,
- AC_DEFINE(READLINE) LIBS="$LIBS -ledit",
- AC_MSG_WARN(editline library not found)))
-
-AC_ARG_WITH(readline, [ --with-readline Bloated GNU line editing],
- AC_CHECK_LIB(readline, readline,
- AC_DEFINE(READLINE) LIBS="$LIBS -lreadline -ltermcap",
- AC_MSG_WARN(readline library not found)))
-
-AC_OUTPUT(Makefile)
diff --git a/cpp b/cpp
@@ -1,38 +0,0 @@
-#!/bin/sh
-
-# @(#) cpp.sh 1.3 92/01/15 21:53:22
-
-# Unprototypeing preprocessor for pre-ANSI C compilers. On some systems,
-# this script can be as simple as:
-#
-# /lib/cpp "$@" | unproto
-#
-# However, some cc(1) drivers specify output file names on the
-# preprocessor command line, so this shell script must be prepared to
-# intercept them. Depending on the driver program, the cpp options may
-# even go before or after the file name argument(s). The script below
-# tries to tackle all these cases.
-#
-# You may want to add -Ipath_to_stdarg.h_file, -Dvoid=, -Dvolatile=,
-# and even -D__STDC__.
-
-## (This is what I used while testing with the SunOS C compiler.
-## Also, I added "-Qpath ." to CFLAGS so that cpp would be
-## run out of the current directory. --- Byron)
-cpp_args="-I/u/byron/lib/sun4 -Dconst= -Dvolatile="
-
-while :
-do
- case $1 in
- "") break;;
- -*) cpp_args="$cpp_args $1";;
- *) cpp_args="$cpp_args $1"
- case $2 in
- ""|-*) ;;
- *) exec 1> $2 || exit 1; shift;;
- esac;;
- esac
- shift
-done
-
-/lib/cpp $cpp_args | unproto
diff --git a/except.c b/except.c
@@ -1,140 +0,0 @@
-#include <setjmp.h>
-#include <signal.h>
-#include "rc.h"
-#include "jbwrap.h"
-
-/*
- A return goes back stack frames to the last return. A break does
- not. A signal goes to the last interactive level. (see below)
-*/
-
-bool nl_on_intr = TRUE;
-
-static Estack *estack;
-
-/* add an exception to the input stack. */
-
-extern void except(ecodes e, Edata data, Estack *ex) {
- ex->prev = estack;
- estack = ex;
- estack->e = e;
- estack->data = data;
- if (e == eError || e == eBreak || e == eReturn)
- estack->interactive = interactive;
-}
-
-/* remove an exception, restore last interactive value */
-
-extern void unexcept() {
- switch (estack->e) {
- default:
- break;
- case eError:
- interactive = estack->interactive;
- break;
- case eArena:
- restoreblock(estack->data.b);
- break;
- case eFifo:
- unlink(estack->data.name);
- break;
- case eFd:
- close(estack->data.fd);
- break;
- }
- estack = estack->prev;
-}
-
-/*
- Raise an exception. The rules are pretty complicated: you can return
- from a loop inside a function, but you can't break from a function
- inside of a loop. On errors, rc_raise() goes back to the LAST
- INTERACTIVE stack frame. If no such frame exists, then rc_raise()
- exits the shell. This is what happens, say, when there is a syntax
- error in a noninteractive shell script. While traversing the
- exception stack backwards, rc_raise() also removes input sources
- (closing file-descriptors, etc.) and pops instances of variables
- that have been pushed onto the variable stack (e.g., for a function
- call (for $*) or a local assignment).
-*/
-
-extern void rc_raise(ecodes e) {
- if (e == eError && rc_pid != getpid())
- exit(1); /* child processes exit on an error/signal */
- for (; estack != NULL; estack = estack->prev)
- if (estack->e != e) {
- if (e == eBreak && estack->e != eArena)
- rc_error("break outside of loop");
- else if (e == eReturn && estack->e == eError) /* can return from loops inside functions */
- rc_error("return outside of function");
- switch (estack->e) {
- default:
- break;
- case eVarstack:
- varrm(estack->data.name, TRUE);
- break;
- case eArena:
- restoreblock(estack->data.b);
- break;
- case eFifo:
- unlink(estack->data.name);
- break;
- case eFd:
- close(estack->data.fd);
- break;
- }
- } else {
- if (e == eError && !estack->interactive) {
- popinput();
- } else {
- Jbwrap *j = estack->data.jb;
-
- interactive = estack->interactive;
- estack = estack->prev;
- longjmp(j->j, 1);
- }
- }
- rc_exit(1); /* top of exception stack */
-}
-
-extern bool outstanding_cmdarg() {
- return estack->e == eFifo || estack->e == eFd;
-}
-
-extern void pop_cmdarg(bool remove) {
- for (; estack != NULL; estack = estack->prev)
- switch (estack->e) {
- case eFifo:
- if (remove)
- unlink(estack->data.name);
- break;
- case eFd:
- if (remove)
- close(estack->data.fd);
- break;
- default:
- return;
- }
-}
-
-/* exception handlers */
-
-extern void rc_error(char *s) {
- pr_error(s);
- set(FALSE);
- redirq = NULL;
- cond = FALSE; /* no longer inside conditional */
- rc_raise(eError);
-}
-
-extern void sigint(int s) {
- if (s != SIGINT)
- panic("s != SIGINT in sigint catcher");
- /* this is the newline you see when you hit ^C while typing a command */
- if (interactive && nl_on_intr)
- fprint(2, "\n");
- nl_on_intr = TRUE;
- redirq = NULL;
- cond = FALSE;
- rc_raise(eError);
-}
diff --git a/exec.c b/exec.c
@@ -1,132 +0,0 @@
-/* exec.c */
-#include <signal.h>
-#include <errno.h>
-#include <setjmp.h>
-#include "rc.h"
-#include "jbwrap.h"
-
-/*
- Takes an argument list and does the appropriate thing (calls a
- builtin, calls a function, etc.)
-*/
-
-extern void exec(List *s, bool parent) {
- char **av, **ev = NULL;
- int stat;
- pid_t pid;
- builtin_t *b;
- char *path = NULL;
- bool didfork, returning, saw_exec, saw_builtin;
- av = list2array(s, dashex);
- saw_builtin = saw_exec = FALSE;
- do {
- if (*av == NULL || isabsolute(*av))
- b = NULL;
- else if (!saw_builtin && fnlookup(*av) != NULL)
- b = funcall;
- else
- b = isbuiltin(*av);
-
- /*
- a builtin applies only to the immmediately following
- command, e.g., builtin exec echo hi
- */
- saw_builtin = FALSE;
-
- if (b == b_exec) {
- av++;
- saw_exec = TRUE;
- parent = FALSE;
- } else if (b == b_builtin) {
- av++;
- saw_builtin = TRUE;
- }
- } while (b == b_exec || b == b_builtin);
- if (*av == NULL && saw_exec) { /* do redirs and return on a null exec */
- doredirs();
- return;
- }
- /* force an exit on exec with any rc_error, but not for null commands as above */
- if (saw_exec)
- rc_pid = -1;
- if (b == NULL) {
- path = which(*av, TRUE);
- if (path == NULL && *av != NULL) { /* perform null commands for redirections */
- set(FALSE);
- redirq = NULL;
- if (parent)
- return;
- rc_exit(1);
- }
- ev = makeenv(); /* environment only needs to be built for execve() */
- }
- /*
- If parent & the redirq is nonnull, builtin or not it has to fork.
- If the fifoq is nonnull, then it must be emptied at the end so we
- must fork no matter what.
- */
- if ((parent && (b == NULL || redirq != NULL)) || outstanding_cmdarg()) {
- pid = rc_fork();
- didfork = TRUE;
- } else {
- pid = 0;
- didfork = FALSE;
- }
- returning = (!didfork && parent);
- switch (pid) {
- case -1:
- uerror("fork");
- rc_error(NULL);
- /* NOTREACHED */
- case 0:
- if (!returning)
- setsigdefaults(FALSE);
- pop_cmdarg(FALSE);
- doredirs();
-
- /* null commands performed for redirections */
- if (*av == NULL || b != NULL) {
- if (b != NULL)
- (*b)(av);
- if (returning)
- return;
- rc_exit(getstatus());
- }
-#if HASH_BANG
- execve(path, (char * const *) av, (char * const *) ev);
-#else
- my_execve(path, (char * const *) av, (char * const *) ev); /* bogus, huh? */
-#endif
-
-#ifdef DEFAULTINTERP
- if (errno == ENOEXEC) {
- *av = path;
- *--av = DEFAULTINTERP;
- execve(*av, (char * const *) av, (char * const *) ev);
- }
-#endif
- uerror(*av);
- rc_exit(1);
- /* NOTREACHED */
- default:
- redirq = NULL;
- rc_wait4(pid, &stat, TRUE);
- setstatus(-1, stat);
- /*
- There is a very good reason for having this weird
- nl_on_intr variable: when rc and its child both
- process a SIGINT, (i.e., the child has a SIGINT
- catcher installed) then you don't want rc to print
- a newline when the child finally exits. Here's an
- example: ed, <type ^C>, <type "q">. rc does not
- and should not print a newline before the next
- prompt, even though there's a SIGINT in its signal
- vector.
- */
- if ((stat & 0xff) == 0)
- nl_on_intr = FALSE;
- sigchk();
- nl_on_intr = TRUE;
- pop_cmdarg(TRUE);
- }
-}
diff --git a/execve.c b/execve.c
@@ -1,61 +0,0 @@
-/* execve.c: an execve() for geriatric unices without #! */
-
-/*
- NOTE: this file depends on a hack in footobar.c which places two free spots before
- av[][] so that execve does not have to call malloc.
-*/
-
-#include <errno.h>
-#include "rc.h"
-
-#define giveupif(x) { if (x) goto fail; }
-
-extern int my_execve(const char *path, const char **av, const char **ev) {
- int fd, len, fst, snd, end;
- bool noarg;
- char pb[256]; /* arbitrary but generous limit */
- execve(path, av, ev);
- if (errno != ENOEXEC)
- return -1;
- fd = rc_open(path, rFrom);
- giveupif(fd < 0);
- len = read(fd, pb, sizeof pb);
- close(fd);
- /* reject scripts which don't begin with #! */
- giveupif(len <= 0 || pb[0] != '#' || pb[1] != '!');
- for (fst = 2; fst < len && (pb[fst] == ' ' || pb[fst] == '\t'); fst++)
- ; /* skip leading whitespace */
- giveupif(fst == len);
- for (snd = fst; snd < len && pb[snd] != ' ' && pb[snd] != '\t' && pb[snd] != '\n'; snd++)
- ; /* skip first arg */
- giveupif(snd == len);
- noarg = (pb[snd] == '\n');
- pb[snd++] = '\0'; /* null terminate the first arg */
- if (!noarg) {
- while (snd < len && (pb[snd] == ' ' || pb[snd] == '\t'))
- snd++; /* skip whitespace to second arg */
- giveupif(snd == len);
- noarg = (pb[snd] == '\n'); /* could have trailing whitespace after only one arg */
- if (!noarg) {
- for (end = snd; end < len && pb[end] != ' ' && pb[end] != '\t' && pb[end] != '\n'; end++)
- ; /* skip to the end of the second arg */
- giveupif(end == len);
- if (pb[end] == '\n') {
- pb[end] = '\0'; /* null terminate the first arg */
- } else { /* else check for a spurious third arg */
- pb[end++] = '\0';
- while (end < len && (pb[end] == ' ' || pb[end] == '\t'))
- end++;
- giveupif(end == len || pb[end] != '\n');
- }
- }
- }
- *av = path;
- if (!noarg)
- *--av = pb + snd;
- *--av = pb + fst;
- execve(*av, av, ev);
- return -1;
-fail: errno = ENOEXEC;
- return -1;
-}
diff --git a/fn.c b/fn.c
@@ -1,257 +0,0 @@
-/*
- fn.c: functions for adding and deleting functions from the symbol table.
- Support for signal handlers is also found here.
-*/
-
-#include <signal.h>
-#include <errno.h>
-#include "rc.h"
-#include "sigmsgs.h"
-
-static void fn_handler(int), dud_handler(int);
-
-static bool runexit = FALSE;
-static Node *handlers[NUMOFSIGNALS], null;
-static void (*def_sigint)(int) = SIG_DFL;
-static void (*def_sigquit)(int) = SIG_DFL;
-static void (*def_sigterm)(int) = SIG_DFL;
-
-/*
- Set signals to default values for rc. This means that interactive
- shells ignore SIGTERM, etc.
-*/
-
-extern void inithandler() {
- int i;
- null.type = nBody;
- null.u[0].p = null.u[1].p = NULL;
- for (i = 1; i < NUMOFSIGNALS; i++)
-#ifndef HAVE_RESTARTABLE_SYSCALLS
- if (i != SIGCLD)
-#endif
- if (sighandlers[i] == SIG_IGN)
- fnassign(signals[i].name, NULL); /* ignore incoming ignored signals */
- if (interactive || sighandlers[SIGINT] != SIG_IGN) {
- def_sigint = sigint;
- fnrm("sigint"); /* installs SIGINT catcher if not inherited ignored */
- }
- if (!dashdee) {
- if (interactive || sighandlers[SIGQUIT] != SIG_IGN) {
- def_sigquit = dud_handler;
- fnrm("sigquit"); /* "ignores" SIGQUIT unless inherited ignored */
- }
- if (interactive) {
- def_sigterm = dud_handler;
- fnrm("sigterm"); /* ditto for SIGTERM */
- }
- }
-}
-
-/* only run this in a child process! resets signals to their default values */
-
-extern void setsigdefaults(bool sysvbackground) {
- int i;
- /*
- General housekeeping: setsigdefaults happens after fork(),
- so it's a convenient place to clean up open file descriptors.
- (history file, scripts, etc.)
- */
- closefds();
- /*
- Restore signals to SIG_DFL, paying close attention to
- a few quirks: SIGINT, SIGQUIT and are treated specially
- depending on whether we are doing v7-style backgrounding
- or not; the default action for SIGINT, SIGQUIT and SIGTERM
- must be set to the appropriate action; finally, care must
- be taken not to set to SIG_DFL any signals which are being
- ignored.
- */
- for (i = 1; i < NUMOFSIGNALS; i++)
- if (sighandlers[i] != SIG_IGN) {
- handlers[i] = NULL;
- switch (i) {
- case SIGINT:
- if (sysvbackground) {
- def_sigint = SIG_IGN;
- fnassign("sigint", NULL); /* ignore */
- } else {
- def_sigint = SIG_DFL;
- goto sigcommon;
- }
- break;
- case SIGQUIT:
- if (sysvbackground) {
- def_sigquit = SIG_IGN;
- fnassign("sigquit", NULL); /* ignore */
- } else {
- def_sigquit = SIG_DFL;
- goto sigcommon;
- }
- break;
- case SIGTERM:
- def_sigterm = SIG_DFL;
- /* FALLTHROUGH */
- sigcommon:
- default:
- if (sighandlers[i] != SIG_DFL) {
- rc_signal(i, SIG_DFL);
- delete_fn(signals[i].name);
- }
- }
- }
- delete_fn("sigexit");
- runexit = FALSE; /* No sigexit on subshells */
-}
-
-/* rc's exit. if runexit is set, run the sigexit function. */
-
-extern void rc_exit(int stat) {
- if (runexit) {
- char *sig[2];
- sig[0] = "sigexit";
- sig[1] = NULL;
- runexit = FALSE;
- funcall(sig);
- stat = getstatus();
- }
- exit(stat);
-}
-
-/* The signal handler for all functions. calls walk() */
-
-static void fn_handler(int s) {
- char *sig[2];
- int olderrno;
- if (s < 1 || s >= NUMOFSIGNALS)
- panic("unknown signal");
- olderrno = errno;
- sig[0] = signals[s].name;
- sig[1] = NULL;
- funcall(sig);
- errno = olderrno;
-}
-
-/* A dud signal handler for SIGQUIT and SIGTERM */
-
-static void dud_handler(int s) {
-}
-
-/*
- Assign a function in Node form. Check to see if the function is also
- a signal, and set the signal vectors appropriately.
-*/
-
-extern void fnassign(char *name, Node *def) {
- Node *newdef = treecpy(def == NULL ? &null : def, ealloc); /* important to do the treecopy first */
- Function *new = get_fn_place(name);
- int i;
- new->def = newdef;
- new->extdef = NULL;
- if (strncmp(name, "sig", conststrlen("sig")) == 0) { /* slight optimization */
-#ifndef HAVE_RESTARTABLE_SYSCALLS /* System V machines treat SIGCLD very specially */
- if (streq(name, "sigcld"))
- rc_error("can't trap SIGCLD");
-#endif
- if (streq(name, "sigexit"))
- runexit = TRUE;
- for (i = 1; i < NUMOFSIGNALS; i++) /* zero is a bogus signal */
- if (streq(signals[i].name, name)) {
- handlers[i] = newdef;
- if (def == NULL)
- rc_signal(i, SIG_IGN);
- else
- rc_signal(i, fn_handler);
- break;
- }
- }
-}
-
-/* Assign a function from the environment. Store just the external representation */
-
-extern void fnassign_string(char *extdef) {
- char *name = get_name(extdef+3); /* +3 to skip over "fn_" */
- Function *new;
- if (name == NULL)
- return;
- new = get_fn_place(name);
- new->def = NULL;
- new->extdef = ecpy(extdef);
-}
-
-/* Return a function in Node form, evaluating an entry from the environment if necessary */
-
-extern Node *fnlookup(char *name) {
- Function *look = lookup_fn(name);
- Node *ret;
- if (look == NULL)
- return NULL; /* not found */
- if (look->def != NULL)
- return look->def;
- if (look->extdef == NULL) /* function was set to null, e.g., fn foo {} */
- return &null;
- ret = parse_fn(name, look->extdef);
- if (ret == NULL) {
- efree(look->extdef);
- look->extdef = NULL;
- return &null;
- } else {
- return look->def = treecpy(ret, ealloc); /* Need to take it out of nalloc space */
- }
-}
-
-/* Return a function in string form (used by makeenv) */
-
-extern char *fnlookup_string(char *name) {
- Function *look = lookup_fn(name);
-
- if (look == NULL)
- return NULL;
- if (look->extdef != NULL)
- return look->extdef;
- return look->extdef = mprint("fn_%F={%T}", name, look->def);
-}
-
-/*
- Remove a function from the symbol table. If it also defines a signal
- handler, restore the signal handler to its default value.
-*/
-
-extern void fnrm(char *name) {
- int i;
- for (i = 1; i < NUMOFSIGNALS; i++)
- if (streq(signals[i].name, name)) {
- handlers[i] = NULL;
- switch (i) {
- case SIGINT:
- rc_signal(i, def_sigint);
- break;
- case SIGQUIT:
- rc_signal(i, def_sigquit);
- break;
- case SIGTERM:
- rc_signal(i, def_sigterm);
- break;
- default:
- rc_signal(i, SIG_DFL);
- }
- }
- if (streq(name, "sigexit"))
- runexit = FALSE;
- delete_fn(name);
-}
-
-extern void whatare_all_signals() {
- int i;
- for (i = 1; i < NUMOFSIGNALS; i++)
- if (*signals[i].name != '\0')
- if (sighandlers[i] == SIG_IGN)
- fprint(1, "fn %s {}\n", signals[i].name);
- else if (sighandlers[i] == fn_handler)
- fprint(1, "fn %S {%T}\n", signals[i].name, handlers[i]);
- else
- fprint(1, "fn %s\n", signals[i].name);
-}
-
-extern void prettyprint_fn(int fd, char *name, Node *n) {
- fprint(fd, "fn %S {%T}\n", name, n);
-}
diff --git a/footobar.c b/footobar.c
@@ -1,337 +0,0 @@
-/*
- footobar.c: a collection of functions to convert internal representations of
- variables and functions to external representations, and vice versa
-*/
-
-#include "rc.h"
-
-/* protect an exported name from brain-dead shells */
-
-#if PROTECT_ENV
-static bool Fconv(Format *f, int ignore) {
- unsigned const char *s = va_arg(f->args, unsigned const char *);
- int c;
-
- while ((c = *s++) != '\0')
- if (dnw[c] || c == '*' || (c == '_' && *s == '_'))
- fmtprint(f, "__%02x", c);
- else
- fmtputc(f, c);
- return FALSE;
-}
-#endif
-
-/* convert a redirection to a printable form */
-
-static bool Dconv(Format *f, int ignore) {
- const char *name = "?";
- int n = va_arg(f->args, int);
- switch (n) {
- case rCreate: name = ">"; break;
- case rAppend: name = ">>"; break;
- case rFrom: name = "<"; break;
- case rHeredoc: name = "<<"; break;
- case rHerestring: name = "<<<"; break;
- }
- fmtcat(f, name);
- return FALSE;
-}
-
-/* defaultfd -- return the default fd for a given redirection operation */
-
-extern int defaultfd(int op) {
- return (op == rCreate || op == rAppend) ? 1 : 0;
-}
-
-/* convert a function in Node * form into something rc can parse (and humans can read?) */
-
-static bool Tconv(Format *f, int ignore) {
- Node *n = va_arg(f->args, Node *);
- if (n == NULL) {
- fmtprint(f, "()");
- return FALSE;
- }
- switch (n->type) {
- case nWord: fmtprint(f, "%S", n->u[0].s); break;
- case nQword: fmtprint(f, "%#S", n->u[0].s); break;
- case nBang: fmtprint(f, "!%T", n->u[0].p); break;
- case nCase: fmtprint(f, "case %T", n->u[0].p); break;
- case nNowait: fmtprint(f, "%T&", n->u[0].p); break;
- case nRmfn: fmtprint(f, "fn %T", n->u[0].p); break;
- case nSubshell: fmtprint(f, "@ %T", n->u[0].p); break;
- case nAndalso: fmtprint(f, "%T&&%T", n->u[0].p, n->u[1].p); break;
- case nAssign: fmtprint(f, "%T=%T", n->u[0].p, n->u[1].p); break;
- case nConcat: fmtprint(f, "%T^%T", n->u[0].p, n->u[1].p); break;
- case nElse: fmtprint(f, "{%T}else %T", n->u[0].p, n->u[1].p); break;
- case nNewfn: fmtprint(f, "fn %T {%T}", n->u[0].p, n->u[1].p); break;
- case nIf: fmtprint(f, "if(%T)%T", n->u[0].p, n->u[1].p); break;
- case nOrelse: fmtprint(f, "%T||%T", n->u[0].p, n->u[1].p); break;
- case nArgs: fmtprint(f, "%T %T", n->u[0].p, n->u[1].p); break;
- case nSwitch: fmtprint(f, "switch(%T){%T}", n->u[0].p, n->u[1].p); break;
- case nMatch: fmtprint(f, "~ %T %T", n->u[0].p, n->u[1].p); break;
- case nWhile: fmtprint(f, "while(%T)%T", n->u[0].p, n->u[1].p); break;
- case nLappend: fmtprint(f, "(%T %T)", n->u[0].p, n->u[1].p); break;
- case nForin: fmtprint(f, "for(%T in %T)%T", n->u[0].p, n->u[1].p, n->u[2].p); break;
- case nVarsub: fmtprint(f, "$%T(%T)", n->u[0].p, n->u[1].p); break;
- case nCount: case nFlat: case nVar: {
- char *lp = "", *rp = "";
- Node *n0 = n->u[0].p;
-
- if (n0->type != nWord && n0->type != nQword)
- lp = "(", rp = ")";
-
- switch (n->type) {
- default: panic("this can't happen"); break;
- case nCount: fmtprint(f, "$#%s%T%s", lp, n0, rp); break;
- case nFlat: fmtprint(f, "$^%s%T%s", lp, n0, rp); break;
- case nVar: fmtprint(f, "$%s%T%s", lp, n0, rp); break;
- }
- break;
- }
- case nDup:
- if (n->u[2].i != -1)
- fmtprint(f, "%D[%d=%d]", n->u[0].i, n->u[1].i, n->u[2].i);
- else
- fmtprint(f, "%D[%d=]", n->u[0].i, n->u[1].i);
- break;
- case nBackq: {
- Node *n0 = n->u[0].p, *n00;
- if (n0 != NULL && n0->type == nVar
- && (n00 = n0->u[0].p) != NULL && n00->type == nWord && streq(n00->u[0].s, "ifs"))
- fmtprint(f, "`");
- else
- fmtprint(f, "``%T", n0);
- fmtprint(f, "{%T}", n->u[1].p);
- break;
- }
- case nCbody:
- case nBody: {
- Node *n0 = n->u[0].p;
- if (n0 != NULL)
- fmtprint(f, "%T", n->u[0].p);
- if (n->u[1].p != NULL) {
- if (n0 != NULL && n0->type != nNowait)
- fmtprint(f, ";");
- fmtprint(f, "%T", n->u[1].p);
- }
- break;
- }
- case nBrace:
- fmtprint(f, "{%T}", n->u[0].p);
- if (n->u[1].p != NULL)
- fmtprint(f, "%T", n->u[1].p);
- break;
- case nEpilog:
- case nPre:
- fmtprint(f, "%T", n->u[0].p);
- if (n->u[1].p != NULL)
- fmtprint(f, " %T", n->u[1].p);
- break;
- case nPipe: {
- int ofd = n->u[0].i, ifd = n->u[1].i;
- fmtprint(f, "%T|", n->u[2].p);
- if (ifd != 0)
- fmtprint(f, "[%d=%d]", ofd, ifd);
- else if (ofd != 1)
- fmtprint(f, "[%d]", ofd);
- fmtprint(f, "%T", n->u[3].p);
- break;
- }
- case nRedir: {
- int op = n->u[0].i;
- fmtprint(f, "%D", op);
- if (n->u[1].i != defaultfd(op))
- fmtprint(f, "[%d]", n->u[1].i);
- fmtprint(f, "%T", n->u[2].p);
- break;
- }
- case nNmpipe: {
- int op = n->u[0].i;
- fmtprint(f, "%D", op);
- if (n->u[1].i != defaultfd(op))
- fmtprint(f, "[%d]", n->u[1].i);
- fmtprint(f, "{%T}", n->u[2].p);
- break;
- }
- }
- return FALSE;
-}
-
-/* convert a List to an array, for execve() */
-
-extern char **list2array(List *s, bool print) {
- char **argv, **av;
-
- if (print)
- fprint(2, "%L\n", s, " ");
- /*
- Allocate 3 extra spots (2 for the fake execve & 1 for defaulting to
- sh) and hide these from exec().
- */
- argv = av = (char **) nalloc((listnel(s) + 4) * sizeof *av) + 3;
- while (s != NULL) {
- *av++ = s->w;
- s = s->n;
- }
- *av = NULL;
- return argv;
-}
-
-/* figure out the name of a variable given an environment string. */
-
-extern char *get_name(char *s) {
- char *eq = strchr(s, '=');
- char *r, *result;
- int c;
-
- if (eq == NULL)
- return NULL;
- r = result = nalloc(eq - s + 1);
- while (1)
- switch (c = *s++) {
- case '=':
- *r++ = '\0';
- return result;
-#if PROTECT_ENV
- case '_':
- if (*s == '_') {
- static const char hexchar[] = "0123456789abcdef";
- char *h1 = strchr(hexchar, s[1]);
- char *h2 = strchr(hexchar, s[2]);
- if (h1 != NULL && h2 != NULL) {
- *r++ = ((h1 - hexchar) << 4) | (h2 - hexchar);
- s += 3;
- break;
- }
- }
- /* FALLTHROUGH */
-#endif
- default:
- *r++ = c;
- break;
- }
-}
-
-/*
- Hacky routine to split a ^A-separated environment variable. Scans
- backwards. Be VERY CAREFUL with the loop boundary conditions. e.g.,
- notice what happens when there is no ^A in the extdef. (It does
- the right thing, of course :-)
-*/
-
-#define skipleft(p) do --p; while (*p != '\0' && *p != '\001');
-
-extern List *parse_var(char *name, char *extdef) {
- char *endp, *realend, *sepp;
- List *tailp, *new;
-
- extdef = strchr(extdef, '=');
- *extdef++ = '\0'; /* null "initiate" the string for rtol scanning */
-
- sepp = realend = strchr(extdef, '\0');
- tailp = NULL;
-
- while (1) {
- endp = sepp; /* set endp to end of current mebmer */
- skipleft(sepp); /* advance sepp to the previous \1, */
- *endp = '\0'; /* and null terminate the member. */
-
- new = enew(List);
- new->w = ecpy(sepp+1);
- new->m = NULL;
- new->n = tailp;
- tailp = new;
-
- if (sepp < extdef) /* break when sepp hits the null "initiator" */
- break;
- if (endp != realend) /* else restore the \1 in between members */
- *endp = '\001';
- }
- if (endp != realend)
- *endp = '\001';
- *--extdef = '='; /* restore extdef '=' */
- return tailp;
-}
-
-/* get an environment entry for a function and have rc parse it. */
-
-#define PREFIX "fn x"
-#define PRELEN conststrlen(PREFIX)
-extern Node *parse_fn(char *name, char *extdef) {
- Node *def;
- char *s, old[PRELEN];
- if ((s = strchr(extdef, '=')) == NULL)
- return NULL;
- memcpy(old, s -= (PRELEN-1), PRELEN);
- memcpy(s, PREFIX, PRELEN);
- def = parseline(s);
- memcpy(s, old, PRELEN);
- return (def == NULL || def->type != nNewfn) ? NULL : def->u[1].p;
-}
-
-static bool Aconv(Format *f, int c) {
- char **a = va_arg(f->args, char **);
- if (*a != NULL) {
- fmtcat(f, *a);
- while (*++a != NULL)
- fmtprint(f, " %s", *a);
- }
- return FALSE;
-}
-
-static bool Lconv(Format *f, int c) {
- List *l = va_arg(f->args, List *);
- char *sep = va_arg(f->args, char *);
- char *fmt = (f->flags & FMT_leftside) ? "%s%s" : "%-S%s";
- if (l == NULL && (f->flags & FMT_leftside) == 0)
- fmtprint(f, "()");
- else {
- List *s;
- for (s = l; s != NULL; s = s->n)
- fmtprint(f, fmt, s->w, s->n == NULL ? "" : sep);
- }
- return FALSE;
-}
-
-#define ISMETA(c) (c == '*' || c == '?' || c == '[')
-
-static bool Sconv(Format *f, int ignore) {
- int c;
- unsigned char *s = va_arg(f->args, unsigned char *), *t = s;
- bool quoted = (f->flags & FMT_altform) != 0; /* '#' */
- bool metaquote = (f->flags & FMT_leftside) != 0; /* '-' */
- if (*s == '\0') {
- fmtprint(f, "''");
- return FALSE;
- }
- if (!quoted) {
- while ((c = *t++) != '\0')
- if (nw[c] == 1 || (metaquote && ISMETA(c)))
- goto quoteit;
- fmtprint(f, "%s", s);
- return FALSE;
- }
-quoteit:
- fmtputc(f, '\'');
- while ((c = *s++) != '\0') {
- fmtputc(f, c);
- if (c == '\'')
- fmtputc(f, '\'');
-
- }
- fmtputc(f, '\'');
- return FALSE;
-}
-
-void initprint(void) {
- fmtinstall('A', Aconv);
- fmtinstall('L', Lconv);
- fmtinstall('S', Sconv);
- fmtinstall('T', Tconv);
- fmtinstall('D', Dconv);
-#if PROTECT_ENV
- fmtinstall('F', Fconv);
-#else
- fmtinstall('F', fmtinstall('s', NULL));
-#endif
-}
diff --git a/getopt.c b/getopt.c
@@ -1,50 +0,0 @@
-#include "rc.h"
-
-int rc_opterr = 1;
-int rc_optind = 1;
-int rc_optopt;
-char *rc_optarg;
-
-/* getopt routine courtesy of David Sanderson */
-
-extern int rc_getopt(int argc, char **argv, char *opts) {
- static int sp = 1;
- int c;
- char *cp;
- if (rc_optind == 0) /* reset rc_getopt() */
- rc_optind = sp = 1;
- if (sp == 1)
- if (rc_optind >= argc || argv[rc_optind][0] != '-' || argv[rc_optind][1] == '\0') {
- return -1;
- } else if (strcmp(argv[rc_optind], "--") == 0) {
- rc_optind++;
- return -1;
- }
- rc_optopt = c = argv[rc_optind][sp];
- if (c == ':' || (cp=strchr(opts, c)) == 0) {
- fprint(2, "%s: bad option: -%c\n", argv[0], c);
- if (argv[rc_optind][++sp] == '\0') {
- rc_optind++;
- sp = 1;
- }
- return '?';
- }
- if (*++cp == ':') {
- if (argv[rc_optind][sp+1] != '\0') {
- rc_optarg = &argv[rc_optind++][sp+1];
- } else if (++rc_optind >= argc) {
- fprint(2, "%s: option requires an argument -- %c\n", argv[0], c);
- sp = 1;
- return '?';
- } else
- rc_optarg = argv[rc_optind++];
- sp = 1;
- } else {
- if (argv[rc_optind][++sp] == '\0') {
- sp = 1;
- rc_optind++;
- }
- rc_optarg = NULL;
- }
- return c;
-}
diff --git a/glob.c b/glob.c
@@ -1,278 +0,0 @@
-/* glob.c: rc's (ugly) globber. This code is not elegant, but it works */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "rc.h"
-
-/* Lifted from autoconf documentation.*/
-#if HAVE_DIRENT_H
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# endif
-# if HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# endif
-# if HAVE_NDIR_H
-# include <ndir.h>
-# endif
-#endif
-
-static List *dmatch(char *, char *, char *);
-static List *doglob(char *, char *);
-static List *lglob(List *, char *, char *, size_t);
-static List *sort(List *);
-
-/*
- Matches a list of words s against a list of patterns p. Returns true iff
- a pattern in p matches a word in s. () matches (), but otherwise null
- patterns match nothing.
-*/
-
-extern bool lmatch(List *s, List *p) {
- List *q;
- int i;
- bool okay;
- if (s == NULL) {
- if (p == NULL) /* null matches null */
- return TRUE;
- for (; p != NULL; p = p->n) { /* one or more stars match null */
- if (*p->w != '\0') { /* the null string is a special case; it does *not* match () */
- okay = TRUE;
- for (i = 0; p->w[i] != '\0'; i++)
- if (p->w[i] != '*' || p->m[i] != 1) {
- okay = FALSE;
- break;
- }
- if (okay)
- return TRUE;
- }
- }
- return FALSE;
- }
- for (; s != NULL; s = s->n)
- for (q = p; q != NULL; q = q->n)
- if (match(q->w, q->m, s->w))
- return TRUE;
- return FALSE;
-}
-
-/*
- Globs a list; checks to see if each element in the list has a metacharacter. If it
- does, it is globbed, and the output is sorted.
-*/
-
-extern List *glob(List *s) {
- List *top, *r;
- bool meta;
- for (r = s, meta = FALSE; r != NULL; r = r->n)
- if (r->m != NULL)
- meta = TRUE;
- if (!meta)
- return s; /* don't copy lists with no metacharacters in them */
- for (top = r = NULL; s != NULL; s = s->n) {
- if (s->m == NULL) { /* no metacharacters; just tack on to the return list */
- if (top == NULL)
- top = r = nnew(List);
- else
- r = r->n = nnew(List);
- r->w = s->w;
- } else {
- if (top == NULL)
- top = r = sort(doglob(s->w, s->m));
- else
- r->n = sort(doglob(s->w, s->m));
- while (r->n != NULL)
- r = r->n;
- }
- }
- r->n = NULL;
- return top;
-}
-
-/* Matches a pattern p against the contents of directory d */
-
-static List *dmatch(char *d, char *p, char *m) {
- bool matched = FALSE;
- List *top, *r;
- static DIR *dirp;
- static struct dirent *dp;
- static struct stat s;
- int i;
-
- /*
- return a match if there are no metacharacters; allows globbing through
- directories with no read permission. make sure the file exists, though.
- */
- matched = TRUE;
- if (m != NULL)
- for (i = 0; p[i] != '\0'; i++)
- if (m[i]) {
- matched = FALSE;
- break;
- }
-
- if (matched) {
- char *path = nprint("%s/%s", d, p);
- if (stat(path, &s) < 0)
- return NULL;
- r = nnew(List);
- r->w = ncpy(p);
- r->m = NULL;
- r->n = NULL;
- return r;
- }
-
- top = r = NULL;
- if ((dirp = opendir(d)) == NULL)
- return NULL;
- /* opendir succeeds on regular files on some systems, so the stat() call is necessary (sigh) */
- if (stat(d, &s) < 0 || (s.st_mode & S_IFMT) != S_IFDIR) {
- closedir(dirp);
- return NULL;
- }
- while ((dp = readdir(dirp)) != NULL)
- if ((*dp->d_name != '.' || *p == '.') && match(p, m, dp->d_name)) { /* match ^. explicitly */
- matched = TRUE;
- if (top == NULL)
- top = r = nnew(List);
- else
- r = r->n = nnew(List);
- r->w = ncpy(dp->d_name);
- r->m = NULL;
- }
- closedir(dirp);
- if (!matched)
- return NULL;
- r->n = NULL;
- return top;
-}
-
-/*
- lglob() globs a pattern agains a list of directory roots. e.g., (/tmp /usr /bin) "*"
- will return a list with all the files in /tmp, /usr, and /bin. NULL on no match.
- slashcount indicates the number of slashes to stick between the directory and the
- matched name. e.g., for matching ////tmp/////foo*
-*/
-
-static List *lglob(List *s, char *p, char *m, size_t slashcount) {
- List *q, *r, *top, foo;
- static struct {
- List l;
- size_t size;
- } slash;
- if (slashcount+1 > slash.size) {
- slash.size = 2*(slashcount+1);
- slash.l.w = erealloc(slash.l.w, slash.size);
- }
- slash.l.w[slashcount] = '\0';
- while (slashcount > 0)
- slash.l.w[--slashcount] = '/';
- for (top = r = NULL; s != NULL; s = s->n) {
- q = dmatch(s->w, p, m);
- if (q != NULL) {
- foo.w = s->w;
- foo.m = NULL;
- foo.n = NULL;
- if (!(s->w[0] == '/' && s->w[1] == '\0')) /* need to separate */
- q = concat(&slash.l, q); /* dir/name with slash */
- q = concat(&foo, q);
- if (r == NULL)
- top = r = q;
- else
- r->n = q;
- while (r->n != NULL)
- r = r->n;
- }
- }
- return top;
-}
-
-/*
- Doglob globs a pathname in pattern form against a unix path. Returns the original
- pattern (cleaned of metacharacters) on failure, or the globbed string(s).
-*/
-
-static List *doglob(char *w, char *m) {
- static char *dir = NULL, *pattern = NULL, *metadir = NULL, *metapattern = NULL;
- static size_t dsize = 0;
- char *d, *p, *md, *mp;
- size_t psize;
- char *s = w;
- List firstdir;
- List *matched;
- if ((psize = strlen(w) + 1) > dsize || dir == NULL) {
- efree(dir); efree(pattern); efree(metadir); efree(metapattern);
- dir = ealloc(psize);
- pattern = ealloc(psize);
- metadir = ealloc(psize);
- metapattern = ealloc(psize);
- dsize = psize;
- }
- d = dir;
- p = pattern;
- md = metadir;
- mp = metapattern;
- if (*s == '/')
- while (*s == '/')
- *d++ = *s++, *md++ = *m++;
- else
- while (*s != '/' && *s != '\0')
- *d++ = *s++, *md++ = *m++; /* get first directory component */
- *d = '\0';
- /*
- Special case: no slashes in the pattern, i.e., open the current directory.
- Remember that w cannot consist of slashes alone (the other way *s could be
- zero) since doglob gets called iff there's a metacharacter to be matched
- */
- if (*s == '\0') {
- matched = dmatch(".", dir, metadir);
- goto end;
- }
- if (*w == '/') {
- firstdir.w = dir;
- firstdir.m = metadir;
- firstdir.n = NULL;
- matched = &firstdir;
- } else {
- /*
- we must glob against current directory,
- since the first character is not a slash.
- */
- matched = dmatch(".", dir, metadir);
- }
- do {
- size_t slashcount;
- sigchk();
- for (slashcount = 0; *s == '/'; s++, m++)
- slashcount++; /* skip slashes */
- while (*s != '/' && *s != '\0')
- *p++ = *s++, *mp++ = *m++; /* get pattern */
- *p = '\0';
- matched = lglob(matched, pattern, metapattern, slashcount);
- p = pattern, mp = metapattern;
- } while (*s != '\0');
-end: if (matched == NULL) {
- matched = nnew(List);
- matched->w = w;
- matched->m = NULL;
- matched->n = NULL;
- }
- return matched;
-}
-
-static List *sort(List *s) {
- size_t nel = listnel(s);
- if (nel > 1) {
- char **a;
- List *t;
- qsort(a = list2array(s, FALSE), nel, sizeof(char *), starstrcmp);
- for (t = s; t != NULL; t = t->n)
- t->w = *a++;
- }
- return s;
-}
diff --git a/glom.c b/glom.c
@@ -1,433 +0,0 @@
-/* glom.c: builds an argument list out of words, variables, etc. */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include <errno.h>
-#include "rc.h"
-
-static List *backq(Node *, Node *);
-static List *bqinput(List *, int);
-static List *count(List *);
-static List *mkcmdarg(Node *);
-
-Rq *redirq = NULL;
-
-extern List *word(char *w, char *m) {
- List *s = NULL;
- if (w != NULL) {
- s = nnew(List);
- s->w = w;
- s->m = m;
- s->n = NULL;
- }
- return s;
-}
-
-/*
- Append list s2 to list s1 by copying s1 and making the new copy
- point at s2.
-*/
-
-extern List *append(List *s1, List *s2) {
- List *r, *top;
- if (s1 == NULL)
- return s2;
- if (s2 == NULL)
- return s1;
- for (r = top = nnew(List); 1; r = r->n = nnew(List)) {
- r->w = s1->w;
- r->m = s1->m;
- if ((s1 = s1->n) == NULL)
- break;
- }
- r->n = s2;
- return top;
-}
-
-extern List *concat(List *s1, List *s2) {
- int n1, n2;
- List *r, *top;
- if (s1 == NULL)
- return s2;
- if (s2 == NULL)
- return s1;
- if ((n1 = listnel(s1)) != (n2 = listnel(s2)) && n1 != 1 && n2 != 1)
- rc_error("bad concatenation");
- for (r = top = nnew(List); 1; r = r->n = nnew(List)) {
- size_t x = strlen(s1->w);
- size_t y = strlen(s2->w);
- size_t z = x + y + 1;
- r->w = nalloc(z);
- strcpy(r->w, s1->w);
- strcat(r->w, s2->w);
- if (s1->m == NULL && s2->m == NULL) {
- r->m = NULL;
- } else {
- r->m = nalloc(z);
- if (s1->m == NULL)
- memzero(r->m, x);
- else
- memcpy(r->m, s1->m, x);
- if (s2->m == NULL)
- memzero(&r->m[x], y);
- else
- memcpy(&r->m[x], s2->m, y);
- r->m[z] = 0;
- }
- if (n1 > 1)
- s1 = s1->n;
- if (n2 > 1)
- s2 = s2->n;
- if (s1 == NULL || s2 == NULL || (n1 == 1 && n2 == 1))
- break;
- }
- r->n = NULL;
- return top;
-}
-
-extern List *varsub(List *var, List *subs) {
- List *r, *top;
- int n = listnel(var);
- for (top = r = NULL; subs != NULL; subs = subs->n) {
- int i = a2u(subs->w);
- if (i < 1)
- rc_error("bad subscript");
- if (i <= n) {
- List *sub = var;
- while (--i)
- sub = sub->n; /* loop until sub == var(i) */
- if (top == NULL)
- top = r = nnew(List);
- else
- r = r->n = nnew(List);
- r->w = sub->w;
- r->m = sub->m;
- }
- }
- if (top != NULL)
- r->n = NULL;
- return top;
-}
-
-extern List *flatten(List *s) {
- List *r;
- size_t step;
- char *f;
- if (s == NULL || s->n == NULL)
- return s;
- r = nnew(List);
- f = r->w = nalloc(listlen(s) + 1);
- r->m = NULL; /* flattened lists come from variables, so no meta */
- r->n = NULL;
- strcpy(f, s->w);
- f += strlen(s->w);
- do {
- *f++ = ' ';
- s = s->n;
- step = strlen(s->w);
- memcpy(f, s->w, step);
- f += step;
- } while (s->n != NULL);
- *f = '\0';
- return r;
-}
-
-static List *count(List *l) {
- List *s = nnew(List);
- s->w = nprint("%d", listnel(l));
- s->n = NULL;
- s->m = NULL;
- return s;
-}
-
-extern void assign(List *s1, List *s2, bool stack) {
- List *val = s2;
- if (s1 == NULL)
- rc_error("null variable name");
- if (s1->n != NULL)
- rc_error("multi-word variable name");
- if (*s1->w == '\0')
- rc_error("zero-length variable name");
- if (a2u(s1->w) != -1)
- rc_error("numeric variable name");
- if (strchr(s1->w, '=') != NULL)
- rc_error("'=' in variable name");
- if (*s1->w == '*' && s1->w[1] == '\0')
- val = append(varlookup("0"), s2); /* preserve $0 when * is assigned explicitly */
- if (s2 != NULL || stack) {
- if (dashex)
- prettyprint_var(2, s1->w, val);
- varassign(s1->w, val, stack);
- alias(s1->w, varlookup(s1->w), stack);
- } else {
- if (dashex)
- prettyprint_var(2, s1->w, NULL);
- varrm(s1->w, stack);
- }
-}
-
-/*
- The following two functions are by the courtesy of Paul Haahr,
- who could not stand the incompetence of my own backquote implementation.
-*/
-
-#define BUFSIZE ((size_t) 1000)
-
-static List *bqinput(List *ifs, int fd) {
- char *end, *bufend, *s;
- List *r, *top, *prev;
- size_t remain, bufsize;
- char isifs[256];
- int n, state; /* a simple FSA is used to read in data */
-
- memzero(isifs, sizeof isifs);
- for (isifs['\0'] = TRUE; ifs != NULL; ifs = ifs->n)
- for (s = ifs->w; *s != '\0'; s++)
- isifs[*(unsigned char *)s] = TRUE;
- remain = bufsize = BUFSIZE;
- top = r = nnew(List);
- r->w = end = nalloc(bufsize + 1);
- r->m = NULL;
- state = 0;
- prev = NULL;
-
- while (1) {
- if (remain == 0) { /* is the string bigger than the buffer? */
- size_t m = end - r->w;
- char *buf;
- while (bufsize < m + BUFSIZE)
- bufsize *= 2;
- buf = nalloc(bufsize + 1);
- memcpy(buf, r->w, m);
- r->w = buf;
- end = &buf[m];
- remain = bufsize - m;
- }
- if ((n = rc_read(fd, end, remain)) <= 0) {
- if (n == 0)
- /* break */ break;
- else if (errno == EINTR)
- return NULL; /* interrupted, wait for subproc */
- else {
- uerror("backquote read");
- rc_error(NULL);
- }
- }
- remain -= n;
- for (bufend = &end[n]; end < bufend; end++)
- if (state == 0) {
- if (!isifs[*(unsigned char *)end]) {
- state = 1;
- r->w = end;
- r->m = NULL;
- }
- } else {
- if (isifs[*(unsigned char *)end]) {
- state = 0;
- *end = '\0';
- prev = r;
- r = r->n = nnew(List);
- r->w = end+1;
- r->m = NULL;
- }
- }
- }
- if (state == 1) { /* terminate last string */
- *end = '\0';
- r->n = NULL;
- } else {
- if (prev == NULL) /* no input at all? */
- top = NULL;
- else
- prev->n = NULL; /* else terminate list */
- }
- return top;
-}
-
-static List *backq(Node *ifs, Node *n) {
- int p[2], sp;
- pid_t pid;
- List *bq;
- if (n == NULL)
- return NULL;
- if (pipe(p) < 0) {
- uerror("pipe");
- rc_error(NULL);
- }
- if ((pid = rc_fork()) == 0) {
- mvfd(p[1], 1);
- close(p[0]);
- redirq = NULL;
- walk(n, FALSE);
- exit(getstatus());
- }
- close(p[1]);
- bq = bqinput(glom(ifs), p[0]);
- close(p[0]);
- rc_wait4(pid, &sp, TRUE);
- statprint(-1, sp);
- varassign("bqstatus", word(strstatus(sp), NULL), FALSE);
- sigchk();
- return bq;
-}
-
-extern void qredir(Node *n) {
- Rq *next;
- if (redirq == NULL) {
- next = redirq = nnew(Rq);
- } else {
- for (next = redirq; next->n != NULL; next = next->n)
- ;
- next->n = nnew(Rq);
- next = next->n;
- }
- next->r = n;
- next->n = NULL;
-}
-
-#if HAVE_DEV_FD || HAVE_PROC_SELF_FD
-static List *mkcmdarg(Node *n) {
- char *name;
- List *ret = nnew(List);
- Estack *e = nnew(Estack);
- Edata efd;
- int p[2];
- if (pipe(p) < 0) {
- uerror("pipe");
- return NULL;
- }
- if (rc_fork() == 0) {
- setsigdefaults(FALSE);
- if (mvfd(p[n->u[0].i == rFrom], n->u[0].i == rFrom) < 0) /* stupid hack */
- exit(1);
- close(p[n->u[0].i != rFrom]);
- redirq = NULL;
- walk(n->u[2].p, FALSE);
- exit(getstatus());
- }
-
-#if HAVE_DEV_FD
- name = nprint("/dev/fd/%d", p[n->u[0].i != rFrom]);
-#else
- name = nprint("/proc/self/fd/%d", p[n->u[0].i != rFrom]);
-#endif
-
- efd.fd = p[n->u[0].i != rFrom];
- except(eFd, efd, e);
- close(p[n->u[0].i == rFrom]);
- ret->w = name;
- ret->m = NULL;
- ret->n = NULL;
- return ret;
-}
-
-#elif HAVE_FIFO
-
-static List *mkcmdarg(Node *n) {
- int fd;
- char *name;
- Edata efifo;
- Estack *e = enew(Estack);
- List *ret = nnew(List);
- static int fifonumber = 0;
- name = nprint("/tmp/rc%d.%d", getpid(), fifonumber++);
- if (mknod(name, S_IFIFO | 0666, 0) < 0) {
- uerror("mknod");
- return NULL;
- }
- if (rc_fork() == 0) {
- setsigdefaults(FALSE);
- fd = rc_open(name, (n->u[0].i != rFrom) ? rFrom : rCreate); /* stupid hack */
- if (fd < 0) {
- uerror("open");
- exit(1);
- }
- if (mvfd(fd, (n->u[0].i == rFrom)) < 0) /* same stupid hack */
- exit(1);
- redirq = NULL;
- walk(n->u[2].p, FALSE);
- exit(getstatus());
- }
- efifo.name = name;
- except(eFifo, efifo, e);
- ret->w = name;
- ret->m = NULL;
- ret->n = NULL;
- return ret;
-}
-
-#else
-
-static List *mkcmdarg(Node *n) {
- rc_error("named pipes are not supported");
- return NULL;
-}
-
-#endif
-
-extern List *glom(Node *n) {
- List *v, *head, *tail;
- Node *words;
- if (n == NULL)
- return NULL;
- switch (n->type) {
- case nArgs:
- case nLappend:
- words = n->u[0].p;
- tail = NULL;
- while (words != NULL && (words->type == nArgs || words->type == nLappend)) {
- if (words->u[1].p != NULL && words->u[1].p->type != nWord && words->u[1].p->type != nQword)
- break;
- head = glom(words->u[1].p);
- if (head != NULL) {
- head->n = tail;
- tail = head;
- }
- words = words->u[0].p;
- }
- v = append(glom(words), tail); /* force left to right evaluation */
- return append(v, glom(n->u[1].p));
- case nBackq:
- return backq(n->u[0].p, n->u[1].p);
- case nConcat:
- head = glom(n->u[0].p); /* force left-to-right evaluation */
- return concat(head, glom(n->u[1].p));
- case nDup:
- case nRedir:
- qredir(n);
- return NULL;
- case nWord:
- case nQword:
- return word(n->u[0].s, n->u[1].s);
- case nNmpipe:
- return mkcmdarg(n);
- default:
- /*
- The next four operations depend on the left-child of glom
- to be a variable name. Therefore the variable is looked up
- here.
- */
- if ((v = glom(n->u[0].p)) == NULL)
- rc_error("null variable name");
- if (v->n != NULL)
- rc_error("multi-word variable name");
- if (*v->w == '\0')
- rc_error("zero-length variable name");
- v = (*v->w == '*' && v->w[1] == '\0') ? varlookup(v->w)->n : varlookup(v->w);
- switch (n->type) {
- default:
- panic("unexpected node in glom");
- exit(1);
- /* NOTREACHED */
- case nCount:
- return count(v);
- case nFlat:
- return flatten(v);
- case nVar:
- return v;
- case nVarsub:
- return varsub(v, glom(n->u[1].p));
- }
- }
-}
diff --git a/group.h b/group.h
@@ -1,9 +0,0 @@
-/* Solaris / `gcc -ansi' only defines NGROUPS_MAX in <limits.h> if
-_POSIX_C_SOURCE is defined. */
-#define _POSIX_C_SOURCE 1
-#include <limits.h>
-#undef _POSIX_C_SOURCE
-
-#if defined(NGROUPS) && !defined(NGROUPS_MAX)
-#define NGROUPS_MAX NGROUPS
-#endif
diff --git a/hash.c b/hash.c
@@ -1,304 +0,0 @@
-/* hash.c: hash table support for functions and variables. */
-
-/*
- Functions and variables are cached in both internal and external
- form for performance. Thus a variable which is never "dereferenced"
- with a $ is passed on to rc's children untouched. This is not so
- important for variables, but is a big win for functions, where a call
- to yyparse() is involved.
-*/
-
-#include "rc.h"
-#include "sigmsgs.h"
-
-static bool var_exportable(char *);
-static bool fn_exportable(char *);
-static int hash(char *, int);
-static int find(char *, Htab *, int);
-static void free_fn(Function *);
-
-Htab *fp;
-Htab *vp;
-static int fused, fsize, vused, vsize;
-static char **env;
-static int bozosize;
-static int envsize;
-static bool env_dirty = TRUE;
-static char *dead = "";
-
-#define HASHSIZE 64 /* rc was debugged with HASHSIZE == 2; 64 is about right for normal use */
-
-extern void inithash() {
- Htab *fpp, *vpp;
- int i;
- fp = ealloc(sizeof(Htab) * HASHSIZE);
- vp = ealloc(sizeof(Htab) * HASHSIZE);
- fused = vused = 0;
- fsize = vsize = HASHSIZE;
- for (vpp = vp, fpp = fp, i = 0; i < HASHSIZE; i++, vpp++, fpp++)
- vpp->name = fpp->name = NULL;
-}
-
-#define ADV() {if ((c = *s++) == '\0') break;}
-
-/* hash function courtesy of paul haahr */
-
-static int hash(char *s, int size) {
- int c, n = 0;
- while (1) {
- ADV();
- n += (c << 17) ^ (c << 11) ^ (c << 5) ^ (c >> 1);
- ADV();
- n ^= (c << 14) + (c << 7) + (c << 4) + c;
- ADV();
- n ^= (~c << 11) | ((c << 3) ^ (c >> 1));
- ADV();
- n -= (c << 16) | (c << 9) | (c << 2) | (c & 3);
- }
- if (n < 0)
- n = ~n;
- return n & (size - 1); /* need power of 2 size */
-}
-
-static bool rehash(Htab *ht) {
- int i, j, size;
- int newsize, newused;
- Htab *newhtab;
- if (ht == fp) {
- if (fsize > 2 * fused)
- return FALSE;
- size = fsize;
- } else {
- if (vsize > 2 * vused)
- return FALSE;
- size = vsize;
- }
- newsize = 2 * size;
- newhtab = ealloc(newsize * sizeof(Htab));
- for (i = 0; i < newsize; i++)
- newhtab[i].name = NULL;
- for (i = newused = 0; i < size; i++)
- if (ht[i].name != NULL && ht[i].name != dead) {
- newused++;
- j = hash(ht[i].name, newsize);
- while (newhtab[j].name != NULL) {
- j++;
- j &= (newsize - 1);
- }
- newhtab[j].name = ht[i].name;
- newhtab[j].p = ht[i].p;
- }
- if (ht == fp) {
- fused = newused;
- fp = newhtab;
- fsize = newsize;
- } else {
- vused = newused;
- vp = newhtab;
- vsize = newsize;
- }
- efree(ht);
- return TRUE;
-}
-
-#define varfind(s) find(s, vp, vsize)
-#define fnfind(s) find(s, fp, fsize)
-
-static int find(char *s, Htab *ht, int size) {
- int h = hash(s, size);
- while (ht[h].name != NULL && !streq(ht[h].name, s)) {
- h++;
- h &= size - 1;
- }
- return h;
-}
-
-extern void *lookup(char *s, Htab *ht) {
- int h = find(s, ht, ht == fp ? fsize : vsize);
- return (ht[h].name == NULL) ? NULL : ht[h].p;
-}
-
-extern Function *get_fn_place(char *s) {
- int h = fnfind(s);
- env_dirty = TRUE;
- if (fp[h].name == NULL) {
- if (rehash(fp))
- h = fnfind(s);
- fused++;
- fp[h].name = ecpy(s);
- fp[h].p = enew(Function);
- } else
- free_fn(fp[h].p);
- return fp[h].p;
-}
-
-extern Variable *get_var_place(char *s, bool stack) {
- Variable *new;
- int h = varfind(s);
-
- env_dirty = TRUE;
-
- if (vp[h].name == NULL) {
- if (rehash(vp))
- h = varfind(s);
- vused++;
- vp[h].name = ecpy(s);
- vp[h].p = enew(Variable);
- ((Variable *)vp[h].p)->n = NULL;
- return vp[h].p;
- } else {
- if (stack) { /* increase the stack by 1 */
- new = enew(Variable);
- new->n = vp[h].p;
- return vp[h].p = new;
- } else { /* trample the top of the stack */
- new = vp[h].p;
- efree(new->extdef);
- listfree(new->def);
- return new;
- }
- }
-}
-
-extern void delete_fn(char *s) {
- int h = fnfind(s);
- if (fp[h].name == NULL)
- return; /* not found */
- env_dirty = TRUE;
- free_fn(fp[h].p);
- efree(fp[h].p);
- efree(fp[h].name);
- if (fp[(h+1)&(fsize-1)].name == NULL) {
- --fused;
- fp[h].name = NULL;
- } else {
- fp[h].name = dead;
- }
-}
-
-extern void delete_var(char *s, bool stack) {
- int h = varfind(s);
- Variable *v;
- if (vp[h].name == NULL)
- return; /* not found */
- env_dirty = TRUE;
- v = vp[h].p;
- efree(v->extdef);
- listfree(v->def);
- if (v->n != NULL) { /* This is the top of a stack */
- if (stack) { /* pop */
- vp[h].p = v->n;
- efree(v);
- } else { /* else just empty */
- v->extdef = NULL;
- v->def = NULL;
- }
- } else { /* needs to be removed from the hash table */
- efree(v);
- efree(vp[h].name);
- if (vp[(h+1)&(vsize-1)].name == NULL) {
- --vused;
- vp[h].name = NULL;
- } else {
- vp[h].name = dead;
- }
- }
-}
-
-static void free_fn(Function *f) {
- treefree(f->def);
- efree(f->extdef);
-}
-
-extern void initenv(char **envp) {
- int n;
- for (n = 0; envp[n] != NULL; n++)
- ;
- n++; /* one for the null terminator */
- if (n < HASHSIZE)
- n = HASHSIZE;
- env = ealloc((envsize = 2 * n) * sizeof (char *));
- for (; *envp != NULL; envp++)
- if (strncmp(*envp, "fn_", conststrlen("fn_")) == 0) {
- if (!dashpee)
- fnassign_string(*envp);
- } else {
- if (!varassign_string(*envp)) /* add to bozo env */
- env[bozosize++] = *envp;
- }
-}
-
-static bool var_exportable(char *s) {
- static char *notforexport[] = {
- "apid", "pid", "apids", "*", "ifs"
- };
- int i;
- for (i = 0; i < arraysize(notforexport); i++)
- if (streq(s, notforexport[i]))
- return FALSE;
- return TRUE;
-}
-
-static bool fn_exportable(char *s) {
- int i;
- if (strncmp(s, "sig", conststrlen("sig")) == 0) { /* small speed hack */
- for (i = 0; i < NUMOFSIGNALS; i++)
- if (streq(s, signals[i].name))
- return FALSE;
- if (streq(s, "sigexit"))
- return FALSE;
- }
- return TRUE;
-}
-
-extern char **makeenv() {
- int ep, i;
- char *v;
- if (!env_dirty)
- return env;
- env_dirty = FALSE;
- ep = bozosize;
- if (vsize + fsize + 1 + bozosize > envsize) {
- envsize = 2 * (bozosize + vsize + fsize + 1);
- env = erealloc(env, envsize * sizeof(char *));
- }
- for (i = 0; i < vsize; i++) {
- if (vp[i].name == NULL || vp[i].name == dead || !var_exportable(vp[i].name))
- continue;
- v = varlookup_string(vp[i].name);
- if (v != NULL)
- env[ep++] = v;
- }
- for (i = 0; i < fsize; i++) {
- if (fp[i].name == NULL || fp[i].name == dead || !fn_exportable(fp[i].name))
- continue;
- env[ep++] = fnlookup_string(fp[i].name);
- }
- env[ep] = NULL;
- qsort(env, (size_t) ep, sizeof(char *), starstrcmp);
- return env;
-}
-
-extern void whatare_all_vars(bool showfn, bool showvar) {
- int i;
- List *s;
- if (showvar)
- for (i = 0; i < vsize; i++)
- if (vp[i].name != NULL && (s = varlookup(vp[i].name)) != NULL)
- prettyprint_var(1, vp[i].name, s);
- if (showfn)
- for (i = 0; i < fsize; i++)
- if (fp[i].name != NULL && fp[i].name != dead)
- prettyprint_fn(1, fp[i].name, fnlookup(fp[i].name));
-}
-
-/* fake getenv() for readline() follows: */
-
-#if READLINE
-extern char *getenv(const char *name) {
- List *s;
- if (name == NULL || vp == NULL || (s = varlookup((char *) name)) == NULL)
- return NULL;
- return s->w;
-}
-#endif
diff --git a/heredoc.c b/heredoc.c
@@ -1,156 +0,0 @@
-/* heredoc.c: heredoc slurping is done here */
-
-#include "rc.h"
-
-struct Hq {
- Node *doc;
- char *name;
- Hq *n;
- bool quoted;
-} *hq;
-
-static bool dead = FALSE;
-
-/*
- * read in a heredocument. A clever trick: skip over any partially matched end-of-file
- * marker storing only the number of characters matched. If the whole marker is matched,
- * return from readheredoc(). If only part of the marker is matched, copy that part into
- * the heredocument.
- *
- * BUG: if the eof string contains a newline, the state can get confused, and the
- * heredoc may continue past where it should. on the other hand, /bin/sh seems to
- * never get out of its readheredoc() when the heredoc string contains a newline
- */
-
-static char *readheredoc(char *eof) {
- int c;
- char *t, *buf, *bufend;
- unsigned char *s;
- size_t bufsize;
- t = buf = nalloc(bufsize = 512);
- bufend = &buf[bufsize];
- dead = FALSE;
-#define RESIZE(extra) { \
- char *nbuf; \
- bufsize = bufsize * 2 + extra; \
- nbuf = nalloc(bufsize); \
- memcpy(nbuf, buf, (size_t) (t - buf)); \
- t = nbuf + (t - buf); \
- buf = nbuf; \
- bufend = &buf[bufsize]; \
- }
- for (;;) {
- print_prompt2();
- for (s = (unsigned char *) eof; (c = gchar()) == *s; s++)
- ;
- if (*s == '\0' && (c == '\n' || c == EOF)) {
- *t++ = '\0';
- return buf;
- }
- if (s != (unsigned char *) eof) {
- size_t len = s - (unsigned char *) eof;
- if (t + len >= bufend)
- RESIZE(len);
- memcpy(t, eof, len);
- t += len;
- }
- for (;; c = gchar()) {
- if (c == EOF) {
- yyerror("heredoc incomplete");
- dead = TRUE;
- return NULL;
- }
- if (t + 1 >= bufend)
- RESIZE(0);
- *t++ = c;
- if (c == '\n')
- break;
- }
- }
-}
-
-/* parseheredoc -- turn a heredoc with variable references into a node chain */
-
-static Node *parseheredoc(char *s) {
- int c = *s;
- Node *result = NULL;
- while (TRUE) {
- Node *node;
- switch (c) {
- default: {
- char *begin = s;
- while ((c = *s++) != '\0' && c != '$')
- ;
- *--s = '\0';
- node = mk(nQword, begin, NULL);
- break;
- }
- case '$': {
- char *begin = ++s, *var;
- c = *s++;
- if (c == '$') {
- node = mk(nQword, "$", NULL);
- c = *s;
- } else {
- size_t len = 0;
- do
- len++;
- while (!dnw[c = *(unsigned char *) s++]);
- if (c == '^')
- c = *s;
- else
- s--;
- var = nalloc(len + 1);
- var[len] = '\0';
- memcpy(var, begin, len);
- node = mk(nFlat, mk(nWord, var, NULL));
- }
- break;
- }
- case '\0':
- return result;
- }
- result = (result == NULL) ? node : mk(nConcat, result, node);
- }
-}
-
-/* read in heredocs when yyparse hits a newline. called from yyparse */
-
-extern int heredoc(int end) {
- Hq *here;
- if ((here = hq) != NULL) {
- hq = NULL;
- if (end) {
- yyerror("heredoc incomplete");
- return FALSE;
- }
- do {
- Node *n = here->doc;
- char *s = readheredoc(here->name);
- if (dead)
- return FALSE;
- n->u[2].p = here->quoted ? mk(nQword, s, NULL) : parseheredoc(s);
- n->u[0].i = rHerestring;
- } while ((here = here->n) != NULL);
- }
- return TRUE;
-}
-
-/* queue pending heredocs into a queue. called from yyparse */
-
-extern int qdoc(Node *name, Node *n) {
- Hq *new, **prev;
- if (name->type != nWord && name->type != nQword) {
- yyerror("eof-marker not a single literal word");
- flushu();
- return FALSE;
- }
- for (prev = &hq; (new = *prev) != NULL; prev = &new->n)
- ;
- *prev = new = nnew(Hq);
- new->name = name->u[0].s;
- new->quoted = (name->type == nQword);
- new->doc = n;
- new->n = NULL;
- return TRUE;
-}
diff --git a/history/history.1 b/history/history.1
@@ -1,234 +0,0 @@
-.\" history.1
-.\"-------
-.\" See rc.1 for man page portability notes.
-.\"-------
-.\" Dd distance to space vertically before a "display"
-.\" These are what n/troff use for interparagraph distance
-.\"-------
-.if t .nr Dd .4v
-.if n .nr Dd 1v
-.\"-------
-.\" Ds begin a display, indented .5 inches from the surrounding text.
-.\"
-.\" Note that uses of Ds and De may NOT be nested.
-.\"-------
-.de Ds
-.\" .RS \\$1
-.sp \\n(Ddu
-.in +0.5i
-.nf
-..
-.\"-------
-.\" De end a display (no trailing vertical spacing)
-.\"-------
-.de De
-.fi
-.in
-.\" .RE
-..
-.\"-------
-.\" I stole the Xf macro from the -man macros on my machine (originally
-.\" "}S", I renamed it so that it won't conflict).
-.\"-------
-.\" Set Cf to the name of the constant width font.
-.\" It will be "C" or "(CW", typically.
-.\" NOTEZ BIEN the lines defining Cf must have no trailing white space:
-.\"-------
-.if t .ds Cf C
-.if n .ds Cf R
-.\"-------
-.\" Rc - Alternate Roman and Courier
-.\"-------
-.de Rc
-.Xf R \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Ic - Alternate Italic and Courier
-.\"-------
-.de Ic
-.Xf I \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Bc - Alternate Bold and Courier
-.\"-------
-.de Bc
-.Xf B \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Cr - Alternate Courier and Roman
-.\"-------
-.de Cr
-.Xf \\*(Cf R \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Ci - Alternate Courier and Italic
-.\"-------
-.de Ci
-.Xf \\*(Cf I \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Cb - Alternate Courier and Bold
-.\"-------
-.de Cb
-.Xf \\*(Cf B \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Xf - Alternate fonts
-.\"
-.\" \$1 - first font
-.\" \$2 - second font
-.\" \$3 - desired word with embedded font changes, built up by recursion
-.\" \$4 - text for first font
-.\" \$5 - \$9 - remaining args
-.\"
-.\" Every time we are called:
-.\"
-.\" If there is something in \$4
-.\" then Call ourself with the fonts switched,
-.\" with a new word made of the current word (\$3) and \$4
-.\" rendered in the first font,
-.\" and with the remaining args following \$4.
-.\" else We are done recursing. \$3 holds the desired output
-.\" word. We emit \$3, change to Roman font, and restore
-.\" the point size to the default.
-.\" fi
-.\"
-.\" Use Xi to add a little bit of space after italic text.
-.\"-------
-.de Xf
-.ds Xi
-.\"-------
-.\" I used to test for the italic font both by its font position
-.\" and its name. Now just test by its name.
-.\"
-.\" .if "\\$1"2" .if !"\\$5"" .ds Xi \^
-.\"-------
-.if "\\$1"I" .if !"\\$5"" .ds Xi \^
-.\"-------
-.\" This is my original code to deal with the recursion.
-.\" Evidently some nroffs can't deal with it.
-.\"-------
-.\" .ie !"\\$4"" \{\
-.\" . Xf \\$2 \\$1 "\\$3\\f\\$1\\$4\\*(Xi" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
-.\" .\}
-.\" .el \{\\$3
-.\" . ft R \" Restore the default font, since we don't know
-.\" . \" what the last font change was.
-.\" . ps 10 \" Restore the default point size, since it might
-.\" . \" have been changed by an argument to this macro.
-.\" .\}
-.\"-------
-.\" Here is more portable (though less pretty) code to deal with
-.\" the recursion.
-.\"-------
-.if !"\\$4"" .Xf \\$2 \\$1 "\\$3\\f\\$1\\$4\\*(Xi" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
-.if "\\$4"" \\$3\fR\s10
-..
-.TH HISTORY 1 "30 July 1991"
-.SH NAME
-\-, \-\|\-, \-p, \-\|\-p \- shell history programs
-.SH SYNOPSIS
-.B \-
-.RI [ pattern ...]
-.RI [ substitution ...]
-.SH DESCRIPTION
-This set of programs provides a crude history mechanism for the shell
-.IR rc (1).
-It is based on the v8 UNIX programs
-.IR = ,
-.IR == ,
-etc.
-.PP
-The program
-.RI `` \- ''
-runs the shell on the command it is requested to find.
-The program
-.RI `` \-\|\- ''
-edits that command first.
-The programs
-.RI `` \-p ''
-and
-.RI `` \-\|\-p ''
-are similar, except that they print the final command on their standard
-output instead of running the shell.
-.PP
-The commands work by looking for a file
-named by the environment variable
-.Cr $history ,
-and by searching for previous commands in this file.
-Old commands can be edited,
-or simply re-executed according to the rules below:
-.PP
-A command is searched for by examining the lines in
-.Cr $history
-in reverse order.
-Lines which contain a previous invocation of the history
-program itself are ignored.
-If one or more
-.I pattern
-is supplied on the command line,
-then the patterns are used as a means of
-limiting the search.
-Patterns match any substring of a previous command,
-and if more than one pattern is present then all patterns must be
-matched before a command is selected.
-.PP
-Substitutions may also be specified on the command line.
-These have the syntax:
-.Ds
-.Ic old : new
-.De
-.PP
-(Note that the
-.I old
-pattern is used as a search-limiting pattern also.)
-Substitutions happen on the first match.
-.PP
-Finally, a command may be edited in a crude line-mode fashion:
-The line to be edited is printed out, and below it the user
-supplies modifications to the command:
-.TP
-.B any character
-Replaces the character above.
-.TP
-.B space or tab
-Skips over the above character(s).
-.TP
-.B #
-Deletes one character.
-.TP
-.B %
-Replaces one character with a space.
-.TP
-.B ^
-Inserts the rest of the typed line just before the character.
-.TP
-.B $
-Deletes the rest of the line from that character on, and replaces
-it with the rest of the typed line.
-.TP
-.B +
-Appends the rest of the typed line.
-.TP
-.B \-
-Backs up to a previous command satisfying the same matching
-constraints.
-.TP
-.B end of file
-If an end-of-file is read from the keyboard by the editor,
-it aborts with exit status 1 and does not produce any output.
-.SH EXAMPLES
-The history programs work best when their output is reinterpreted by
-the shell using an
-.Cr eval
-command.
-This can be achieved by writing a shell function to perform the
-reinterpretation:
-.Ds
-.Cr "fn - -- {"
-.Cr " comm = \`{$0^p $*}"
-.Cr " if (! ~ $#comm 0) {"
-.Cr " echo $comm >[1=2]"
-.Cr " eval $comm"
-.Cr " }"
-.Cr "}"
diff --git a/history/history.c b/history/history.c
@@ -1,341 +0,0 @@
-/*
- history.c -- primitive history mechanism
-
- Paul Haahr & Byron Rakitzis, July 1991.
-
- This program mimics the att v8 = and == history programs.
- The edit() algorithm was adapted from a similar program
- that Boyd Roberts wrote, but otherwise all the code has
- been written from scratch.
-
- edit() was subsequently redone by Hugh Redelmeier in order
- to correctly deal with tab characters in the source line.
-
- BUGS:
- There is an implicit assumption that commands are no
- more than 1k characters long.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-static char *id = "@(#) history.c 8/91";
-
-#undef FALSE
-#undef TRUE
-typedef enum { FALSE, TRUE } bool;
-
-#define CHUNKSIZE 65536
-
-static struct {
- char *old, *new;
-} *replace;
-
-static char **search, *progname, *history;
-static char me; /* typically ':' or '-' */
-static bool editit = FALSE, printit = FALSE;
-static int nreplace = 0, nsearch = 0;
-static FILE *fp;
-
-static void *ealloc(size_t n) {
- void *p = (void *) malloc(n);
- if (p == NULL) {
- perror("malloc");
- exit(1);
- }
- return p;
-}
-
-static void *erealloc(void *p, size_t n) {
- p = (void *) realloc(p, n);
- if (p == NULL) {
- perror("realloc");
- exit(1);
- }
- return p;
-}
-
-static char *newstr() {
- return ealloc((size_t)1024);
-}
-
-static char *basename(char *s) {
- char *t = strrchr(s, '/');
- return (t == NULL) ? s : t + 1;
-}
-
-/* stupid O(n^2) substring matching routine */
-
-static char *isin(char *target, char *pattern) {
- size_t plen = strlen(pattern);
- size_t tlen = strlen(target);
- for (; tlen >= plen; target++, --tlen)
- if (strncmp(target, pattern, plen) == 0)
- return target;
- return NULL;
-}
-
-/* replace the first match in the string with "new" */
-static char *sub(char *s, char *old, char *new) {
- char *t, *u;
-
- t = isin(s, old);
- u = newstr();
-
- *t = '\0';
- while (*old != '\0')
- old++, t++;
- strcpy(u, s);
- strcat(u, new);
- strcat(u, t);
- return u;
-}
-
-static char *edit(char *s) {
- char *final, *f, *end;
- int col;
- bool ins;
-
-start:
- fprintf(stderr, "%s\n", s);
- f = final = newstr();
- end = s + strlen(s);
- col = 0;
- ins = FALSE;
-
- for (;; col++) {
- int c = getchar();
-
- if (c == me && col == 0) {
- int peekc = getchar();
- if (peekc == '\n')
- return NULL;
- ungetc(peekc, stdin);
- }
- if (c == '\n') {
- if (col == 0)
- return s;
-
- while (s < end) /* copy remainder of string */
- *f++ = *s++;
- *f = '\0';
- s = final;
- goto start;
- } else if (ins || s>=end) {
- /* col need not be accurate -- tabs need not be interpreted */
- *f++ = c;
- } else {
- switch (c) {
- case '+':
- while (s < end)
- *f++ = *s++;
- *f = '\0';
- continue;
- case '%':
- c = ' ';
- /* FALLTHROUGH */
- default:
- *f++ = c;
- break;
- case EOF:
- exit(1);
- /* NOTREACHED */
- case ' ':
- if (*s == '\t') {
- int oldcol = col;
-
- for (;; col++) {
- int peekc;
-
- if ((col&07) == 07) {
- *f++ = '\t'; /* we spaced past a tab */
- break;
- }
- peekc = getchar();
- if (peekc != ' ') {
- ungetc(peekc, stdin);
- if (peekc != '\n') {
- /* we spaced partially into a tab */
- do {
- *f++ = ' ';
- oldcol++;
- } while (oldcol <= col);
- }
- break;
- }
- }
- } else {
- *f++ = *s;
- }
- break;
- case '#':
- break;
- case '$':
- end = s; /* truncate s */
- continue; /* skip incrementing s */
- case '^':
- ins = TRUE;
- continue; /* skip incrementing s */
- case '\t':
- for (;; col++) {
- if ((*f++ = s<end? *s++ : '\t') == '\t') {
- col = col | 07; /* advance to before next tabstop */
- }
- if ((col&07) == 07) /* stop before tabstop */
- break;
- }
- continue; /* skip incrementing s */
- }
- if (s<end && (*s!='\t' || (col&07)==07))
- s++;
- }
- }
-}
-
-static char *readhistoryfile(char **last) {
- char *buf;
- size_t count, size;
- long nread;
-
- if ((history = getenv("history")) == NULL) {
- fprintf(stderr, "$history not set\n");
- exit(1);
- }
- fp = fopen(history, "r+");
- if (fp == NULL) {
- perror(history);
- exit(1);
- }
-
- size = 0;
- count = 0;
- buf = ealloc(size = CHUNKSIZE);
- while ((nread = fread(buf + count, sizeof (char), size - count, fp)) > 0) {
- count += nread;
- if (size - count == 0)
- buf = erealloc(buf, size *= 4);
- }
- if (nread == -1) {
- perror(history);
- exit(1);
- }
- *last = buf + count;
- return buf;
-}
-
-static char *getcommand() {
- char *s, *t;
- static char *hist = NULL, *last;
-
- if (hist == NULL) {
- hist = readhistoryfile(&last);
- *--last = '\0'; /* trim final newline */
- }
-
-again: s = last;
- if (s < hist)
- return NULL;
- while (*--s != '\n')
- if (s <= hist) {
- last = hist - 1;
- return hist;
- }
- *s = '\0';
- last = s++;
-
- /*
- * if the command contains the "me" character at the start of the line
- * or after any of [`{|()@] then try again
- */
-
- for (t = s; *t != '\0'; t++)
- if (*t == me) {
- char *u = t - 1;
- while (u >= s && (*u == ' ' || *u == '\t'))
- --u;
- if (u < s)
- goto again;
- switch (*u) {
- case '`': case '@':
- case '(': case ')':
- case '{': case '|':
- goto again;
- default:
- break;
- }
- }
- return s;
-}
-
-int main(int argc, char **argv) {
- int i;
- char *s;
-
- s = progname = basename(argv[0]);
- me = *s++;
- if (*s == me) {
- s++;
- editit = TRUE;
- }
- if (*s == 'p') {
- s++;
- printit = TRUE;
- }
-/* Nahh...
- if (*s != '\0') {
- fprintf(stderr, "\"%s\": bad name for history program\n", progname);
- exit(1);
- }
-*/
-
- if (argc > 1) {
- replace = ealloc((argc - 1) * sizeof *replace);
- search = ealloc((argc - 1) * sizeof *search);
- }
- for (i = 1; i < argc; i++)
- if ((s = strchr(argv[i], ':')) == NULL)
- search[nsearch++] = argv[i];
- else {
- *(char *)s = '\0'; /* do we confuse ps too much? */
- replace[nreplace].old = argv[i];
- replace[nreplace].new = s + 1;
- nreplace++;
- }
-
-next: s = getcommand();
- if (s == NULL) {
- fprintf(stderr, "command not matched\n");
- return 1;
- }
- for (i = 0; i < nsearch; i++)
- if (!isin(s, search[i]))
- goto next;
- for (i = 0; i < nreplace; i++)
- if (!isin(s, replace[i].old))
- goto next;
- else
- s = sub(s, replace[i].old, replace[i].new);
- if (editit) {
- s = edit(s);
- if (s == NULL)
- goto next;
- }
- fseek(fp, 0, 2); /* 2 == end of file. i.e., append command to $history */
- fprintf(fp, "%s\n", s);
- fclose(fp);
- if (printit)
- printf("%s\n", s);
- else {
- char *shell = getenv("SHELL");
-
- if (!editit)
- fprintf(stderr, "%s\n", s);
- if (shell == NULL)
- shell = "/bin/sh";
- execl(shell, basename(shell), "-c", s, NULL);
- perror(shell);
- exit(1);
- }
- return 0;
-}
diff --git a/input.c b/input.c
@@ -1,363 +0,0 @@
-/* input.c: i/o routines for files and pseudo-files (strings) */
-
-#include <errno.h>
-#include <setjmp.h>
-#include "rc.h"
-#include "jbwrap.h"
-
-/*
- NB: character unget is supported for up to two characters, but NOT
- in the case of EOF. Since EOF does not fit in a char, it is easiest
- to support only one unget of EOF.
-*/
-
-typedef struct Input {
- inputtype t;
- char *ibuf;
- int fd, index, read, lineno, last;
- bool saved, eofread;
-} Input;
-
-#define BUFSIZE ((size_t) 256)
-
-#if READLINE
-extern char *readline(char *);
-extern void add_history(char *);
-static char *rlinebuf;
-#endif
-
-char *prompt, *prompt2;
-bool rcrc;
-
-static int dead(void);
-static int fdgchar(void);
-static int stringgchar(void);
-static void history(void);
-static void ugdead(int);
-static void pushcommon(void);
-
-static char *inbuf;
-static size_t istacksize, chars_out, chars_in;
-static bool eofread = FALSE, save_lineno = TRUE;
-static Input *istack, *itop;
-
-static int (*realgchar)(void);
-static void (*realugchar)(int);
-
-int last;
-
-extern int gchar() {
- int c;
-
- if (eofread) {
- eofread = FALSE;
- return last = EOF;
- }
-
- while ((c = (*realgchar)()) == '\0')
- pr_error("warning: null character ignored");
-
- return c;
-}
-
-extern void ugchar(int c) {
- (*realugchar)(c);
-}
-
-static int dead() {
- return last = EOF;
-}
-
-static void ugdead(int c) {
- return;
-}
-
-static void ugalive(int c) {
- if (c == EOF)
- eofread = TRUE;
- else
- inbuf[--chars_out] = c;
-}
-
-/* get the next character from a string. */
-
-static int stringgchar() {
- return last = (inbuf[chars_out] == '\0' ? EOF : inbuf[chars_out++]);
-}
-
-/* signal-safe readline wrapper */
-
-#if READLINE
-#ifndef HAVE_RESTARTABLE_SYSCALLS
-static char *rc_readline(char *prompt) {
- char *r;
- interrupt_happened = FALSE;
- if (!setjmp(slowbuf.j)) {
- slow = TRUE;
- if (!interrupt_happened)
- r = readline(prompt);
- else
- r = NULL;
- } else
- r = NULL;
- slow = FALSE;
- if (r == NULL)
- errno = EINTR;
- sigchk();
- return r;
-}
-#else
-#define rc_readline readline
-#endif /* HAVE_RESTARTABLE_SYSCALLS */
-#endif /* READLINE */
-
-/*
- read a character from a file-descriptor. If GNU readline is defined, add a newline and doctor
- the buffer to look like a regular fdgchar buffer.
-*/
-
-static int fdgchar() {
- if (chars_out >= chars_in + 2) { /* has the buffer been exhausted? if so, replenish it */
- while (1) {
-#if READLINE
- if (interactive && istack->fd == 0) {
- rlinebuf = rc_readline(prompt);
- if (rlinebuf == NULL) {
- chars_in = 0;
- } else {
- if (*rlinebuf != '\0')
- add_history(rlinebuf);
- chars_in = strlen(rlinebuf) + 1;
- efree(inbuf);
- inbuf = ealloc(chars_in + 3);
- strcpy(inbuf+2, rlinebuf);
- strcat(inbuf+2, "\n");
- efree(rlinebuf);
- }
- } else
-#endif
- {
- long /*ssize_t*/ r = rc_read(istack->fd, inbuf + 2, BUFSIZE);
- sigchk();
- if (r < 0) {
- uerror("read");
- rc_exit(1);
- }
- chars_in = (size_t) r;
- }
- break;
- }
- if (chars_in == 0)
- return last = EOF;
- chars_out = 2;
- if (dashvee)
- writeall(2, inbuf + 2, chars_in);
- history();
- }
- return last = inbuf[chars_out++];
-}
-
-/* set up the input stack, and put a "dead" input at the bottom, so that yyparse will always read eof */
-
-extern void initinput() {
- istack = itop = ealloc(istacksize = 256 * sizeof (Input));
- istack->t = iFd;
- istack->fd = -1;
- realugchar = ugalive;
-}
-
-/* push an input source onto the stack. set up a new input buffer, and set gchar() */
-
-static void pushcommon() {
- size_t idiff;
- istack->index = chars_out;
- istack->read = chars_in;
- istack->ibuf = inbuf;
- istack->lineno = lineno;
- istack->saved = save_lineno;
- istack->last = last;
- istack->eofread = eofread;
- istack++;
- idiff = istack - itop;
- if (idiff >= istacksize / sizeof (Input)) {
- itop = erealloc(itop, istacksize *= 2);
- istack = itop + idiff;
- }
- realugchar = ugalive;
- chars_out = 2;
- chars_in = 0;
-}
-
-extern void pushfd(int fd) {
- pushcommon();
- istack->t = iFd;
- save_lineno = TRUE;
- istack->fd = fd;
- realgchar = fdgchar;
- inbuf = ealloc(BUFSIZE + 2);
- lineno = 1;
-}
-
-extern void pushstring(char **a, bool save) {
- pushcommon();
- istack->t = iString;
- save_lineno = save;
- inbuf = mprint("..%A", a);
- realgchar = stringgchar;
- if (save_lineno)
- lineno = 1;
- else
- --lineno;
-}
-
-/* remove an input source from the stack. restore the right kind of getchar (string,fd) etc. */
-
-extern void popinput() {
- if (istack->t == iFd)
- close(istack->fd);
- efree(inbuf);
- --istack;
- realgchar = (istack->t == iString ? stringgchar : fdgchar);
- if (istack->t == iFd && istack->fd == -1) { /* top of input stack */
- realgchar = dead;
- realugchar = ugdead;
- }
- last = istack->last;
- eofread = istack->eofread;
- inbuf = istack->ibuf;
- chars_out = istack->index;
- chars_in = istack->read;
- if (save_lineno)
- lineno = istack->lineno;
- else
- lineno++;
- save_lineno = istack->saved;
-}
-
-/* flush input characters upto newline. Used by scanerror() */
-
-extern void flushu() {
- int c;
- if (last == '\n' || last == EOF)
- return;
- while ((c = gchar()) != '\n' && c != EOF)
- ; /* skip to newline */
- if (c == EOF)
- ugchar(c);
-}
-
-/* the wrapper loop in rc: prompt for commands until EOF, calling yyparse and walk() */
-
-extern Node *doit(bool execit) {
- bool eof;
- Jbwrap j;
- Estack e1, e2;
- Edata jerror;
-
- if (dashen)
- execit = FALSE;
- setjmp(j.j);
- jerror.jb = &j;
- except(eError, jerror, &e1);
- for (eof = FALSE; !eof;) {
- Edata block;
- block.b = newblock();
- except(eArena, block, &e2);
- sigchk();
- if (dashell) {
- char *fname[3];
- fname[1] = concat(varlookup("home"), word("/.rcrc", NULL))->w;
- fname[2] = NULL;
- rcrc = TRUE;
- dashell = FALSE;
- b_dot(fname);
- }
- if (interactive) {
- List *s;
- if (!dashen && fnlookup("prompt") != NULL) {
- static char *arglist[] = { "prompt", NULL };
- funcall(arglist);
- }
- if ((s = varlookup("prompt")) != NULL) {
-#if READLINE
- prompt = s->w;
-#else
- fprint(2, "%s", s->w);
-#endif
- prompt2 = (s->n == NULL ? "" : s->n->w);
- }
- }
- inityy();
- if (yyparse() == 1 && execit)
- rc_raise(eError);
- eof = (last == EOF); /* "last" can be clobbered during a walk() */
- if (parsetree != NULL) {
- if (execit)
- walk(parsetree, TRUE);
- else if (dashex && dashen)
- fprint(2, "%T\n", parsetree);
- }
- unexcept(); /* eArena */
- }
- popinput();
- unexcept(); /* eError */
- return parsetree;
-}
-
-/* parse a function imported from the environment */
-
-extern Node *parseline(char *extdef) {
- int i = interactive;
- char *in[2];
- Node *fun;
- in[0] = extdef;
- in[1] = NULL;
- interactive = FALSE;
- pushstring(in, TRUE);
- fun = doit(FALSE);
- interactive = i;
- return fun;
-}
-
-/* write last command out to a file if interactive && $history is set */
-
-static void history() {
- List *hist;
- size_t a;
-
- if (!interactive || (hist = varlookup("history")) == NULL)
- return;
-
- for (a = 0; a < chars_in; a++) {
- char c = inbuf[a+2];
-
- /* skip empty lines and comments */
- if (c == '#' || c == '\n')
- break;
-
- /* line matches [ \t]*[^#\n] so it's ok to write out */
- if (c != ' ' && c != '\t') {
- char *name = hist->w;
- int fd = rc_open(name, rAppend);
- if (fd < 0) {
- uerror(name);
- varrm(name, TRUE);
- } else {
- writeall(fd, inbuf + 2, chars_in);
- close(fd);
- }
- break;
- }
- }
-}
-
-/* close file descriptors after a fork() */
-
-extern void closefds() {
- Input *i;
- for (i = istack; i != itop; --i) /* close open scripts */
- if (i->t == iFd && i->fd > 2) {
- close(i->fd);
- i->fd = -1;
- }
-}
diff --git a/install-sh b/install-sh
@@ -1,250 +0,0 @@
-#! /bin/sh
-#
-# install - install a program, script, or datafile
-# This comes from X11R5 (mit/util/scripts/install.sh).
-#
-# Copyright 1991 by the Massachusetts Institute of Technology
-#
-# Permission to use, copy, modify, distribute, and sell this software and its
-# documentation for any purpose is hereby granted without fee, provided that
-# the above copyright notice appear in all copies and that both that
-# copyright notice and this permission notice appear in supporting
-# documentation, and that the name of M.I.T. not be used in advertising or
-# publicity pertaining to distribution of the software without specific,
-# written prior permission. M.I.T. makes no representations about the
-# suitability of this software for any purpose. It is provided "as is"
-# without express or implied warranty.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch. It can only install one file at a time, a restriction
-# shared with many OS's install programs.
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
- case $1 in
- -c) instcmd="$cpprog"
- shift
- continue;;
-
- -d) dir_arg=true
- shift
- continue;;
-
- -m) chmodcmd="$chmodprog $2"
- shift
- shift
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd="$stripprog"
- shift
- continue;;
-
- -t=*) transformarg=`echo $1 | sed 's/-t=//'`
- shift
- continue;;
-
- -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
- shift
- continue;;
-
- *) if [ x"$src" = x ]
- then
- src=$1
- else
- # this colon is to work around a 386BSD /bin/sh bug
- :
- dst=$1
- fi
- shift
- continue;;
- esac
-done
-
-if [ x"$src" = x ]
-then
- echo "install: no input file specified"
- exit 1
-else
- true
-fi
-
-if [ x"$dir_arg" != x ]; then
- dst=$src
- src=""
-
- if [ -d $dst ]; then
- instcmd=:
- else
- instcmd=mkdir
- fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad
-# if $src (and thus $dsttmp) contains '*'.
-
- if [ -f $src -o -d $src ]
- then
- true
- else
- echo "install: $src does not exist"
- exit 1
- fi
-
- if [ x"$dst" = x ]
- then
- echo "install: no destination specified"
- exit 1
- else
- true
- fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
- if [ -d $dst ]
- then
- dst="$dst"/`basename $src`
- else
- true
- fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-# this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
- pathcomp="${pathcomp}${1}"
- shift
-
- if [ ! -d "${pathcomp}" ] ;
- then
- $mkdirprog "${pathcomp}"
- else
- true
- fi
-
- pathcomp="${pathcomp}/"
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
- $doit $instcmd $dst &&
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
- if [ x"$transformarg" = x ]
- then
- dstfile=`basename $dst`
- else
- dstfile=`basename $dst $transformbasename |
- sed $transformarg`$transformbasename
- fi
-
-# don't allow the sed command to completely eliminate the filename
-
- if [ x"$dstfile" = x ]
- then
- dstfile=`basename $dst`
- else
- true
- fi
-
-# Make a temp file name in the proper directory.
-
- dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
- $doit $instcmd $src $dsttmp &&
-
- trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing. If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
- $doit $rmcmd -f $dstdir/$dstfile &&
- $doit $mvcmd $dsttmp $dstdir/$dstfile
-
-fi &&
-
-
-exit 0
diff --git a/jbwrap.h b/jbwrap.h
@@ -1,9 +0,0 @@
-#include <setjmp.h>
-
-/* certain braindamaged environments don't define jmp_buf as an array, so... */
-
-struct Jbwrap {
- jmp_buf j;
-};
-
-extern Jbwrap slowbuf; /* for getting out of interrupts while performing slow i/o on BSD */
diff --git a/lex.c b/lex.c
@@ -1,395 +0,0 @@
-/* lex.c: rc's lexical analyzer */
-
-#include "rc.h"
-#include "y.tab.h"
-
-/*
- Special characters (i.e., "non-word") in rc:
- \t \n # ; & | ^ $ = ~ ` ' { } @ ! ( ) < > \
-
- The lexical analyzer is fairly straightforward. The only really
- unclean part concerns backslash continuation and "double
- backslashes". A backslash followed by a newline is treated as a
- space, otherwise backslash is not a special character (i.e.,
- it can be part of a word). This introduces a host of unwanted
- special cases. In our case, \ cannot be a word character, since
- we wish to read in all word characters in a tight loop.
-
- Note: to save the trouble of declaring these arrays with TRUEs
- and FALSEs, I am assuming that FALSE = 0, TRUE = 1. (and so is
- it declared in rc.h)
-*/
-
-#define BUFSIZE ((size_t) 1000) /* malloc hates power of 2 buffers? */
-#define BUFMAX (8 * BUFSIZE) /* How big the buffer can get before we re-allocate the
- space at BUFSIZE again. Premature optimization? Maybe.
- */
-
-typedef enum wordstates {
- NW, RW, KW /* "nonword", "realword", "keyword" */
-} wordstates;
-
-static void getpair(int);
-
-int lineno;
-
-const char nw[] = {
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-const char dnw[] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
-};
-
-static size_t bufsize = BUFSIZE;
-static char *realbuf = NULL;
-static bool newline = FALSE;
-static bool errset = FALSE;
-static bool prerror = FALSE;
-static wordstates w = NW;
-static int fd_left, fd_right;
-
-#define checkfreecaret {if (w != NW) { w = NW; ugchar(c); return '^'; }}
-
-enum filedescriptors {
- UNSET = -9, CLOSED = -1
-};
-
-extern int yylex() {
- static bool dollar = FALSE;
- bool saw_meta = FALSE;
- int c;
- size_t i; /* The purpose of all these local assignments is to */
- const char *meta; /* allow optimizing compilers like gcc to load these */
- char *buf = realbuf; /* values into registers. On a sparc this is a */
- YYSTYPE *y = &yylval; /* win, in code size *and* execution time */
- if (errset) {
- errset = FALSE;
- return '\n';
- }
- /* rc variable-names may contain only alnum, '*' and '_', so use dnw if we are scanning one. */
- meta = (dollar ? dnw : nw);
- dollar = FALSE;
- if (newline) {
- --lineno; /* slight space optimization; print_prompt2() always increments lineno */
- print_prompt2();
- newline = FALSE;
- }
-top: while ((c = gchar()) == ' ' || c == '\t')
- w = NW;
- if (c == EOF)
- return END;
- if (!meta[(unsigned char) c]) { /* it's a word or keyword. */
- checkfreecaret;
- w = RW;
- i = 0;
- read: do {
- buf[i++] = c;
- if (c == '?' || c == '[' || c == '*')
- saw_meta = TRUE;
- if (i >= bufsize)
- buf = realbuf = erealloc(buf, bufsize *= 2);
- } while ((c = gchar()) != EOF && !meta[(unsigned char) c]);
- while (c == '\\') {
- if ((c = gchar()) == '\n') {
- print_prompt2();
- c = ' '; /* Pretend a space was read */
- break;
- } else {
- bs: if (meta != dnw) { /* all words but varnames may have a bslash */
- buf[i++] = '\\';
- if (i >= bufsize)
- buf = realbuf = erealloc(buf, bufsize *= 2);
- if (!meta[(unsigned char) c])
- goto read;
- } else {
- ugchar(c);
- c = '\\';
- break;
- }
- }
- }
- ugchar(c);
- buf[i] = '\0';
- w = KW;
- if (i == 2) {
- if (*buf == 'i' && buf[1] == 'f') return IF;
- if (*buf == 'f' && buf[1] == 'n') return FN;
- if (*buf == 'i' && buf[1] == 'n') return IN;
- }
- if (streq(buf, "for")) return FOR;
- if (streq(buf, "else")) return ELSE;
- if (streq(buf, "switch")) return SWITCH;
- if (streq(buf, "while")) return WHILE;
- if (streq(buf, "case")) return CASE;
- w = RW;
- y->word.w = ncpy(buf);
- if (saw_meta) {
- char *r, *s;
-
- y->word.m = nalloc(strlen(buf) + 1);
- for (r = buf, s = y->word.m; *r != '\0'; r++, s++)
- *s = (*r == '?' || *r == '[' || *r == '*');
- } else {
- y->word.m = NULL;
- }
- return WORD;
- }
- if (c == '`' || c == '!' || c == '@' || c == '~' || c == '$' || c == '\'') {
- checkfreecaret;
- if (c == '!' || c == '@' || c == '~')
- w = KW;
- }
- switch (c) {
- case '!':
- return BANG;
- case '@':
- return SUBSHELL;
- case '~':
- return TWIDDLE;
- case '`':
- c = gchar();
- if (c == '`')
- return BACKBACK;
- ugchar(c);
- return '`';
- case '$':
- dollar = TRUE;
- c = gchar();
- if (c == '#')
- return COUNT;
- if (c == '^')
- return FLAT;
- ugchar(c);
- return '$';
- case '\'':
- w = RW;
- i = 0;
- do {
- buf[i++] = c;
- if (c == '\n')
- print_prompt2();
- if (c == EOF) {
- w = NW;
- scanerror("eof in quoted string");
- return HUH;
- }
- if (i >= bufsize)
- buf = realbuf = erealloc(buf, bufsize *= 2);
- } while ((c = gchar()) != '\'' || (c = gchar()) == '\''); /* quote "'" thus: 'how''s it going?' */
- ugchar(c);
- buf[i] = '\0';
- y->word.w = ncpy(buf);
- y->word.m = NULL;
- return WORD;
- case '\\':
- if ((c = gchar()) == '\n') {
- print_prompt2();
- goto top; /* Pretend it was just another space. */
- }
- ugchar(c);
- c = '\\';
- checkfreecaret;
- c = gchar();
- i = 0;
- goto bs;
- case '(':
- if (w == RW) /* SUB's happen only after real words, not keyowrds, so if () and while () work */
- c = SUB;
- w = NW;
- return c;
- case '#':
- while ((c = gchar()) != '\n') /* skip comment until newline */
- if (c == EOF)
- return END;
- /* FALLTHROUGH */
- case '\n':
- lineno++;
- newline = TRUE;
- /* FALLTHROUGH */
- case ';':
- case '^':
- case ')':
- case '=':
- case '{': case '}':
- w = NW;
- return c;
- case '&':
- w = NW;
- c = gchar();
- if (c == '&')
- return ANDAND;
- ugchar(c);
- return '&';
- case '|':
- w = NW;
- c = gchar();
- if (c == '|')
- return OROR;
- getpair(c);
- if (errset)
- return HUH;
- if ((y->pipe.left = fd_left) == UNSET)
- y->pipe.left = 1; /* default to fd 1 */
- if ((y->pipe.right = fd_right) == UNSET)
- y->pipe.right = 0; /* default to fd 0 */
- if (y->pipe.right == CLOSED) {
- scanerror("expected digit after '='"); /* can't close a pipe */
- return HUH;
- }
- return PIPE;
- case '>':
- c = gchar();
- if (c == '>') {
- c = gchar();
- y->redir.type = rAppend;
- } else
- y->redir.type = rCreate;
- y->redir.fd = 1;
- goto common;
- case '<':
- c = gchar();
- if (c == '<') {
- c = gchar();
- if (c == '<') {
- c = gchar();
- y->redir.type = rHerestring;
- } else {
- y->redir.type = rHeredoc;
- }
- } else
- y->redir.type = rFrom;
- y->redir.fd = 0;
- common:
- w = NW;
- getpair(c);
- if (errset)
- return HUH;
- if (fd_right == UNSET) { /* redirection, not dup */
- if (fd_left != UNSET) {
- y->redir.fd = fd_left;
- return SREDIR;
- }
- return (y->redir.type == rFrom || y->redir.type == rCreate) ? REDIR : SREDIR;
- } else { /* dup; recast yylval */
- y->dup.type = y->redir.type;
- y->dup.left = fd_left;
- y->dup.right = fd_right;
- return DUP;
- }
- default:
- w = NW;
- return c; /* don't know what it is, let yacc barf on it */
- }
-}
-
-extern void yyerror(const char *s) {
- char *tok;
- if (prerror) { /* don't print "syntax error" if there's a more informative scanerror */
- prerror = FALSE;
- return;
- }
- if (!interactive) {
- if (w != NW)
- tok = realbuf;
- else if (last == EOF)
- tok = "eof";
- else if (last == '\n')
- tok = "end of line";
- else
- tok = nprint((last < 32 || last > 126) ? "(decimal %d)" : "'%c'", last);
- fprint(2, "line %d: %s near %s\n", lineno - (last == '\n'), s, tok);
- } else
- fprint(2, "%s\n", s);
-}
-
-extern void scanerror(char *s) {
- flushu(); /* flush upto newline */
- yyerror(s);
- errset = prerror = TRUE;
-}
-
-extern void inityy() {
- newline = FALSE;
- w = NW;
- hq = NULL;
- /* return memory to the system if the buffer got too large */
- if (bufsize > BUFMAX && realbuf != NULL) {
- efree(realbuf);
- bufsize = BUFSIZE;
- realbuf = ealloc(bufsize);
- } else if (realbuf == NULL)
- realbuf = ealloc(bufsize);
-}
-
-extern void print_prompt2() {
- lineno++;
-#if READLINE
- prompt = prompt2;
-#else
- if (interactive)
- fprint(2, "%s", prompt2);
-#endif
-}
-
-/*
- Scan in a pair of integers for redirections like >[2=1]. CLOSED represents a closed file
- descriptor (i.e., >[2=]) and UNSET represents an undesignated file descriptor (e.g.,
- >[2] is represented as (2,UNSET).
-
- This function makes use of unsigned compares to make range tests in one compare operation.
-*/
-
-static void getpair(int c) {
- int n;
- fd_left = fd_right = UNSET;
- if (c != '[') {
- ugchar(c);
- return;
- }
- if ((unsigned int) (n = gchar() - '0') > 9) {
- scanerror("expected digit after '['");
- return;
- }
- while ((unsigned int) (c = gchar() - '0') <= 9)
- n = n * 10 + c;
- fd_left = n;
- c += '0';
- switch (c) {
- default:
- scanerror("expected '=' or ']' after digit");
- return;
- case ']':
- return;
- case '=':
- if ((unsigned int) (n = gchar() - '0') > 9) {
- if (n != ']' - '0') {
- scanerror("expected digit or ']' after '='");
- return;
- }
- fd_right = CLOSED;
- } else {
- while ((unsigned int) (c = gchar() - '0') <= 9)
- n = n * 10 + c;
- if (c != ']' - '0') {
- scanerror("expected ']' after digit");
- return;
- }
- fd_right = n;
- }
- }
-}
diff --git a/list.c b/list.c
@@ -1,57 +0,0 @@
-/* list.c: routines for manipulating the List type */
-
-#include "rc.h"
-
-/*
- These list routines assign meta values of null to the resulting lists;
- it is impossible to glob with the value of a variable unless this value
- is rescanned with eval---therefore it is safe to throw away the meta-ness
- of the list.
-*/
-
-/* free a list from malloc space */
-
-extern void listfree(List *p) {
- while (p != NULL) {
- List *n = p->n;
- efree(p->w);
- efree(p);
- p = n;
- }
-}
-
-/* Copy list into malloc space (for storing a variable) */
-
-extern List *listcpy(List *s, void *(*alloc)(size_t)) {
- List *top, *r;
- for (top = r = NULL; s != NULL; s = s->n) {
- if (top == NULL)
- r = top = (*alloc)(sizeof (List));
- else
- r = r->n = (*alloc)(sizeof (List));
- r->w = (*alloc)(strlen(s->w) + 1);
- strcpy(r->w, s->w);
- r->m = NULL;
- }
- if (r != NULL)
- r->n = NULL;
- return top;
-}
-
-/* Length of list */
-
-extern size_t listlen(List *s) {
- size_t size;
- for (size = 0; s != NULL; s = s->n)
- size += strlen(s->w) + 1;
- return size;
-}
-
-/* Number of elements in list */
-
-extern int listnel(List *s) {
- int nel;
- for (nel = 0; s != NULL; s = s->n)
- nel++;
- return nel;
-}
diff --git a/main.c b/main.c
@@ -1,121 +0,0 @@
-/* main.c: handles initialization of rc and command line options */
-
-#include "rc.h"
-
-bool dashdee, dashee, dashvee, dashex, dashell, dasheye,
- dashen, dashpee, dashess, interactive;
-pid_t rc_pid;
-
-static bool dashoh;
-
-static void assigndefault(char *,...);
-static void checkfd(int, enum redirtype);
-
-extern void main(int argc, char *argv[], char *envp[]) {
- char *dashsee[2], *dollarzero, *null[1];
- int c;
- initprint();
- dashsee[0] = dashsee[1] = NULL;
- dollarzero = argv[0];
- rc_pid = getpid();
- dashell = (*argv[0] == '-'); /* Unix tradition */
- while ((c = rc_getopt(argc, argv, "nolpeivdxsc:")) != -1)
- switch (c) {
- case 'l':
- dashell = TRUE;
- break;
- case 'e':
- dashee = TRUE;
- break;
- case 'i':
- dasheye = interactive = TRUE;
- break;
- case 'v':
- dashvee = TRUE;
- break;
- case 'x':
- dashex = TRUE;
- break;
- case 'd':
- dashdee = TRUE;
- break;
- case 's':
- dashess = dasheye = interactive = TRUE;
- break;
- case 'c':
- dashsee[0] = rc_optarg;
- goto quitopts;
- case 'n':
- dashen = TRUE;
- break;
- case 'p':
- dashpee = TRUE;
- break;
- case 'o':
- dashoh = TRUE;
- break;
- case '?':
- exit(1);
- }
-quitopts:
- argv += rc_optind;
- /* use isatty() iff -i is not set, and iff the input is not from a script or -c or -s flags */
- if (!dasheye && !dashess && dashsee[0] == NULL && *argv == NULL)
- interactive = isatty(0);
- if (!dashoh) {
- checkfd(0, rFrom);
- checkfd(1, rCreate);
- checkfd(2, rCreate);
- }
- initsignal();
- inithash();
- initparse();
- assigndefault("prompt", "; ", "", (void *)0);
-#ifdef DEFAULTPATH
- assigndefault("path", DEFAULTPATH, (void *)0);
-#endif
- assigndefault("ifs", " ", "\t", "\n", (void *)0);
- assigndefault("pid", nprint("%d", rc_pid), (void *)0);
- initenv(envp);
- initinput();
- null[0] = NULL;
- starassign(dollarzero, null, FALSE); /* assign $0 to $* */
- inithandler();
- if (dashsee[0] != NULL || dashess) { /* input from -c or -s? */
- if (*argv != NULL)
- starassign(dollarzero, argv, FALSE);
- if (dashess)
- pushfd(0);
- else
- pushstring(dashsee, TRUE);
- } else if (*argv != NULL) { /* else from a file? */
- b_dot(--argv);
- rc_exit(getstatus());
- } else { /* else stdin */
- pushfd(0);
- }
- dasheye = FALSE;
- doit(TRUE);
- rc_exit(getstatus());
-}
-
-static void assigndefault(char *name,...) {
- va_list ap;
- List *l;
- char *v;
- va_start(ap, name);
- for (l = NULL; (v = va_arg(ap, char *)) != NULL;)
- l = append(l, word(v, NULL));
- varassign(name, l, FALSE);
- if (streq(name, "path"))
- alias(name, l, FALSE);
- va_end(ap);
-}
-
-/* open an fd on /dev/null if it is inherited closed */
-
-static void checkfd(int fd, enum redirtype r) {
- int new = rc_open("/dev/null", r);
- if (new != fd && new != -1)
- close(new);
-}
diff --git a/match.c b/match.c
@@ -1,99 +0,0 @@
-/* match.c: pattern matching routines */
-
-#include "rc.h"
-
-static int rangematch(char *, char);
-
-enum { RANGE_FAIL = -1, RANGE_ERROR = -2 };
-
-/* match() matches a single pattern against a single string. */
-
-extern bool match(char *p, char *m, char *s) {
- int i, j;
- if (m == NULL)
- return streq(p, s);
- i = 0;
- while (1) {
- if (p[i] == '\0')
- return *s == '\0';
- else if (m[i]) {
- switch (p[i++]) {
- case '?':
- if (*s++ == '\0')
- return FALSE;
- break;
- case '*':
- while (p[i] == '*' && m[i] == 1) /* collapse multiple stars */
- i++;
- if (p[i] == '\0') /* star at end of pattern? */
- return TRUE;
- while (*s != '\0')
- if (match(p + i, m + i, s++))
- return TRUE;
- return FALSE;
- case '[':
- if (*s == '\0')
- return FALSE;
- switch (j = rangematch(p + i, *s)) {
- default:
- i += j;
- break;
- case RANGE_FAIL:
- return FALSE;
- case RANGE_ERROR:
- if (*s != '[')
- return FALSE;
- }
- s++;
- break;
- default:
- panic("bad metacharacter in match");
- /* NOTREACHED */
- return FALSE; /* hush up gcc -Wall */
- }
- } else if (p[i++] != *s++)
- return FALSE;
- }
-}
-
-/*
- From the ed(1) man pages (on ranges):
-
- The `-' is treated as an ordinary character if it occurs first
- (or first after an initial ^) or last in the string.
-
- The right square bracket does not terminate the enclosed string
- if it is the first character (after an initial `^', if any), in
- the bracketed string.
-
- rangematch() matches a single character against a class, and returns
- an integer offset to the end of the range on success, or -1 on
- failure.
-*/
-
-static int rangematch(char *p, char c) {
- char *orig = p;
- bool neg = (*p == '~');
- bool matched = FALSE;
- if (neg)
- p++;
- if (*p == ']') {
- p++;
- matched = (c == ']');
- }
- for (; *p != ']'; p++) {
- if (*p == '\0')
- return RANGE_ERROR; /* bad syntax */
- if (p[1] == '-' && p[2] != ']') { /* check for [..-..] but ignore [..-] */
- if (c >= *p)
- matched |= (c <= p[2]);
- p += 2;
- } else {
- matched |= (*p == c);
- }
- }
- if (matched ^ neg)
- return p - orig + 1; /* skip the right-bracket */
- else
- return RANGE_FAIL;
-}
diff --git a/mksignal b/mksignal
@@ -1,76 +0,0 @@
-#!/bin/sh
-# generate rc's internal signal table from signal.h
-
-exec > sigmsgs.c
-
-echo '#include "sigmsgs.h"'
-echo
-echo 'Sigmsgs signals[] = {'
-
-sed ' s/\/\*[ ]*//
- s/[ ]*\*\///
- s/([@*+!]) //
- s/[ ]*([a-zA-Z,->& ]*)[ ]*//
- s/^[ ]*\#[ ]*define/\#define/
- s/[ ]*signal$//
- s/_SIG/SIG/g' $1 |
-awk '
- BEGIN {
- # assign to nomesg["SIGNAME"] to suppress a long message
- nomesg["SIGINT"] = 1
- nomesg["SIGPIPE"] = 1
- # assign to mesg["SIGNAME"] to override a message
- mesg["SIGHUP"] = "hangup"
- mesg["SIGKILL"] = "killed"
- mesg["SIGQUIT"] = "quit"
- mesg["SIGTERM"] = "terminated"
- mesg["SIGURG"] = "urgent condition on i/o channel"
- mesg["SIGSTOP"] = "stop signal not from tty"
- mesg["SIGTSTP"] = "stopped"
- mesg["SIGCONT"] = "continue"
- mesg["SIGCHLD"] = "child stop or exit"
- mesg["SIGTTIN"] = "background tty read"
- mesg["SIGTTOU"] = "background tty write"
- # assign to ignore["SIGNAME"] to explicitly ignore a named signal
- ignore["SIGMAX"] = 1
- }
- $1 == "#define" && $2 == "NSIG" && $3 ~ /^[0-9]+$/ { nsig = $3 }
- $1 == "#define" && $2 ~ /^SIG/ && $3 ~ /^[0-9]+$/ && sig[$3] == "" && ignore[$2] == 0 {
- sig[$3] = $2
- if ($3 > max)
- max = $3
- if (mesg[$2] == "" && nomesg[$2] == 0) {
- str = $4
- for (i = 5; i <= NF; i++)
- str = str " " $i
- mesg[$2] = str
- }
- }
- END {
- if (nsig == 0)
- nsig = max + 1
- printf " {!!, !!},\n"
- for (i = 1; i < nsig; i++) {
- if (sig[i] == "")
- printf " {!!, !!},\n"
- else
- printf " {!%s!, !%s!},\n", sig[i], mesg[sig[i]]
- }
- }
-' |
-tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ!' 'abcdefghijklmnopqrstuvwxyz"'
-
-echo '};'
-
-exec > sigmsgs.h
-
-echo 'typedef struct {'
-echo ' char *name, *msg;'
-echo '} Sigmsgs;'
-echo 'extern Sigmsgs signals[];'
-
-grep '^ ' sigmsgs.c | # the thing in quotes is ^<tab>
-awk '
- { sum = sum + 1; }
- END { print "#define NUMOFSIGNALS", sum }
-'
diff --git a/nalloc.c b/nalloc.c
@@ -1,139 +0,0 @@
-/* nalloc.c: a simple single-arena allocator for command-line-lifetime allocation */
-#include "rc.h"
-
-static struct Block {
- size_t used, size;
- char *mem;
- Block *n;
-} *fl, *ul;
-
-/* alignto() works only with power of 2 blocks and assumes 2's complement arithmetic */
-#define alignto(m, n) ((m + n - 1) & ~(n - 1))
-#define BLOCKSIZE ((size_t) 4096)
-
-/* Allocate a block from the free list or malloc one if none in the fl fit */
-
-static void getblock(size_t n) {
- Block *r, *p;
- for (r = fl, p = NULL; r != NULL; p = r, r = r->n)
- if (n <= r->size)
- break; /* look for a block which fits the request */
- if (r != NULL) { /* if one is found, take it off the free list */
- if (p != NULL)
- p->n = r->n;
- else
- fl = r->n;
- } else { /* else allocate a new block */
- r = enew(Block);
- r->mem = ealloc(r->size = alignto(n, BLOCKSIZE));
- }
- r->used = 0;
- r->n = ul;
- ul = r;
-}
-
-/*
- A fast single-arena allocator. Looks at the current block, and if
- there is not enough room, it goes to getblock() for more. "ul"
- stands for "used list", and the head of the list is the current
- block. "ulp" is a register cache for "ul"; this routine is hacked
- for speed. (sigh, optimizing RISC compilers still can't cache the
- address of a global in a register)
-*/
-
-extern void *nalloc(size_t n) {
- size_t base;
- Block *ulp;
- n = alignto(n, sizeof(align_t));
- ulp = ul;
- if (ulp != NULL && n + (base = ulp->used) < ulp->size) {
- ulp->used = base + n;
- return &ulp->mem[base];
- } else {
- getblock(n); /* assert(ul->used) == 0 */
- (ulp = ul)->used = n;
- return &ulp->mem[0];
- }
-}
-
-/*
- Frees memory from nalloc space by putting it on the free list.
- Returns free blocks to the system, retaining at least MAXMEM bytes
- worth of blocks for nalloc.
-*/
-
-#define MAXMEM 500000
-
-extern void nfree() {
- size_t count;
- Block *r;
- if (ul == NULL)
- return;
- for (r = ul; r->n != NULL; r = r->n)
- ; /* get to end of used list */
- r->n = fl; /* tack free list onto it */
- fl = ul; /* and make it the free list */
- ul = NULL; /* finally, zero out the used list */
- for (r = fl, count = r->size; r->n != NULL; r = r->n, count += r->size) {
- if (count >= MAXMEM) {
- Block *tmp = r;
- r = r->n;
- tmp->n = NULL; /* terminate the free list */
- while (r != NULL) { /* free memory off the tail of the free list */
- tmp = r->n;
- efree(r->mem);
- efree(r);
- r = tmp;
- }
- return;
- }
- }
-}
-
-/*
- "Allocates" a new arena by zeroing out the old one. Up to the
- calling routine to keep the old value of the block around.
-*/
-
-extern Block *newblock() {
- Block *old = ul;
- ul = NULL;
- return old;
-}
-
-/* "Restores" an arena to its saved value. */
-
-extern void restoreblock(Block *old) {
- nfree();
- ul = old;
-}
-
-/* generic memory allocation functions */
-
-extern void *ealloc(size_t n) {
- extern void *malloc(size_t);
- void *p = malloc(n);
- if (p == NULL) {
- uerror("malloc");
- rc_exit(1);
- }
- return p;
-}
-
-extern void *erealloc(void *p, size_t n) {
- extern void *realloc(void *, size_t);
- if (p == NULL) /* convenience feature */
- return ealloc(n);
- if ((p = realloc(p, n)) == NULL) {
- uerror("realloc");
- rc_exit(1);
- }
- return p;
-}
-
-extern void efree(void *p) {
- extern void free(void *);
- if (p != NULL)
- free(p);
-}
-
diff --git a/open.c b/open.c
@@ -1,25 +0,0 @@
-/* open.c: to insulate <fcntl.h> from the rest of rc. */
-
-#include <fcntl.h>
-#include "rc.h"
-
-/*
- Opens a file with the necessary flags. Assumes the following
- declaration for redirtype:
-
- enum redirtype {
- rFrom, rCreate, rAppend, rHeredoc, rHerestring
- };
-*/
-
-static const int mode_masks[] = {
- /* rFrom */ O_RDONLY,
- /* rCreate */ O_TRUNC | O_CREAT | O_WRONLY,
- /* rAppend */ O_APPEND | O_CREAT | O_WRONLY
-};
-
-extern int rc_open(const char *name, redirtype m) {
- if ((unsigned) m >= arraysize(mode_masks))
- panic("bad mode passed to rc_open");
- return open(name, mode_masks[m], 0666);
-}
diff --git a/parse.y b/parse.y
@@ -1,174 +0,0 @@
-/* parse.y */
-
-/*
- * Adapted from rc grammar, v10 manuals, volume 2.
- */
-
-%{
-#include "rc.h"
-#ifndef lint
-#define lint /* hush up gcc -Wall, leave out the dumb sccsid's. */
-#endif
-static Node *star, *nolist;
-Node *parsetree; /* not using yylval because bison declares it as an auto */
-%}
-
-%token ANDAND BACKBACK BANG CASE COUNT DUP ELSE END FLAT FN FOR IF IN
-%token OROR PIPE REDIR SREDIR SUB SUBSHELL SWITCH TWIDDLE WHILE WORD HUH
-
-%left WHILE ')' ELSE
-%left ANDAND OROR '\n'
-%left BANG SUBSHELL
-%left PIPE
-%right '$'
-%left SUB
-/*
-*/
-
-%union {
- struct Node *node;
- struct Redir redir;
- struct Pipe pipe;
- struct Dup dup;
- struct Word word;
- char *keyword;
-}
-
-%type <redir> REDIR SREDIR
-%type <pipe> PIPE
-%type <dup> DUP
-%type <word> WORD
-%type <keyword> keyword
-%type <node> assign body brace case cbody cmd cmdsa cmdsan comword epilog
- first line nlwords paren redir sword simple iftail word words
-
-%start rc
-
-%%
-
-rc : line end { parsetree = $1; YYACCEPT; }
- | error end { yyerrok; parsetree = NULL; YYABORT; }
-
-/* an rc line may end in end-of-file as well as newline, e.g., rc -c 'ls' */
-end : END /* EOF */ { if (!heredoc(1)) YYABORT; } /* flag error if there is a heredoc in the queue */
- | '\n' { if (!heredoc(0)) YYABORT; } /* get heredoc on \n */
-
-/* a cmdsa is a command followed by ampersand or newline (used in "line" and "body") */
-cmdsa : cmd ';'
- | cmd '&' { $$ = ($1 != NULL ? mk(nNowait,$1) : $1); }
-
-/* a line is a single command, or a command terminated by ; or & followed by a line (recursive) */
-line : cmd
- | cmdsa line { $$ = ($1 != NULL ? mk(nBody,$1,$2) : $2); }
-
-/* a body is like a line, only commands may also be terminated by newline */
-body : cmd
- | cmdsan body { $$ = ($1 == NULL ? $2 : $2 == NULL ? $1 : mk(nBody,$1,$2)); }
-
-cmdsan : cmdsa
- | cmd '\n' { $$ = $1; if (!heredoc(0)) YYABORT; } /* get h.d. on \n */
-
-brace : '{' body '}' { $$ = $2; }
-
-paren : '(' body ')' { $$ = $2; }
-
-assign : first '=' word { $$ = mk(nAssign,$1,$3); }
-
-epilog : { $$ = NULL; }
- | redir epilog { $$ = mk(nEpilog,$1,$2); }
-
-/* a redirection is a dup (e.g., >[1=2]) or a file redirection. (e.g., > /dev/null) */
-redir : DUP { $$ = mk(nDup,$1.type,$1.left,$1.right); }
- | REDIR word { $$ = mk(nRedir,$1.type,$1.fd,$2);
- if ($1.type == rHeredoc && !qdoc($2, $$)) YYABORT; /* queue heredocs up */
- }
- | SREDIR word { $$ = mk(nRedir,$1.type,$1.fd,$2);
- if ($1.type == rHeredoc && !qdoc($2, $$)) YYABORT; /* queue heredocs up */
- }
-
-case : CASE words ';' { $$ = mk(nCase, $2); }
- | CASE words '\n' { $$ = mk(nCase, $2); }
-
-cbody : cmd { $$ = mk(nCbody, $1, NULL); }
- | case cbody { $$ = mk(nCbody, $1, $2); }
- | cmdsan cbody { $$ = mk(nCbody, $1, $2); }
-
-iftail : cmd %prec ELSE
- | brace ELSE optnl cmd { $$ = mk(nElse,$1,$4); }
-
-cmd : /* empty */ %prec WHILE { $$ = NULL; }
- | simple
- | brace epilog { $$ = mk(nBrace,$1,$2); }
- | IF paren optnl iftail { $$ = mk(nIf,$2,$4); }
- | FOR '(' word IN words ')' optnl cmd { $$ = mk(nForin,$3,$5,$8); }
- | FOR '(' word ')' optnl cmd { $$ = mk(nForin,$3,star,$6); }
- | WHILE paren optnl cmd { $$ = mk(nWhile,$2,$4); }
- | SWITCH '(' word ')' optnl '{' cbody '}' { $$ = mk(nSwitch,$3,$7); }
- | TWIDDLE optcaret word words { $$ = mk(nMatch,$3,$4); }
- | cmd ANDAND optnl cmd { $$ = mk(nAndalso,$1,$4); }
- | cmd OROR optnl cmd { $$ = mk(nOrelse,$1,$4); }
- | cmd PIPE optnl cmd { $$ = mk(nPipe,$2.left,$2.right,$1,$4); }
- | redir cmd %prec BANG { $$ = ($2 != NULL ? mk(nPre,$1,$2) : $1); }
- | assign cmd %prec BANG { $$ = ($2 != NULL ? mk(nPre,$1,$2) : $1); }
- | BANG optcaret cmd { $$ = mk(nBang,$3); }
- | SUBSHELL optcaret cmd { $$ = mk(nSubshell,$3); }
- | FN words brace { $$ = mk(nNewfn,$2,$3); }
- | FN words { $$ = mk(nRmfn,$2); }
-
-optcaret : /* empty */
- | '^'
-
-simple : first
- | simple word { $$ = ($2 != NULL ? mk(nArgs,$1,$2) : $1); }
- | simple redir { $$ = mk(nArgs,$1,$2); }
-
-first : comword
- | first '^' sword { $$ = mk(nConcat,$1,$3); }
-
-sword : comword
- | keyword { $$ = mk(nWord,$1, NULL); }
-
-word : sword
- | word '^' sword { $$ = mk(nConcat,$1,$3); }
-
-comword : '$' sword { $$ = mk(nVar,$2); }
- | '$' sword SUB words ')' { $$ = mk(nVarsub,$2,$4); }
- | COUNT sword { $$ = mk(nCount,$2); }
- | FLAT sword { $$ = mk(nFlat, $2); }
- | '`' sword { $$ = mk(nBackq,nolist,$2); }
- | '`' brace { $$ = mk(nBackq,nolist,$2); }
- | BACKBACK word brace { $$ = mk(nBackq,$2,$3); }
- | BACKBACK word sword { $$ = mk(nBackq,$2,$3); }
- | '(' nlwords ')' { $$ = $2; }
- | REDIR brace { $$ = mk(nNmpipe,$1.type,$1.fd,$2); }
- | WORD { $$ = ($1.w[0] == '\'') ? mk(nQword, $1.w+1, NULL) : mk(nWord,$1.w, $1.m); }
-
-keyword : FOR { $$ = "for"; }
- | IN { $$ = "in"; }
- | WHILE { $$ = "while"; }
- | IF { $$ = "if"; }
- | SWITCH { $$ = "switch"; }
- | FN { $$ = "fn"; }
- | ELSE { $$ = "else"; }
- | CASE { $$ = "case"; }
- | TWIDDLE { $$ = "~"; }
- | BANG { $$ = "!"; }
- | SUBSHELL { $$ = "@"; }
-
-words : { $$ = NULL; }
- | words word { $$ = ($1 != NULL ? ($2 != NULL ? mk(nLappend,$1,$2) : $1) : $2); }
-
-nlwords : { $$ = NULL; }
- | nlwords '\n'
- | nlwords word { $$ = ($1 != NULL ? ($2 != NULL ? mk(nLappend,$1,$2) : $1) : $2); }
-
-optnl : /* empty */
- | optnl '\n'
-
-%%
-
-void initparse() {
- star = treecpy(mk(nVar,mk(nWord,"*",NULL)), ealloc);
- nolist = treecpy(mk(nVar,mk(nWord,"ifs",NULL)), ealloc);
-}
-
diff --git a/print.c b/print.c
@@ -1,482 +0,0 @@
-/* print.c -- formatted printing routines (Paul Haahr, 12/91) */
-
-#include "rc.h"
-#include <setjmp.h>
-
-#define PRINT_ALLOCSIZE ((size_t)64)
-#define SPRINT_BUFSIZ ((size_t)1024)
-
-#define MAXCONV 256
-
-/*
- * conversion functions
- * true return -> flag changes only, not a conversion
- */
-
-#define Flag(name, flag) \
-static bool name(Format *format, int c) { \
- format->flags |= flag; \
- return TRUE; \
-}
-
-Flag(uconv, FMT_unsigned)
-Flag(hconv, FMT_short)
-Flag(lconv, FMT_long)
-
-#if HAVE_QUAD_T
-Flag(qconv, FMT_quad)
-#endif
-
-Flag(altconv, FMT_altform)
-Flag(leftconv, FMT_leftside)
-Flag(dotconv, FMT_f2set)
-
-static bool digitconv(Format *format, int c) {
- if (format->flags & FMT_f2set)
- format->f2 = 10 * format->f2 + c - '0';
- else {
- format->flags |= FMT_f1set;
- format->f1 = 10 * format->f1 + c - '0';
- }
- return TRUE;
-}
-
-static bool zeroconv(Format *format, int c) {
- if (format->flags & (FMT_f1set | FMT_f2set))
- return digitconv(format, '0');
- format->flags |= FMT_zeropad;
- return TRUE;
-}
-
-static void pad(Format *format, size_t len, int c) {
- while (len-- != 0)
- fmtputc(format, c);
-}
-
-static bool sconv(Format *format, int c) {
- char *s = va_arg(format->args, char *);
- if ((format->flags & FMT_f1set) == 0)
- fmtcat(format, s);
- else {
- size_t len = strlen(s), width = format->f1 - len;
- if (format->flags & FMT_leftside) {
- fmtappend(format, s, len);
- pad(format, width, ' ');
- } else {
- pad(format, width, ' ');
- fmtappend(format, s, len);
- }
- }
- return FALSE;
-}
-
-static char *utoa(unsigned long u, char *t, unsigned int radix, const char *digit) {
- if (u >= radix) {
- t = utoa(u / radix, t, radix, digit);
- u %= radix;
- }
- *t++ = digit[u];
- return t;
-}
-
-static void intconv(Format *format, unsigned int radix, int upper, const char *altform) {
- static const char * const table[] = {
- "0123456789abcdefghijklmnopqrstuvwxyz",
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",
- };
- char padchar;
- size_t len, pre, zeroes, padding, width;
- long n, flags;
- unsigned long u;
- char number[64], prefix[20];
-
- if (radix > 36)
- return;
-
- flags = format->flags;
-
-#if HAVE_QUAD_T
- if (flags & FMT_quad)
- n = va_arg(format->args, quad_t);
- else
-#endif
-
- if (flags & FMT_long)
- n = va_arg(format->args, long);
- else if (flags & FMT_short)
- n = va_arg(format->args, short);
- else
- n = va_arg(format->args, int);
-
- pre = 0;
- if ((flags & FMT_unsigned) || n >= 0)
- u = n;
- else {
- prefix[pre++] = '-';
- u = -n;
- }
-
- if (flags & FMT_altform)
- while (*altform != '\0')
- prefix[pre++] = *altform++;
-
- len = utoa(u, number, radix, table[upper]) - number;
- if ((flags & FMT_f2set) && (size_t) format->f2 > len)
- zeroes = format->f2 - len;
- else
- zeroes = 0;
-
- width = pre + zeroes + len;
- if ((flags & FMT_f1set) && (size_t) format->f1 > width) {
- padding = format->f1 - width;
- } else
- padding = 0;
-
- padchar = ' ';
- if (padding > 0 && flags & FMT_zeropad) {
- padchar = '0';
- if ((flags & FMT_leftside) == 0) {
- zeroes += padding;
- padding = 0;
- }
- }
-
-
- if ((flags & FMT_leftside) == 0)
- pad(format, padding, padchar);
- fmtappend(format, prefix, pre);
- pad(format, zeroes, '0');
- fmtappend(format, number, len);
- if (flags & FMT_leftside)
- pad(format, padding, padchar);
-}
-
-static bool cconv(Format *format, int c) {
- fmtputc(format, va_arg(format->args, int));
- return FALSE;
-}
-
-static bool dconv(Format *format, int c) {
- intconv(format, 10, 0, "");
- return FALSE;
-}
-
-static bool oconv(Format *format, int c) {
- intconv(format, 8, 0, "0");
- return FALSE;
-}
-
-static bool xconv(Format *format, int c) {
- intconv(format, 16, 0, "0x");
- return FALSE;
-}
-
-static bool pctconv(Format *format, int c) {
- fmtputc(format, '%');
- return FALSE;
-}
-
-static bool badconv(Format *format, int c) {
- panic("bad conversion character in printfmt");
- /* NOTREACHED */
- return FALSE; /* hush up gcc -Wall */
-}
-
-
-/*
- * conversion table management
- */
-
-static Conv fmttab[MAXCONV];
-
-static void inittab(void) {
- int i;
- for (i = 0; i < MAXCONV; i++)
- fmttab[i] = badconv;
-
- fmttab['s'] = sconv;
- fmttab['c'] = cconv;
- fmttab['d'] = dconv;
- fmttab['o'] = oconv;
- fmttab['x'] = xconv;
- fmttab['%'] = pctconv;
-
- fmttab['u'] = uconv;
- fmttab['h'] = hconv;
- fmttab['l'] = lconv;
- fmttab['#'] = altconv;
- fmttab['-'] = leftconv;
- fmttab['.'] = dotconv;
-
-#if HAVE_QUAD_T
- fmttab['q'] = qconv;
-#endif
-
- fmttab['0'] = zeroconv;
- for (i = '1'; i <= '9'; i++)
- fmttab[i] = digitconv;
-}
-
-extern bool (*fmtinstall(int c, bool (*f)(Format *, int)))(Format *, int) {
-/*Conv fmtinstall(int c, Conv f) {*/
- Conv oldf;
- if (fmttab[0] == NULL)
- inittab();
- c &= MAXCONV - 1;
- oldf = fmttab[c];
- if (f != NULL)
- fmttab[c] = f;
- return oldf;
-}
-
-
-/*
- * functions for inserting strings in the format buffer
- */
-
-extern void fmtappend(Format *format, const char *s, size_t len) {
- while (format->buf + len > format->bufend) {
- size_t split = format->bufend - format->buf;
- memcpy(format->buf, s, split);
- format->buf += split;
- s += split;
- len -= split;
- (*format->grow)(format, len);
- }
- memcpy(format->buf, s, len);
- format->buf += len;
-}
-
-extern void fmtcat(Format *format, const char *s) {
- fmtappend(format, s, strlen(s));
-}
-
-/*
- * printfmt -- the driver routine
- */
-
-extern int printfmt(Format *format, const char *fmt) {
- unsigned const char *s = (unsigned const char *) fmt;
-
- if (fmttab[0] == NULL)
- inittab();
-
- for (;;) {
- int c = *s++;
- switch (c) {
- case '%':
- format->flags = format->f1 = format->f2 = 0;
- do
- c = *s++;
- while ((*fmttab[c])(format, c));
- break;
- case '\0':
- return format->buf - format->bufbegin + format->flushed;
- default:
- fmtputc(format, c);
- break;
- }
- }
-}
-
-
-/*
- * the public entry points
- */
-
-extern int fmtprint(Format *format, const char *fmt,...) {
- int n = -format->flushed;
- va_list ap, saveargs;
-
- va_start(ap, fmt);
- saveargs = format->args;
- format->args = ap;
- n += printfmt(format, fmt);
- va_end(format->args);
- format->args = saveargs;
-
- return n + format->flushed;
-}
-
-static void fprint_flush(Format *format, size_t more) {
- size_t n = format->buf - format->bufbegin;
- char *buf = format->bufbegin;
-
- format->flushed += n;
- format->buf = format->bufbegin;
- writeall(format->u.n, buf, n);
-}
-
-extern int fprint(int fd, const char *fmt,...) {
- char buf[1024];
- Format format;
- va_list ap;
-
- format.buf = buf;
- format.bufbegin = buf;
- format.bufend = buf + sizeof buf;
- format.grow = fprint_flush;
- format.flushed = 0;
- format.u.n = fd;
-
- va_start(ap, fmt);
- format.args = ap;
- printfmt(&format, fmt);
- va_end(format.args);
-
- fprint_flush(&format, 0);
- return format.flushed;
-}
-
-static void memprint_grow(Format *format, size_t more) {
- char *buf;
- size_t len = format->bufend - format->bufbegin + 1;
- len = (len >= more)
- ? len * 2
- : ((len + more) + PRINT_ALLOCSIZE) &~ (PRINT_ALLOCSIZE - 1);
- if (format->u.n)
- buf = erealloc(format->bufbegin, len);
- else {
- size_t used = format->buf - format->bufbegin;
- buf = nalloc(len);
- memcpy(buf, format->bufbegin, used);
- }
- format->buf = buf + (format->buf - format->bufbegin);
- format->bufbegin = buf;
- format->bufend = buf + len - 1;
-}
-
-static char *memprint(Format *format, const char *fmt, char *buf, size_t len) {
- format->buf = buf;
- format->bufbegin = buf;
- format->bufend = buf + len - 1;
- format->grow = memprint_grow;
- format->flushed = 0;
- printfmt(format, fmt);
- *format->buf = '\0';
- return format->bufbegin;
-}
-
-extern char *mprint(const char *fmt,...) {
- Format format;
- char *result;
- va_list ap;
-
- format.u.n = 1;
- va_start(ap, fmt);
- format.args = ap;
- result = memprint(&format, fmt, ealloc(PRINT_ALLOCSIZE), PRINT_ALLOCSIZE);
- va_end(format.args);
- return result;
-}
-
-extern char *nprint(const char *fmt,...) {
- Format format;
- char *result;
- va_list ap;
-
- format.u.n = 0;
- va_start(ap, fmt);
- format.args = ap;
- result = memprint(&format, fmt, nalloc(PRINT_ALLOCSIZE), PRINT_ALLOCSIZE);
- va_end(format.args);
- return result;
-}
-
-
-/* THESE ARE UNUSED IN rc */
-
-#if 0
-
-extern int print(const char *fmt,...) {
- char buf[1024];
- Format format;
-
- format.buf = buf;
- format.bufbegin = buf;
- format.bufend = buf + sizeof buf;
- format.grow = fprint_flush;
- format.flushed = 0;
- format.u.n = 1;
-
- va_start(format.args, fmt);
- printfmt(&format, fmt);
- va_end(format.args);
-
- fprint_flush(&format, 0);
- return format.flushed;
-}
-
-extern int eprint(const char *fmt,...) {
- char buf[1024];
- Format format;
-
- format.buf = buf;
- format.bufbegin = buf;
- format.bufend = buf + sizeof buf;
- format.grow = fprint_flush;
- format.flushed = 0;
- format.u.n = 2;
-
- va_start(format.args, fmt);
- printfmt(&format, fmt);
- va_end(format.args);
-
- fprint_flush(&format, 0);
- return format.flushed;
-}
-
-static void snprint_grow(Format *format, size_t more) {
- longjmp(format->u.p, 1);
-}
-
-extern int snprint(char *buf, int buflen, const char *fmt,...) {
- int n;
- jmp_buf jbuf;
- Format format;
-
- if (setjmp(jbuf)) {
- *format.buf = '\0';
- return format.buf - format.bufbegin;
- }
-
- format.buf = buf;
- format.bufbegin = buf;
- format.bufend = buf + buflen - 1;
- format.grow = snprint_grow;
- format.flushed = 0;
- format.u.p = jbuf;
-
- va_start(format.args, fmt);
- n = printfmt(&format, fmt);
- va_end(format.args);
-
- *format.buf = '\0';
- return n;
-}
-
-extern int sprint(char *buf, const char *fmt,...) {
- int n;
- jmp_buf jbuf;
- Format format;
-
- if (setjmp(jbuf)) {
- *format.buf = '\0';
- return format.buf - format.bufbegin;
- }
-
- format.buf = buf;
- format.bufbegin = buf;
- format.bufend = buf + SPRINT_BUFSIZ - 1;
- format.grow = snprint_grow;
- format.flushed = 0;
- format.u.p = jbuf;
-
- va_start(format.args, fmt);
- n = printfmt(&format, fmt);
- va_end(format.args);
-
- *format.buf = '\0';
- return n;
-}
-#endif
diff --git a/proto.h b/proto.h
@@ -1,40 +0,0 @@
-#if HAVE_QUAD_T
-typedef quad_t align_t;
-#else
-typedef long align_t;
-#endif
-
-/* If you need to change this, please let the maintainer know. */
-#ifndef SIG_ATOMIC_T
-typedef int SIG_ATOMIC_T;
-#endif
-
-#if STDC_HEADERS
-#include <stdlib.h>
-#else
-/* fake stdlib.h */
-extern void exit(int);
-extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
-#endif
-
-#if STDC_HEADERS
-#include <string.h>
-#else
-/* fake string.h */
-extern int strncmp(const char *, const char *, size_t);
-extern int strcmp(const char *, const char *);
-extern size_t strlen(const char *);
-extern char *strchr(const char *, int);
-extern char *strrchr(const char *, int);
-extern char *strcpy(char *, const char *);
-extern char *strncpy(char *, const char *, size_t);
-extern char *strcat(char *, const char *);
-extern char *strncat(char *, const char *, size_t);
-extern void *memcpy(void *, const void *, size_t);
-extern void *memset(void *, int, size_t);
-#endif
-
-/* fake errno.h for mips (which doesn't declare errno in errno.h!?!?) */
-#ifdef host_mips
-extern int errno;
-#endif
diff --git a/rc.1 b/rc.1
@@ -1,1881 +0,0 @@
-.\" rc.1
-.\"-------
-.\" Man page portability notes
-.\"
-.\" These are some notes on conventions to maintain for greatest
-.\" portability of this man page to various other versions of
-.\" nroff.
-.\"
-.\" When you want a \ to appear in the output, use \e in the man page.
-.\" (NOTE this comes up in the rc grammar, where to print out '\n' the
-.\" man page must contain '\en'.)
-.\"
-.\" Evidently not all versions of nroff allow the omission of the
-.\" terminal " on a macro argument. Thus what could be written
-.\"
-.\" .Cr "exec >[2] err.out
-.\"
-.\" in true nroffs must be written
-.\"
-.\" .Cr "exec >[2] err.out"
-.\"
-.\" instead.
-.\"
-.\" Use symbolic font names (e.g. R, I, B) instead of the standard
-.\" font positions 1, 2, 3. Note that for Xf to work the standard
-.\" font names must be single characters.
-.\"
-.\" Not all man macros have the RS and RE requests (I altered the Ds
-.\" and De macros and the calls to Ds accordingly).
-.\"
-.\" Thanks to Michael Haardt (u31b3hs@cip-s01.informatik.rwth-aachen.de)
-.\" for pointing out these problems.
-.\"
-.\" Note that sentences should end at the end of a line. nroff and
-.\" troff will supply the correct intersentence spacing, but only if
-.\" the sentences end at the end of a line. Explicit spaces, if given,
-.\" are apparently honored and the normal intersentence spacing is
-.\" supressed.
-.\"
-.\" DaviD W. Sanderson
-.\"-------
-.\" Dd distance to space vertically before a "display"
-.\" These are what n/troff use for interparagraph distance
-.\"-------
-.if t .nr Dd .4v
-.if n .nr Dd 1v
-.\"-------
-.\" Ds begin a display, indented .5 inches from the surrounding text.
-.\"
-.\" Note that uses of Ds and De may NOT be nested.
-.\"-------
-.de Ds
-.\" .RS \\$1
-.sp \\n(Ddu
-.in +0.5i
-.nf
-..
-.\"-------
-.\" De end a display (no trailing vertical spacing)
-.\"-------
-.de De
-.fi
-.in
-.\" .RE
-..
-.\"-------
-.\" I stole the Xf macro from the -man macros on my machine (originally
-.\" "}S", I renamed it so that it won't conflict).
-.\"-------
-.\" Set Cf to the name of the constant width font.
-.\" It will be "C" or "(CW", typically.
-.\" NOTEZ BIEN the lines defining Cf must have no trailing white space:
-.\"-------
-.if t .ds Cf C
-.if n .ds Cf R
-.\"-------
-.\" Rc - Alternate Roman and Courier
-.\"-------
-.de Rc
-.Xf R \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Ic - Alternate Italic and Courier
-.\"-------
-.de Ic
-.Xf I \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Bc - Alternate Bold and Courier
-.\"-------
-.de Bc
-.Xf B \\*(Cf \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Cr - Alternate Courier and Roman
-.\"-------
-.de Cr
-.Xf \\*(Cf R \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Ci - Alternate Courier and Italic
-.\"-------
-.de Ci
-.Xf \\*(Cf I \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Cb - Alternate Courier and Bold
-.\"-------
-.de Cb
-.Xf \\*(Cf B \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
-..
-.\"-------
-.\" Xf - Alternate fonts
-.\"
-.\" \$1 - first font
-.\" \$2 - second font
-.\" \$3 - desired word with embedded font changes, built up by recursion
-.\" \$4 - text for first font
-.\" \$5 - \$9 - remaining args
-.\"
-.\" Every time we are called:
-.\"
-.\" If there is something in \$4
-.\" then Call ourself with the fonts switched,
-.\" with a new word made of the current word (\$3) and \$4
-.\" rendered in the first font,
-.\" and with the remaining args following \$4.
-.\" else We are done recursing. \$3 holds the desired output
-.\" word. We emit \$3, change to Roman font, and restore
-.\" the point size to the default.
-.\" fi
-.\"
-.\" Use Xi to add a little bit of space after italic text.
-.\"-------
-.de Xf
-.ds Xi
-.\"-------
-.\" I used to test for the italic font both by its font position
-.\" and its name. Now just test by its name.
-.\"
-.\" .if "\\$1"2" .if !"\\$5"" .ds Xi \^
-.\"-------
-.if "\\$1"I" .if !"\\$5"" .ds Xi \^
-.\"-------
-.\" This is my original code to deal with the recursion.
-.\" Evidently some nroffs can't deal with it.
-.\"-------
-.\" .ie !"\\$4"" \{\
-.\" . Xf \\$2 \\$1 "\\$3\\f\\$1\\$4\\*(Xi" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
-.\" .\}
-.\" .el \{\\$3
-.\" . ft R \" Restore the default font, since we don't know
-.\" . \" what the last font change was.
-.\" . ps 10 \" Restore the default point size, since it might
-.\" . \" have been changed by an argument to this macro.
-.\" .\}
-.\"-------
-.\" Here is more portable (though less pretty) code to deal with
-.\" the recursion.
-.\"-------
-.if !"\\$4"" .Xf \\$2 \\$1 "\\$3\\f\\$1\\$4\\*(Xi" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
-.if "\\$4"" \\$3\fR\s10
-..
-.TH RC 1 "28 April 1991"
-.SH NAME
-rc \- shell
-.SH SYNOPSIS
-.B rc
-.RB [ \-eixvldnpo ]
-.RB [ \-c
-.IR command ]
-.RI [ arguments ]
-.SH DESCRIPTION
-.I rc
-is a command interpreter and programming language similar to
-.IR sh (1).
-It is based on the AT&T Plan 9 shell of the same name.
-The shell offers a C-like syntax (much more so than the C shell),
-and a powerful mechanism for manipulating variables.
-It is reasonably small and reasonably fast,
-especially when compared to contemporary shells.
-Its use is intended to be interactive,
-but the language lends itself well to scripts.
-.SH OPTIONS
-.TP
-.Cr \-e
-If the
-.Cr \-e
-option is present, then
-.I rc
-will exit if the exit status of a command is false (nonzero).
-.I rc
-will not exit, however, if a conditional fails, e.g., an
-.Cr if()
-command.
-.TP
-.Cr \-i
-If the
-.Cr \-i
-option is present or if the input to
-.I rc
-is from a terminal (as determined by
-.IR isatty (3))
-then
-.I rc
-will be in
-.I interactive
-mode.
-That is, a prompt (from
-.Cr $prompt(1)\^ )
-will be printed before an
-input line is taken, and
-.I rc
-will ignore the signals
-.Cr SIGINT
-and
-.Cr SIGQUIT .
-.TP
-.Cr \-x
-This option will make
-.I rc
-print every command on standard error before it is executed.
-It can be useful for debugging
-.I rc
-scripts.
-.TP
-.Cr \-v
-This option will echo input to
-.I rc
-on standard error as it is read.
-.TP
-.Cr \-l
-If the
-.Cr \-l
-option is present, or if
-.IR rc 's
-.Cr argv[0][0]
-is a dash
-.Rc ( \- ),
-then
-.I rc
-will behave as a login shell.
-That is, it will try to run commands present in
-.Cr $home/.rcrc ,
-if this file exists, before reading any other input.
-.TP
-.Cr \-d
-This flag causes
-.I rc
-not to ignore
-.Cr SIGQUIT
-or
-.Cr SIGTERM .
-Thus
-.I rc
-can be made to dump core if sent
-.Cr SIGQUIT .
-This option is only useful for debugging
-.IR rc .
-.TP
-.Cr \-n
-This flag causes
-.I rc
-to read its input and parse it, but not to execute any commands.
-This is useful for syntax checking on scripts.
-If used in combination with the
-.Cr \-x
-option,
-.I rc
-will print each command as it is parsed in a form similar to the one
-used for exporting functions into the environment.
-.TP
-.Cr \-p
-This flag prevents
-.I rc
-from initializing shell functions from the environment.
-This allows
-.I rc
-to run in a protected mode, whereby it becomes more difficult for
-an
-.I rc
-script to be subverted by placing false commands in the environment.
-(Note that this presence of this option does NOT mean that it is safe to
-run setuid
-.I rc
-scripts; the usual caveats about the setuid bit still apply.)
-.TP
-.Cr \-o
-This flag prevents the usual practice of trying to open
-.Cr /dev/null
-on file descriptors 0, 1, and 2, if any of those descriptors
-are inherited closed.
-.TP
-.Cr \-c
-If
-.Cr \-c
-is present, commands are executed from the immediately following
-argument.
-Any further arguments to
-.I rc
-are placed in
-.Cr $* .
-.PP
-.SH COMMANDS
-A simple command is a sequence of words, separated by white space
-(space and tab) characters that ends with a newline, semicolon
-.Rc ( ; ),
-or ampersand
-.Rc ( & ).
-The first word of a command is the name of that command.
-If the name begins with
-.Cr / ,
-.Cr ./ ,
-or
-.Cr ../ ,
-then the name is used as an absolute path
-name referring to an executable file.
-Otherwise, the name of the command is looked up in a table
-of shell functions, builtin commands,
-or as a file in the directories named by
-.Cr $path .
-.SS "Background Tasks"
-A command ending with a
-.Cr &
-is run in the background; that is,
-the shell returns immediately rather than waiting for the command to
-complete.
-Background commands have
-.Cr /dev/null
-connected to their standard input unless an explicit redirection for
-standard input is used.
-.SS "Subshells"
-A command prefixed with an at-sign
-.Rc ( @ )
-is executed in a subshell.
-This insulates the parent shell from the effects
-of state changing operations such as a
-.B cd
-or a variable assignment.
-For example:
-.Ds
-.Cr "@ {cd ..; make}"
-.De
-.PP
-will run
-.IR make (1)
-in the parent directory
-.Rc ( .. ),
-but leaves the shell running in the current directory.
-.SS "Line continuation"
-A long logical line may be continued over several physical lines by
-terminating each line (except the last) with a backslash
-.Rc ( \e ).
-The backslash-newline sequence is treated as a space.
-A backslash is not otherwise special to
-.IR rc .
-(In addition,
-inside quotes a backslash loses its special meaning
-even when it is followed by a newline.)
-.SS Quoting
-.IR rc
-interprets several characters specially; special characters
-automatically terminate words.
-The following characters are special:
-.Ds
-.Cr "# ; & | ^ $ = \` ' { } ( ) < >"
-.De
-.PP
-The single quote
-.Rc ( ' )
-prevents special treatment of any character other than itself.
-All characters, including control characters, newlines,
-and backslashes between two quote characters are treated as an
-uninterpreted string.
-A quote character itself may be quoted by placing two quotes in a row.
-The minimal sequence needed to enter the quote character is
-.Cr '''' .
-The empty string is represented by
-.Cr '' .
-Thus:
-.Ds
-.Cr "echo 'What''s the plan, Stan?'"
-.De
-.PP
-prints out
-.Ds
-.Cr "What's the plan, Stan?"
-.De
-.PP
-The number sign
-.Rc ( # )
-begins a comment in
-.IR rc .
-All characters up to but not including the next newline are ignored.
-Note that backslash continuation does not work inside a comment,
-i.e.,
-the backslash is ignored along with everything else.
-.SS Grouping
-Zero or more commands may be grouped within braces
-.Rc (`` { ''
-and
-.Rc `` } ''),
-and are then treated as one command.
-Braces do not otherwise define scope;
-they are used only for command grouping.
-In particular, be wary of the command:
-.Ds
-.Cr "for (i) {"
-.Cr " command"
-.Cr "} | command"
-.De
-.PP
-Since pipe binds tighter than
-.Cr for ,
-this command does not perform what the user expects it to.
-Instead, enclose the whole
-.Cr for
-statement in braces:
-.Ds
-.Cr "{for (i) command} | command"
-.De
-.PP
-Fortunately,
-.IR rc 's
-grammar is simple enough that a (confident) user can
-understand it by examining the skeletal
-.IR yacc (1)
-grammar
-at the end of this man page (see the section entitled
-.BR GRAMMAR ).
-.SS "Input and output"
-.PP
-The standard output may be redirected to a file with
-.Ds
-.Cr "command > file"
-.De
-.PP
-and the standard input may be taken from a file with
-.Ds
-.Cr "command < file"
-.De
-.PP
-File descriptors other than 0 and 1 may be specified also.
-For example, to redirect standard error to a file, use:
-.Ds
-.Cr "command >[2] file"
-.De
-.PP
-In order to duplicate a file descriptor, use
-.Ci >[ n = m ]\fR.
-Thus to redirect both standard output and standard error
-to the same file, use
-.Ds
-.Cr "command > file >[2=1]"
-.De
-.PP
-To close a file descriptor that may be open, use
-.Ci >[ n =]\fR.
-For example, to
-close file descriptor 7:
-.Ds
-.Cr "command >[7=]"
-.De
-.PP
-In order to place the output of a command at the end of an already
-existing file, use:
-.Ds
-.Cr "command >> file"
-.De
-.PP
-If the file does not exist, then it is created.
-.PP
-``Here documents'' are supported as in
-.I sh
-with the use of
-.Ds
-.Cr "command << 'eof-marker'"
-.De
-.PP
-If the end-of-file marker is enclosed in quotes,
-then no variable substitution occurs inside the here document.
-Otherwise, every variable is substituted
-by its space-separated-list value (see
-.BR "Flat Lists" ,
-below),
-and if a
-.Cr ^
-character follows a variable name, it is deleted.
-This allows the unambiguous use of variables adjacent to text, as in
-.Ds
-.Cr $variable^follow
-.De
-.PP
-To include a literal
-.Cr $
-in a here document when an unquoted end-of-file marker is being used,
-enter it as
-.Cr $$ .
-.PP
-Additionally,
-.I rc
-supports ``here strings'', which are like here documents,
-except that input is taken directly from a string on the command line.
-Its use is illustrated here:
-.Ds
-.Cr "cat <<< 'this is a here string' | wc"
-.De
-.PP
-(This feature enables
-.I rc
-to export functions using here documents into the environment;
-the author does not expect users to find this feature useful.)
-.SS Pipes
-Two or more commands may be combined in a pipeline by placing the
-vertical bar
-.Rc ( \||\| )
-between them.
-The standard output (file descriptor 1)
-of the command on the left is tied to the standard input (file
-descriptor 0) of the command on the right.
-The notation
-.Ci |[ n = m ]
-indicates that file descriptor
-.I n
-of the left process is connected to
-file descriptor
-.I m
-of the right process.
-.Ci |[ n ]
-is a shorthand for
-.Ci |[ n =0]\fR.
-As an example, to pipe the standard error of a command to
-.IR wc (1),
-use:
-.Ds
-.Cr "command |[2] wc"
-.De
-.PP
-The exit status of a pipeline is considered true if and only if every
-command in the pipeline exits true.
-.SS "Commands as Arguments"
-Some commands, like
-.IR cmp (1)
-or
-.IR diff (1),
-take their arguments on the command
-line, and do not read input from standard input.
-It is convenient
-sometimes to build nonlinear pipelines so that a command like
-.I cmp
-can read the output of two other commands at once.
-.I rc
-does it like this:
-.Ds
-.Cr "cmp <{command} <{command}"
-.De
-.PP
-compares the output of the two commands in braces.
-A note: since this form of
-redirection is implemented with some kind of pipe, and since one cannot
-.IR lseek (2)
-on a pipe, commands that use
-.IR lseek (2)
-will hang.
-For example,
-most versions of
-.IR diff (1)
-use
-.IR lseek (2)
-on their inputs.
-.PP
-Data can be sent down a pipe to several commands using
-.IR tee (1)
-and the output version of this notation:
-.Ds
-.Cr "echo hi there | tee >{sed 's/^/p1 /'} >{sed 's/^/p2 /'}"
-.De
-.SH "CONTROL STRUCTURES"
-The following may be used for control flow in
-.IR rc :
-.SS "If-else Statements"
-.PD 0
-.sp
-.Ci "if (" test ") {"
-.br
-.I " cmd"
-.br
-.TP
-.Ci "} else " cmd
-The
-.I test
-is executed, and if its return status is zero, the first
-command is executed, otherwise the second is.
-Braces are not mandatory around the commands.
-However, an
-.Cr else
-statement is valid only if it
-follows a close-brace on the same line.
-Otherwise, the
-.Cr if
-is taken to be a simple-if:
-.Ds
-.Cr "if (test)"
-.Cr " command"
-.De
-.PD
-.SS "While and For Loops"
-.TP
-.Ci "while (" test ) " cmd"
-.I rc
-executes the
-.I test
-and performs the command as long as the
-.I test
-is true.
-.TP
-.Ci "for (" var " in" " list" ) " cmd"
-.I rc
-sets
-.I var
-to each element of
-.I list
-(which may contain variables and backquote substitutions) and runs
-.IR cmd .
-If
-.Rc `` in
-.IR list ''
-is omitted, then
-.I rc
-will set
-.I var
-to each element of
-.Cr $*
-(excluding
-.Cr $0 ).
-For example:
-.Ds
-.Cr "for (i in \`{ls -F | grep '\e*$' | sed 's/\e*$//'}) { commands }"
-.De
-.TP
-\&
-will set
-.Cr $i
-to the name of each file in the current directory that is
-executable.
-.SS "Switch"
-.TP
-.Ci "switch (" list ") { case" " ..." " }"
-.I rc
-looks inside the braces after a
-.Cr switch
-for statements beginning with the word
-.Cr case .
-If any of the patterns following
-.Cr case
-match the list supplied to
-.Cr switch ,
-then the commands up until the next
-.Cr case
-statement are executed.
-The metacharacters
-.Cr "*" ,
-.Cr [
-or
-.Cr ?
-should not be quoted;
-matching is performed only against the strings in
-.IR list ,
-not against file names.
-(Matching for case statements is the same as for the
-.Cr ~
-command.)
-.SS "Logical Operators"
-There are a number of operators in
-.I rc
-which depend on the exit status of a command.
-.Ds
-.Cr "command && command"
-.De
-.PP
-executes the first command and then executes the second command if and only if
-the first command exits with a zero exit status (``true'' in Unix).
-.Ds
-.Cr "command || command"
-.De
-.PP
-executes the first command and then executes the second command if and only if
-the first command exits with a nonzero exit status (``false'' in Unix).
-.Ds
-.Cr "! command"
-.De
-.PP
-negates the exit status of a command.
-.SH "PATTERN MATCHING"
-There are two forms of pattern matching in
-.IR rc .
-One is traditional shell globbing.
-This occurs in matching for file names in argument lists:
-.Ds
-.Cr "command argument argument ..."
-.De
-.PP
-When the characters
-.Cr "*" ,
-.Cr [
-or
-.Cr ?
-occur in an argument or command,
-.I rc
-looks at the
-argument as a pattern for matching against files.
-(Contrary to the behavior other shells exhibit,
-.I rc
-will only perform pattern matching if a metacharacter occurs unquoted and
-literally in the input.
-Thus,
-.Ds
-.Cr "foo='*'"
-.Cr "echo $foo"
-.De
-.PP
-will always echo just a star.
-In order for non-literal metacharacters to be expanded, an
-.Cr eval
-statement must be used in order to rescan the input.)
-Pattern matching occurs according to the following rules: a
-.Cr *
-matches any number (including zero) of
-characters.
-A
-.Cr ?
-matches any single character, and a
-.Cr [
-followed by a
-number of characters followed by a
-.Cr ]
-matches a single character in that
-class.
-The rules for character class matching are the same as those for
-.IR ed (1),
-with the exception that character class negation is achieved
-with the tilde
-.Rc ( ~ ),
-not the caret
-.Rc ( ^ ),
-since the caret already means
-something else in
-.IR rc .
-.PP
-.I rc
-also matches patterns against strings with the
-.Cr ~
-command:
-.Ds
-.Cr "~ subject pattern pattern ..."
-.De
-.PP
-.Cr ~
-sets
-.Cr $status
-to zero if and only if a supplied pattern matches any
-single element of the subject list.
-Thus
-.Ds
-.Cr "~ foo f*"
-.De
-.PP
-sets status to zero, while
-.Ds
-.Cr "~ (bar baz) f*"
-.De
-.PP
-sets status to one.
-The null list is matched by the null list, so
-.Ds
-.Cr "~ $foo ()"
-.De
-.PP
-checks to see whether
-.Cr $foo
-is empty or not.
-This may also be achieved
-by the test
-.Ds
-.Cr "~ $#foo 0"
-.De
-.PP
-Note that inside a
-.Cr ~
-command
-.I rc
-does not match patterns against file
-names, so it is not necessary to quote the characters
-.Cr "*" ,
-.Cr [
-and
-.Cr "?" .
-However,
-.I rc
-does expand the glob the subject against filenames if it contains
-metacharacters.
-Thus, the command
-.Ds
-.Cr "~ * ?"
-.De
-.PP
-returns true if any of the files in the current directory have a
-single-character name.
-(Note that if the
-.Cr ~
-command is given a list as its first
-argument, then a successful match against any of the elements of that
-list will cause
-.Cr ~
-to return true.
-For example:
-.Ds
-.Cr "~ (foo goo zoo) z*"
-.De
-.PP
-is true.)
-.SH "LISTS AND VARIABLES"
-The primary data structure in
-.IR rc
-is the list, which is a sequence of words.
-Parentheses are used to group lists.
-The empty list is represented by
-.Cr "()" .
-Lists have no hierarchical structure;
-a list inside another list is expanded so the
-outer list contains all the elements of the inner list.
-Thus, the following are all equivalent
-.Ds
-.Cr "one two three"
-
-.Cr "(one two three)"
-
-.Cr "((one) () ((two three)))"
-.De
-.PP
-Note that the null string,
-.Cr "''" ,
-and the null list,
-.Cr "()" ,
-are two very
-different things.
-Assigning the null string to variable is a valid
-operation, but it does not remove its definition.
-For example,
-if
-.Cr $a
-is set to
-.Cr "''" ,
-then
-.Cr "$#a" ,
-returns a 1.
-.SS "List Concatenation"
-Two lists may be joined by the concatenation operator
-.Rc ( ^ ).
-A single word is treated as a list of length one, so
-.Ds
-.Cr "echo foo^bar"
-.De
-.PP
-produces the output
-.Ds
-.Cr foobar
-.De
-.PP
-For lists of more than one element,
-concatenation works according to the following rules:
-if the two lists have the same number of elements,
-then concatenation is pairwise:
-.Ds
-.Cr "echo (a\- b\- c\-)^(1 2 3)"
-.De
-.PP
-produces the output
-.Ds
-.Cr "a\-1 b\-2 c\-3"
-.De
-.PP
-Otherwise, one of the lists must have a single element,
-and then the concatenation is distributive:
-.Ds
-.Cr "cc \-^(O g c) (malloc alloca)^.c"
-.De
-.PP
-has the effect of performing the command
-.Ds
-.Cr "cc \-O \-g \-c malloc.c alloca.c"
-.De
-.SS "Free Carets"
-.I rc
-inserts carets (concatenation operators) for free in certain situations,
-in order to save some typing on the user's behalf.
-For
-example, the above example could also be typed in as:
-.Ds
-.Cr "opts=(O g c) files=(malloc alloca) cc \-$opts $files.c"
-.De
-.PP
-.I rc
-takes care to insert a free-caret between the
-.Rc `` \- ''
-and
-.Cr "$opts" ,
-as well
-as between
-.Cr $files
-and
-.Cr ".c" .
-The rule for free carets is as follows: if
-a word or keyword is immediately
-followed by another word, keyword, dollar-sign or
-backquote, then
-.I rc
-inserts a caret between them.
-.SS "Variables"
-A list may be assigned to a variable, using the notation:
-.Ds
-.Ic var " = " list
-.De
-.PP
-Any sequence of non-special characters, except a sequence including
-only digits, may be used as a variable name.
-All user-defined variables are exported into the environment.
-.PP
-The value of a variable is referenced with the notation:
-.Ds
-.Ci $ var
-.De
-.PP
-Any variable which has not been assigned a value returns the null list,
-.Cr "()" ,
-when referenced.
-In addition, multiple references are allowed:
-.Ds
-.Cr a=foo
-.Cr b=a
-.Cr "echo $$b"
-.De
-.PP
-prints
-.Ds
-.Cr foo
-.De
-.PP
-A variable's definition may also be removed by
-assigning the null list to a variable:
-.Ds
-.Ic var =()
-.De
-.PP
-For ``free careting'' to work correctly,
-.I rc
-must make certain assumptions
-about what characters may appear in a variable name.
-.I rc
-assumes that a variable name consists only of alphanumeric characters,
-underscore
-.Rc ( \|_\| )
-and star
-.Rc ( * ).
-To reference a variable with other
-characters in its name, quote the variable name.
-Thus:
-.Ds
-.Cr "echo $'we$Ird\Variab!le'"
-.De
-.SS "Local Variables"
-Any number of variable assignments may be made local to a single
-command by typing:
-.Ds
-.Cr "a=foo b=bar ... command"
-.De
-.PP
-The command may be a compound command, so for example:
-.Ds
-.Cr "path=. ifs=() {"
-.Cr " " ...
-.Cr }
-.De
-.PP
-sets
-.Cr path
-to
-.Cr .
-and removes
-.Cr ifs
-for the duration of one long compound command.
-.SS "Variable Subscripts"
-Variables may be subscripted with the notation
-.Ds
-.Ci $var( n )
-.De
-.PP
-where
-.I n
-is a list of integers (origin 1).
-The list of subscripts need
-not be in order or even unique.
-Thus, if
-.Ds
-.Cr "a=(one two three)"
-.De
-.PP
-then
-.Ds
-.Cr "echo $a(3 3 3)"
-.De
-.PP
-prints
-.Ds
-.Cr "three three three"
-.De
-.PP
-If
-.I n
-references a nonexistent element, then
-.Ci $var( n )
-returns the null list.
-The notation
-.Ci "$" n\fR,
-where
-.I n
-is an integer, is a shorthand for
-.Ci $*( n )\fR.
-Thus,
-.IR rc 's
-arguments may be referred to as
-.Cr "$1" ,
-.Cr "$2" ,
-and so on.
-.PP
-Note also that the list of subscripts may be given by any of
-.IR rc 's
-list operations:
-.Ds
-.Cr "$var(\`{awk 'BEGIN{for(i=1;i<=10;i++)print i;exit; }'})"
-.De
-.PP
-returns the first 10 elements of
-.Cr $var .
-.PP
-To count the number of elements in a variable, use
-.Ds
-.Cr $#var
-.De
-.PP
-This returns a single-element list, with the number of elements in
-.Cr $var .
-.SS "Flat Lists"
-In order to create a single-element list from a multi-element list,
-with the components space-separated, use
-.Ds
-.Cr $^var
-.De
-.PP
-This is useful when the normal list concatenation rules need to be
-bypassed.
-For example, to append a single period at the end of
-.Cr $path ,
-use:
-.Ds
-.Cr "echo $^path."
-.De
-.SS "Backquote Substitution"
-A list may be formed from the output of a command by using backquote
-substitution:
-.Ds
-.Cr "\`{ command }"
-.De
-.PP
-returns a list formed from the standard output of the command in braces.
-.Cr $ifs
-is used to split the output into list elements.
-By default,
-.Cr $ifs
-has the value space-tab-newline.
-The braces may be omitted if the command is a single word.
-Thus
-.Cr \`ls
-may be used instead of
-.Cr "\`{ls}" .
-This last feature is useful when defining functions that expand
-to useful argument lists.
-A frequent use is:
-.Ds
-.Cr "fn src { echo *.[chy] }"
-.De
-.PP
-followed by
-.Ds
-.Cr "wc \`src"
-.De
-.PP
-(This will print out a word-count of all C source files in the current
-directory.)
-.PP
-In order to override the value of
-.Cr $ifs
-for a single backquote
-substitution, use:
-.Ds
-.Cr "\`\` (ifs-list) { command }"
-.De
-.PP
-.Cr $ifs
-will be temporarily ignored and the command's output will be split as specified by
-the list following the double backquote.
-For example:
-.Ds
-.Cr "\`\` ($nl :) {cat /etc/passwd}"
-.De
-.PP
-splits up
-.Cr /etc/passwd
-into fields, assuming that
-.Cr $nl
-contains a newline
-as its value.
-.SH "SPECIAL VARIABLES"
-Several variables are known to
-.I rc
-and are treated specially.
-.TP
-.Cr *
-The argument list of
-.IR rc .
-.Cr "$1, $2,"
-etc. are the same as
-.Cr $*(1) ,
-.Cr $*(2) ,
-etc.
-The variable
-.Cr $0
-holds the value of
-.Cr argv[0]
-with which
-.I rc
-was invoked.
-Additionally,
-.Cr $0
-is set to the name of a function for the duration of
-the execution of that function, and
-.Cr $0
-is also set to the name of the
-file being interpreted for the duration of a
-.Cr .
-command.
-.TP
-.Cr apid
-The process ID of the last process started in the background.
-.TP
-.Cr apids
-The process IDs of any background processes which are outstanding
-or which have died and have not been waited for yet.
-.TP
-.Cr cdpath
-A list of directories to search for the target of a
-.B cd
-command.
-The empty string stands for the current directory.
-Note that if the
-.Cr $cdpath
-variable does not contain the current directory, then the current
-directory will not be searched; this allows directory searching to
-begin in a directory other than the current directory.
-Note also that an assignment to
-.Cr $cdpath
-causes an automatic assignment to
-.Cr $CDPATH ,
-and vice-versa.
-.TP
-.Cr history
-.Cr $history
-contains the name of a file to which commands are appended as
-.I rc
-reads them.
-This facilitates the use of a stand-alone history program
-(such as
-.IR history (1))
-which parses the contents of the history file and presents them to
-.I rc
-for reinterpretation.
-If
-.Cr $history
-is not set, then
-.I rc
-does not append commands to any file.
-.TP
-.Cr home
-The default directory for the builtin
-.B cd
-command and is the directory
-in which
-.I rc
-looks to find its initialization file,
-.Cr .rcrc ,
-if
-.I rc
-has been started up as a login shell.
-Like
-.Cr $cdpath
-and
-.Cr $CDPATH ,
-.Cr $home
-and
-.Cr $HOME
-are aliased to each other.
-.TP
-.Cr ifs
-The internal field separator, used for splitting up the output of
-backquote commands for digestion as a list.
-.TP
-.Cr path
-This is a list of directories to search in for commands.
-The empty string stands for the current directory.
-Note that like
-.Cr $cdpath
-and
-.Cr $CDPATH ,
-.Cr $path
-and
-.Cr $PATH
-are aliased to each other.
-If
-.Cr $path
-or
-.Cr $PATH
-is not set at startup time,
-.Cr $path
-assumes a default value suitable for your system.
-This is typically
-.Cr "(/usr/ucb /usr/bin /bin .)"
-.TP
-.Cr pid
-The process ID of the currently running
-.IR rc .
-.TP
-.Cr prompt
-This variable holds the two prompts (in list form, of course) that
-.I rc
-prints.
-.Cr $prompt(1)
-is printed before each command is read, and
-.Cr $prompt(2)
-is printed when input is expected to continue on the next
-line.
-.I rc
-sets
-.Cr $prompt
-to
-.Cr "('; ' '')"
-by default.
-The reason for this is that it enables an
-.I rc
-user to grab commands from previous lines using a
-mouse, and to present them to
-.I rc
-for re-interpretation; the semicolon
-prompt is simply ignored by
-.IR rc .
-The null
-.Cr $prompt(2)
-also has its
-justification: an
-.I rc
-script, when typed interactively, will not leave
-.Cr $prompt(2) 's
-on the screen,
-and can therefore be grabbed by a mouse and placed
-directly into a file for use as a shell script, without further editing
-being necessary.
-.TP
-.Cr prompt " (function)"
-If this function is set, then it gets executed every time
-.I rc
-is about to print
-.Cr "$prompt(1)" .
-.TP
-.Cr status
-The exit status of the last command.
-If the command exited with a numeric value,
-that number is the status.
-If the died with a signal,
-the status is the name of that signal; if a core file
-was created, the string
-.Rc `` +core ''
-is appended.
-The value of
-.Cr $status
-for a pipeline is a list, with one entry,
-as above, for each process in the pipeline.
-For example, the command
-.Ds
-.Cr "ls | wc"
-.De
-.TP
-\&
-usually sets
-.Cr $status
-to
-.Cr "(0 0)" .
-.PP
-The values of
-.Cr "$path" ,
-.Cr "$cdpath" ,
-and
-.Cr $home
-are derived from the environment
-values of
-.Cr "$PATH" ,
-.Cr "$CDPATH" ,
-and
-.Cr "$HOME" .
-Otherwise, they are derived from
-the environment values of
-.Cr $path ,
-.Cr $cdpath
-and
-.Cr $home .
-This is for compatibility with other Unix programs, like
-.IR sh (1).
-.Cr $PATH
-and
-.Cr $CDPATH
-are assumed to be colon-separated lists.
-.SH FUNCTIONS
-.I rc
-functions are identical to
-.I rc
-scripts, except that they are stored
-in memory and are automatically exported into the environment.
-A shell function is declared as:
-.Ds
-.Cr "fn name { commands }"
-.De
-.PP
-.I rc
-scans the definition until the close-brace, so the function can
-span more than one line.
-The function definition may be removed by typing
-.Ds
-.Cr "fn name"
-.De
-.PP
-(One or more names may be specified.
-With an accompanying definition, all names receive the same definition.
-This is sometimes useful
-for assigning the same signal handler to many signals.
-Without a definition, all named functions are deleted.)
-When a function is executed,
-.Cr $*
-is set to the arguments to that
-function for the duration of the command.
-Thus a reasonable definition for
-.Cr "l" ,
-a shorthand for
-.IR ls (1),
-could be:
-.Ds
-.Cr "fn l { ls -FC $* }"
-.De
-.PP
-but not
-.Ds
-.Cr "fn l { ls -FC }"
-.De
-.SH "INTERRUPTS AND SIGNALS"
-.I rc
-recognizes a number of signals, and allows the user to define shell
-functions which act as signal handlers.
-.I rc
-by default traps
-.Cr SIGINT
-when it is in interactive mode.
-.Cr SIGQUIT
-and
-.Cr SIGTERM
-are ignored, unless
-.I rc
-has been invoked with the
-.Cr \-d
-flag.
-However, user-defined signal handlers may be written for these and
-all other signals.
-The way to define a signal handler is to
-write a function by the name of the signal in lower case.
-Thus:
-.Ds
-.Cr "fn sighup { echo hangup; rm /tmp/rc$pid.*; exit }"
-.De
-.PP
-In addition to Unix signals,
-.I rc
-recognizes the artificial signal
-.Cr SIGEXIT
-which occurs as
-.I rc
-is about to exit.
-.PP
-In order to remove a signal handler's definition,
-remove it as though it were a regular function.
-For example:
-.Ds
-.Cr "fn sigint"
-.De
-.PP
-returns the handler of
-.Cr SIGINT
-to the default value.
-In order to ignore a signal, set the signal handler's value to
-.Cr "{}" .
-Thus:
-.Ds
-.Cr "fn sigint {}"
-.De
-.PP
-causes SIGINT to be ignored by the shell.
-Only signals that are being ignored are passed on to programs run by
-.IR rc ;
-signal functions are not exported.
-.PP
-On System V-based Unix systems,
-.I rc
-will not allow you to trap
-.Cr SIGCLD .
-.SH "BUILTIN COMMANDS"
-Builtin commands execute in the context of the shell, but otherwise
-behave exactly like other commands.
-Although
-.BR ! ,
-.B ~
-and
-.B @
-are not strictly speaking builtin commands,
-they can usually be used as such.
-.TP
-\&\fB.\fR [\fB\-i\fR] \fIfile \fR[\fIarg ...\fR]
-Reads
-.I file
-as input to
-.IR rc
-and executes its contents.
-With a
-.Cr \-i
-flag, input is interactive.
-Thus from within a shell script,
-.Ds
-.Cr ". \-i /dev/tty"
-.De
-.TP
-\&
-does the ``right'' thing.
-.TP
-.B break
-Breaks from the innermost
-.Cr for
-or
-.Cr while ,
-as in C.
-It is an error to invoke
-.B break
-outside of a loop.
-(Note that there is no
-.B break
-keyword between commands in
-.Cr switch
-statements, unlike C.)
-.TP
-\fBbuiltin \fIcommand \fR[\fIarg ...\fR]
-Executes the command ignoring any function definition of the
-same name.
-This command is present to allow functions with the
-same names as builtins to use the underlying builtin or binary.
-.TP
-\fBcd \fR[\fIdirectory\fR]
-Changes the current directory to
-.IR directory .
-The variable
-.Cr $cdpath
-is searched for possible locations of
-.IR directory ,
-analogous to the searching of
-.Cr $path
-for executable files.
-With no argument,
-.B cd
-changes the current directory to
-.Cr "$home" .
-.TP
-\fBecho \fR[\fB\-n\fR] [\fB\-\|\-\fR] [\fIarg ...\fR]
-Prints its arguments to standard output, terminated by a newline.
-Arguments are separated by spaces.
-If the first argument is
-.Cr "\-n"
-no final newline is printed.
-If the first argument is
-.Cr "\-\|\-" ,
-then all other arguments are echoed literally.
-This is used for echoing a literal
-.Cr "\-n" .
-.TP
-\fBeval \fR[\fIlist\fR]
-Concatenates the elements of
-.I list
-with spaces and feeds the resulting string to
-.I rc
-for re-scanning.
-This is the only time input is rescanned in
-.IR rc .
-.TP
-\fBexec \fR[\fIarg ...\fR]
-Replaces
-.I rc
-with the given command.
-If the exec contains only redirections,
-then these redirections apply to the current shell
-and the shell does not exit.
-For example,
-.Ds
-.Cr "exec >[2] err.out"
-.De
-.TP
-\&
-places further output to standard error in the file
-.IR err.out .
-.TP
-\fBexit \fR[\fIstatus\fR]
-Cause the current shell to exit with the given exit
-.IR status .
-If no argument is given, the current value of
-.Cr $status
-is used.
-.TP
-\fBlimit \fR[\fB\-h\fR] [\fIresource \fR[\fIvalue\fR]]
-Similar to the
-.IR csh (1)
-.B limit
-builtin, this command operates upon the
-BSD-style limits of a process.
-The
-.Cr \-h
-flag displays/alters the hard
-limits.
-The resources which can be shown or altered are
-.BR cputime ,
-.BR filesize ,
-.BR datasize ,
-.BR stacksize ,
-.B coredumpsize
-and
-.BR memoryuse .
-For
-example:
-.Ds
-.Cr "limit coredumpsize 0"
-.De
-.TP
-\&
-disables core dumps.
-.TP
-.B newpgrp
-Puts
-.I rc
-into a new process group.
-This builtin is useful for making
-.I rc
-behave like a job-control shell in a hostile environment.
-One example is the NeXT Terminal program, which implicitly assumes
-that each shell it forks will put itself into a new process group.
-.TP
-\fBreturn \fR[\fIn\fR]
-Returns from the current function, with status
-.IR n ,
-where
-.IR n
-is a single value or a list of possible exit statuses.
-Thus it is legal to have
-.Ds
-.Cr "return (sigpipe 1 2 3)"
-.De
-.TP
-\&
-(This is commonly used to allow a function to return with the exit status
-of a previously executed pipeline of commands.)
-If
-.IR n
-is omitted, then
-.Cr $status
-is left unchanged.
-It is an error to invoke
-.B return
-when not inside a function.
-.TP
-\fBshift \fR[\fIn\fR]
-Deletes
-.I n
-elements from the beginning of
-.Cr $*
-and shifts the other
-elements down by
-.IR n .
-.I n
-defaults to 1.
-(Note that
-.Cr $0
-is not affected by
-.BR shift .)
-.TP
-\fBumask \fR[\fImask\fR]
-Sets the current umask (see
-.IR umask (2))
-to the octal
-.IR mask .
-If no argument is present, the current mask value is printed.
-.TP
-\fBwait \fR[\fIpid\fR]
-Waits for the specified
-.IR pid ,
-which must have been started by
-.IR rc .
-If no
-.I pid
-is specified,
-.I rc
-waits for all child processes to exit.
-.TP
-\fBwhatis \fR[\fB\-s\fR] [\fB\-\|\-\fR] [\fIname ...\fR]
-Prints a definition of the named objects.
-For variables, their values
-are printed; for functions, their definitions are; and for executable
-files, path names are printed.
-Without arguments,
-.B whatis
-prints the values of all shell variables and functions.
-With a
-.Cr \-s
-argument,
-.B whatis
-also prints out a list of available signals and their handlers (if any).
-Note that
-.B whatis
-output is suitable for input to
-.IR rc ;
-by saving the output of
-.B whatis
-in a file, it should be possible to recreate the state of
-.I rc
-by sourcing this file with a
-.Cr .
-command.
-Another note:
-.Cr "whatis -s > file"
-cannot be used to store the state of
-.IR rc 's
-signal handlers in a file, because builtins with redirections
-are run in a subshell, and
-.I rc
-always restores signal handlers to their default value after a
-.Cr fork() .
-.TP
-\&
-Since
-.B whatis
-uses
-.IR getopt (3)
-to parse its arguments, you can use the special argument
-.Cr "\-\|\-"
-to terminate its options.
-This allows you to use names beginning with a dash, such as
-the
-.IR history (1)
-commands.
-For example,
-.Ds
-.Cr "whatis \-\|\- \-p"
-.De
-.SH GRAMMAR
-Here is
-.IR rc 's
-grammar, edited to remove semantic actions.
-.Ds
-.ft \*(Cf
-%term ANDAND BACKBACK BANG CASE COUNT DUP ELSE END FLAT FN FOR IF IN
-%term OROR PIPE REDIR SUB SUBSHELL SWITCH TWIDDLE WHILE WORD HUH
-
-%left WHILE ')' ELSE
-%left ANDAND OROR '\en'
-%left BANG SUBSHELL
-%left PIPE
-%right '$'
-%left SUB
-
-%start rc
-
-%%
-
-rc: line end
- | error end
-
-end: END /* EOF */ | '\en'
-
-cmdsa: cmd ';' | cmd '&'
-
-line: cmd | cmdsa line
-
-body: cmd | cmdsan body
-
-cmdsan: cmdsa | cmd '\en'
-
-brace: '{' body '}'
-
-paren: '(' body ')'
-
-assign: first '=' word
-
-epilog: /* empty */ | redir epilog
-
-redir: DUP | REDIR word
-
-case: CASE words ';' | CASE words '\en'
-
-cbody: cmd | case cbody | cmdsan cbody
-
-iftail: cmd %prec ELSE
- | brace ELSE optnl cmd
-
-cmd : /* empty */ %prec WHILE
- | simple
- | brace epilog
- | IF paren optnl iftail
- | FOR '(' word IN words ')' optnl cmd
- | FOR '(' word ')' optnl cmd
- | WHILE paren optnl cmd
- | SWITCH '(' word ')' optnl '{' cbody '}'
- | TWIDDLE optcaret word words
- | cmd ANDAND optnl cmd
- | cmd OROR optnl cmd
- | cmd PIPE optnl cmd
- | redir cmd %prec BANG
- | assign cmd %prec BANG
- | BANG optcaret cmd
- | SUBSHELL optcaret cmd
- | FN words brace
- | FN words
-
-optcaret: /* empty */ | '^'
-
-simple: first | simple word | simple redir
-
-first: comword | first '^' sword
-
-sword: comword | keyword
-
-word: sword | word '^' sword
-
-comword: '$' sword
- | '$' sword SUB words ')'
- | COUNT sword
- | FLAT sword
- | '`' sword
- | '`' brace
- | BACKBACK word brace | BACKBACK word sword
- | '(' words ')'
- | REDIR brace
- | WORD
-
-keyword: FOR | IN | WHILE | IF | SWITCH
- | FN | ELSE | CASE | TWIDDLE | BANG | SUBSHELL
-
-words: /* empty */ | words word
-
-optnl: /* empty */ | optnl '\en'
-.ft R
-.De
-.SH FILES
-.Cr $HOME/.rcrc ,
-.Cr /tmp/rc* ,
-.Cr /dev/null
-.SH CREDITS
-.I rc
-was written by Byron Rakitzis, with valuable help
-from Paul Haahr, Hugh Redelmeier and David Sanderson.
-The design of this shell has been copied from the
-.I rc
-that Tom Duff wrote at Bell Labs.
-.SH BUGS
-On systems that support
-.Cr /dev/fd ,
-.Cr <{foo}
-style redirection is implemented that way.
-However, on other systems it is implemented with named pipes,
-and it is sometimes
-possible to foil
-.I rc
-into removing the FIFO it places in
-.Cr /tmp
-prematurely, or it is even possible to cause
-.I rc
-to hang.
-.PP
-The functionality of
-.B shift
-should be available for variables other than
-.Cr "$*" .
-.PP
-.B echo
-is built in only for performance reasons, which is a bad idea.
-.PP
-There should be a way to avoid exporting a variable.
-.PP
-The
-.Cr $^var
-notation for flattening should allow for using an arbitrary
-separating character, not just space.
-.PP
-Bug reports should be mailed to
-.Cr "byron@archone.tamu.edu" .
-.SH INCOMPATIBILITIES
-Here is a list of features which distinguish this incarnation of
-.I rc
-from the one described in the Bell Labs manual pages:
-.PP
-The treatment of
-.Cr if - else
-is different in the v10
-.IR rc :
-that version uses an
-.Cr "if not"
-clause which gets executed
-if the preceding
-.Cr if
-test does not succeed.
-.PP
-Backquotes are slightly different in v10
-.IR rc :
-a backquote must always be followed by a left-brace.
-This restriction is not present for single-word commands in this
-.IR rc .
-.PP
-The following are all new with this version of
-.IR rc :
-The
-.Cr \-n
-option,
-the list flattening operator,
-here strings (they facilitate exporting of functions
-with here documents into the environment),
-the
-.B return
-and
-.B break
-keywords,
-the
-.B echo
-builtin,
-the support for the GNU
-.IR readline (3)
-library and
-the support for the
-.Cr prompt
-function.
-This
-.I rc
-also sets
-.Cr $0
-to the name of a function being executed/file
-being sourced.
-.SH "SEE ALSO"
-``rc \(em A Shell for Plan 9 and UNIX Systems'',
-Unix Research System,
-10th Edition,
-vol. 2. (Saunders College Publishing)
-(This paper is also distributed with this
-.I rc
-in PostScript form.)
-.PP
-.IR history (1)
diff --git a/rc.h b/rc.h
@@ -1,406 +0,0 @@
-#include "config.h"
-
-#if HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "proto.h"
-
-/* datatypes */
-
-/* braindamaged IBM header files #define true and false */
-#undef FALSE
-#undef TRUE
-
-#include <stdarg.h>
-
-#if HAVE_SETPGRP
-
-#if SETPGRP_VOID
-/* Smells like POSIX: should all be ok. */
-#else
-/* BSD: fake it. */
-#define setpgid(pid, pgrp) setpgrp(pid, pgrp)
-#define tcsetpgrp(fd, pgrp) ioctl((fd), TIOCSPGRP, &(pgrp))
-#endif
-
-#else /* HAVE_SETPGRP */
-
-/* Nothing doing. */
-#define setpgid
-#define tcsetpgrp
-
-#endif /*HAVE_SETPGRP */
-
-typedef void builtin_t(char **);
-typedef struct Block Block;
-typedef struct Dup Dup;
-typedef struct Estack Estack;
-typedef struct Function Function;
-typedef struct Hq Hq;
-typedef struct Htab Htab;
-typedef struct Jbwrap Jbwrap;
-typedef struct List List;
-typedef struct Node Node;
-typedef struct Pipe Pipe;
-typedef struct Redir Redir;
-typedef struct Rq Rq;
-typedef struct Variable Variable;
-typedef struct Word Word;
-typedef struct Format Format;
-typedef union Edata Edata;
-
-typedef enum nodetype {
- nAndalso, nAssign, nBackq, nBang, nBody, nCbody, nNowait, nBrace, nConcat,
- nCount, nElse, nFlat, nDup, nEpilog, nNewfn, nForin, nIf, nQword,
- nOrelse, nPipe, nPre, nRedir, nRmfn, nArgs, nSubshell, nCase,
- nSwitch, nMatch, nVar, nVarsub, nWhile, nWord, nLappend, nNmpipe
-} nodetype;
-
-typedef enum ecodes {
- eError, eBreak, eReturn, eVarstack, eArena, eFifo, eFd
-} ecodes;
-
-typedef enum bool {
- FALSE, TRUE
-} bool;
-
-typedef enum inputtype {
- iFd, iString
-} inputtype;
-
-typedef enum redirtype {
- rFrom, rCreate, rAppend, rHeredoc, rHerestring
-} redirtype;
-
-typedef bool (*Conv)(Format *, int);
-
-union Edata {
- Jbwrap *jb;
- Block *b;
- char *name;
- int fd;
-};
-
-struct Estack {
- ecodes e;
- bool interactive;
- Edata data;
- Estack *prev;
-};
-
-struct List {
- char *w, *m;
- List *n;
-};
-
-struct Node {
- nodetype type;
- union {
- char *s;
- int i;
- Node *p;
- } u[4];
-};
-
-struct Pipe {
- int left, right;
-};
-
-struct Dup {
- redirtype type;
- int left, right;
-};
-
-struct Redir {
- redirtype type;
- int fd;
-};
-
-struct Word {
- char *w, *m;
-};
-
-struct Rq {
- Node *r;
- struct Rq *n;
-};
-
-struct Function {
- Node *def;
- char *extdef;
-};
-
-struct Variable {
- List *def;
- char *extdef;
- Variable *n;
-};
-
-struct Htab {
- char *name;
- void *p;
-};
-
-struct Format {
- /* for the formatting routines */
- va_list args;
- long flags, f1, f2;
- /* for the buffer maintainence routines */
- char *buf, *bufbegin, *bufend;
- int flushed;
- void (*grow)(Format *, size_t);
- union { int n; void *p; } u;
-};
-
-/* Format->flags values */
-enum {
- FMT_quad = 1, /* %q */
- FMT_long = 2, /* %l */
- FMT_short = 4, /* %h */
- FMT_unsigned = 8, /* %u */
- FMT_zeropad = 16, /* %0 */
- FMT_leftside = 32, /* %- */
- FMT_altform = 64, /* %# */
- FMT_f1set = 128, /* %<n> */
- FMT_f2set = 256 /* %.<n> */
-};
-
-/* macros */
-#define EOF (-1)
-#ifndef NULL
-#define NULL 0
-#endif
-#define a2u(x) n2u(x, 10)
-#define o2u(x) n2u(x, 8)
-#define arraysize(a) ((int)(sizeof(a)/sizeof(*a)))
-#define memzero(s, n) memset(s, 0, n)
-#define enew(x) ((x *) ealloc(sizeof(x)))
-#define ecpy(x) strcpy((char *) ealloc(strlen(x) + 1), x)
-#define lookup_fn(s) ((Function *) lookup(s, fp))
-#define lookup_var(s) ((Variable *) lookup(s, vp))
-#define nnew(x) ((x *) nalloc(sizeof(x)))
-#define ncpy(x) (strcpy((char *) nalloc(strlen(x) + 1), x))
-#ifndef offsetof
-#define offsetof(t, m) ((size_t) (((char *) &((t *) 0)->m) - (char *)0))
-#endif
-#define streq(x, y) (*(x) == *(y) && strcmp(x, y) == 0)
-#define conststrlen(x) (sizeof (x) - 1)
-
-/* rc prototypes */
-
-/* main.c */
-extern char *prompt, *prompt2;
-extern Rq *redirq;
-extern bool dashdee, dashee, dashvee, dashex, dashell,
- dasheye, dashen, dashpee, interactive;
-extern pid_t rc_pid;
-extern int lineno;
-
-/* builtins.c */
-extern builtin_t *isbuiltin(char *);
-extern void b_exec(char **), funcall(char **), b_dot(char **), b_builtin(char **);
-extern char *which(char *, bool);
-
-/* except.c */
-extern bool nl_on_intr;
-extern bool outstanding_cmdarg(void);
-extern void pop_cmdarg(bool);
-extern void rc_raise(ecodes);
-extern void except(ecodes, Edata, Estack *);
-extern void unexcept(void);
-extern void rc_error(char *);
-extern void sigint(int);
-
-/* exec.c */
-extern void exec(List *, bool);
-extern void doredirs(void);
-
-/* footobar.c */
-extern char **list2array(List *, bool);
-extern char *get_name(char *);
-extern List *parse_var(char *, char *);
-extern Node *parse_fn(char *, char *);
-extern void initprint(void);
-extern void rc_exit(int); /* here for odd reasons; user-defined signal handlers are kept in fn.c */
-
-/* getopt.c */
-extern int rc_getopt(int, char **, char *);
-
-extern int rc_optind, rc_opterr, rc_optopt;
-extern char *rc_optarg;
-
-/* glob.c */
-extern bool lmatch(List *, List *);
-extern List *glob(List *);
-
-/* glom.c */
-extern void assign(List *, List *, bool);
-extern void qredir(Node *);
-extern List *append(List *, List*);
-extern List *flatten(List *);
-extern List *glom(Node *);
-extern List *concat(List *, List *);
-extern List *varsub(List *, List *);
-extern List *word(char *, char *);
-
-/* hash.c */
-extern Htab *fp, *vp;
-extern void *lookup(char *, Htab *);
-extern Function *get_fn_place(char *);
-extern List *varlookup(char *);
-extern Node *fnlookup(char *);
-extern Variable *get_var_place(char *, bool);
-extern bool varassign_string(char *);
-extern char **makeenv(void);
-extern char *fnlookup_string(char *);
-extern char *varlookup_string(char *);
-extern void alias(char *, List *, bool);
-extern void starassign(char *, char **, bool);
-extern void delete_fn(char *);
-extern void delete_var(char *, bool);
-extern void fnassign(char *, Node *);
-extern void fnassign_string(char *);
-extern void fnrm(char *);
-extern void initenv(char **);
-extern void inithash(void);
-extern void setsigdefaults(bool);
-extern void inithandler(void);
-extern void varassign(char *, List *, bool);
-extern void varrm(char *, bool);
-extern void whatare_all_vars(bool, bool);
-extern void whatare_all_signals(void);
-extern void prettyprint_var(int, char *, List *);
-extern void prettyprint_fn(int, char *, Node *);
-
-/* heredoc.c */
-extern int heredoc(int);
-extern int qdoc(Node *, Node *);
-extern Hq *hq;
-
-/* input.c */
-extern void initinput(void);
-extern Node *parseline(char *);
-extern int gchar(void);
-extern void ugchar(int);
-extern Node *doit(bool);
-extern void flushu(void);
-extern void pushfd(int);
-extern void pushstring(char **, bool);
-extern void popinput(void);
-extern void closefds(void);
-extern int last;
-extern bool rcrc;
-
-/* lex.c */
-extern int yylex(void);
-extern void inityy(void);
-extern void yyerror(const char *);
-extern void scanerror(char *);
-extern void print_prompt2(void);
-extern const char nw[], dnw[];
-
-/* list.c */
-extern void listfree(List *);
-extern List *listcpy(List *, void *(*)(size_t));
-extern size_t listlen(List *);
-extern int listnel(List *);
-
-/* match.c */
-extern bool match(char *, char *, char *);
-
-/* alloc.c */
-extern void *ealloc(size_t);
-extern void *erealloc(void *, size_t);
-extern void efree(void *);
-extern Block *newblock(void);
-extern void *nalloc(size_t);
-extern void nfree(void);
-extern void restoreblock(Block *);
-
-/* open.c */
-extern int rc_open(const char *, redirtype);
-
-/* print.c */
-/*
- The following prototype should be:
-extern Conv fmtinstall(int, Conv);
- but this freaks out SGI's compiler under IRIX3.3.2
-*/
-extern bool (*fmtinstall(int, bool (*)(Format *, int)))(Format *, int);
-extern int printfmt(Format *, const char *);
-extern int fmtprint(Format *, const char *,...);
-extern void fmtappend(Format *, const char *, size_t);
-extern void fmtcat(Format *, const char *);
-extern int fprint(int fd, const char *fmt,...);
-extern char *mprint(const char *fmt,...);
-extern char *nprint(const char *fmt,...);
-/*
- the following macro should by rights be coded as an expression, not
- a statement, but certain compilers (notably DEC) have trouble with
- void expressions inside the ?: operator. (sheesh, give me a break!)
-*/
-#define fmtputc(f, c) {\
- if ((f)->buf >= (f)->bufend)\
- (*(f)->grow)((f), (size_t)1);\
- *(f)->buf++ = (c);\
-}
-
-/* y.tab.c (parse.y) */
-extern Node *parsetree;
-extern int yyparse(void);
-extern void initparse(void);
-
-/* redir.c */
-extern void doredirs(void);
-
-/* signal.c */
-extern void initsignal(void);
-extern void catcher(int);
-extern void sigchk(void);
-extern void (*rc_signal(int, void (*)(int)))(int);
-extern void (*sighandlers[])(int);
-extern volatile SIG_ATOMIC_T slow, interrupt_happened;
-
-/* status.c */
-extern int istrue(void);
-extern int getstatus(void);
-extern void set(bool);
-extern void setstatus(pid_t, int);
-extern List *sgetstatus(void);
-extern void setpipestatus(int [], int);
-extern void statprint(pid_t, int);
-extern void ssetstatus(char **);
-extern char *strstatus(int s);
-
-/* tree.c */
-extern Node *mk(int /*nodetype*/,...);
-extern Node *treecpy(Node *, void *(*)(size_t));
-extern void treefree(Node *);
-
-/* utils.c */
-extern bool isabsolute(char *);
-extern int n2u(char *, unsigned int);
-extern int rc_read(int, char *, size_t);
-extern int mvfd(int, int);
-extern int starstrcmp(const void *, const void *);
-extern void pr_error(char *);
-extern void panic(char *);
-extern void uerror(char *);
-extern void writeall(int, char *, size_t);
-
-/* wait.c */
-extern pid_t rc_fork(void);
-extern pid_t rc_wait4(pid_t, int *, bool);
-extern List *sgetapids(void);
-extern void waitforall(void);
-extern bool forked;
-
-/* walk.c */
-extern bool walk(Node *, bool);
-extern bool cond;
-
diff --git a/redir.c b/redir.c
@@ -1,77 +0,0 @@
-/* redir.c: code for opening files and piping heredocs after fork but before exec. */
-
-#include "rc.h"
-
-/*
- Walk the redirection queue, and open files and dup2 to them. Also,
- here-documents are treated here by dumping them down a pipe. (this
- should make here-documents fast on systems with lots of memory which
- do pipes right. Under sh, a file is copied to /tmp, and then read
- out of /tmp again. I'm interested in knowing how much faster, say,
- shar runs when unpacking when invoked with rc instead of sh. On my
- sun4/280, it runs in about 60-75% of the time of sh for unpacking
- the rc source distribution.)
-*/
-
-extern void doredirs() {
- List *fname;
- int fd, p[2];
- Rq *r;
- for (r = redirq; r != NULL; r = r->n) {
- switch(r->r->type) {
- default:
- panic("unexpected node in doredirs");
- /* NOTREACHED */
- case nRedir:
- if (r->r->u[0].i == rHerestring) {
- fname = flatten(glom(r->r->u[2].p)); /* fname is really a string */
- if (pipe(p) < 0) {
- uerror("pipe");
- rc_error(NULL);
- }
- if (rc_fork() == 0) { /* child writes to pipe */
- setsigdefaults(FALSE);
- close(p[0]);
- if (fname != NULL)
- writeall(p[1], fname->w, strlen(fname->w));
- exit(0);
- } else {
- close(p[1]);
- if (mvfd(p[0], r->r->u[1].i) < 0)
- rc_error(NULL);
- }
- } else {
- fname = glob(glom(r->r->u[2].p));
- if (fname == NULL)
- rc_error("null filename in redirection");
- if (fname->n != NULL)
- rc_error("multi-word filename in redirection");
- switch (r->r->u[0].i) {
- default:
- panic("unexpected node in doredirs");
- /* NOTREACHED */
- case rCreate: case rAppend: case rFrom:
- fd = rc_open(fname->w, r->r->u[0].i);
- break;
- }
- if (fd < 0) {
- uerror(fname->w);
- rc_error(NULL);
- }
- if (mvfd(fd, r->r->u[1].i) < 0)
- rc_error(NULL);
- }
- break;
- case nDup:
- if (r->r->u[2].i == -1)
- close(r->r->u[1].i);
- else if (r->r->u[2].i != r->r->u[1].i) {
- if (dup2(r->r->u[2].i, r->r->u[1].i) < 0) {
- uerror("dup2");
- rc_error(NULL);
- }
- }
- }
- }
- redirq = NULL;
-}
diff --git a/rlimit.h b/rlimit.h
@@ -1,42 +0,0 @@
-/* What a mess. This file attempts to straighten everything out. */
-
-#if HAVE_SETRLIMIT
-
-#if HAVE_SYS_RESOURCE_H
-# include <sys/time.h>
-# if RLIMIT_NEEDS_KERNEL
-# define _KERNEL
-# endif
-# include <sys/resource.h>
-# if RLIMIT_NEEDS_KERNEL
-# undef _KERNEL
-# endif
-#else
-# include <sys/times.h>
-#endif
-
-#if HAVE_LIMITS_H
-# include <limits.h>
-#endif
-
-#ifndef HAVE_RLIM_T
-# if RLIM_T_IS_QUAD_T
-typedef quad_t rlim_t;
-# else
-typedef long rlim_t;
-# endif
-#endif
-
-#if HAVE_QUAD_T
-# define RLIM_CONV quad_t
-# define RLIM_FMT "%s \t%qd%s\n"
-#else
-# define RLIM_CONV long
-# define RLIM_FMT "%s \t%ld%s\n"
-#endif
-
-#if defined(RLIMIT_OFILE) && !defined (RLIMIT_NOFILE)
-# define RLIMIT_NOFILE RLIMIT_OFILE
-#endif
-
-#endif /* HAVE_SETRLIMIT */
diff --git a/signal.c b/signal.c
@@ -1,80 +0,0 @@
-/* signal.c: a Hugh-approved signal handler. */
-
-#include <signal.h>
-#include <setjmp.h>
-#include "rc.h"
-#include "sigmsgs.h"
-#include "jbwrap.h"
-
-Jbwrap slowbuf;
-volatile SIG_ATOMIC_T slow, interrupt_happened;
-void (*sighandlers[NUMOFSIGNALS])(int);
-
-static volatile SIG_ATOMIC_T sigcount, caught[NUMOFSIGNALS];
-
-extern void catcher(int s) {
- if (caught[s] == 0) {
- sigcount++;
- caught[s] = 1;
- }
- signal(s, catcher);
- interrupt_happened = TRUE;
-#ifndef HAVE_RESTARTABLE_SYSCALLS
- if (slow)
- longjmp(slowbuf.j, 1);
-#endif
-}
-
-extern void sigchk() {
- void (*h)(int);
- int s, i;
- if (sigcount == 0)
- return; /* ho hum; life as usual */
- if (forked)
- exit(1); /* exit unconditionally on a signal in a child process */
- for (i = 0, s = -1; i < NUMOFSIGNALS; i++)
- if (caught[i] != 0) {
- s = i;
- --sigcount;
- caught[s] = 0;
- break;
- }
- if (s == -1)
- panic("all-zero sig vector with nonzero sigcount");
- if ((h = sighandlers[s]) == SIG_DFL)
- panic("caught signal set to SIG_DFL");
- if (h == SIG_IGN)
- panic("caught signal set to SIG_IGN");
- (*h)(s);
-}
-
-extern void (*rc_signal(int s, void (*h)(int)))(int) {
- void (*old)(int);
- sigchk();
- old = sighandlers[s];
- if (h == SIG_DFL || h == SIG_IGN) {
- signal(s, h);
- sighandlers[s] = h;
- } else {
- sighandlers[s] = h;
- signal(s, catcher);
- }
- return old;
-}
-
-extern void initsignal() {
- void (*h)(int);
- int i;
- for (i = 1; i < NUMOFSIGNALS; i++) {
- if ((h = signal(i, SIG_DFL)) != SIG_DFL)
- signal(i, h);
- sighandlers[i] = h;
- }
-
-#ifdef SIGCLD
- /* Ensure that SIGCLD is not SIG_IGN. Solaris's rshd does this. :-( */
- h = signal(SIGCLD, SIG_DFL);
- if (h != SIG_IGN)
- signal(SIGCLD, h);
-#endif
-}
diff --git a/status.c b/status.c
@@ -1,147 +0,0 @@
-/* status.c: functions for printing fancy status messages in rc */
-
-#include "rc.h"
-#include "sigmsgs.h"
-
-/* status == the wait() value of the last command in the pipeline, or the last command */
-
-static int statuses[512];
-static int pipelength = 1;
-
-/*
- Test to see if rc's status is true. According to td, status is true
- if and only if every pipe-member has an exit status of zero.
-*/
-
-extern int istrue() {
- int i;
- for (i = 0; i < pipelength; i++)
- if (statuses[i] != 0)
- return FALSE;
- return TRUE;
-}
-
-/*
- Return the status as an integer. A status which has low-bits set is
- a signal number, whereas a status with high bits set is a value set
- from exit(). The presence of a signal just sets status to 1. Also,
- a pipeline with nonzero exit statuses in it just sets status to 1.
-*/
-
-extern int getstatus() {
- int s;
- if (pipelength > 1)
- return !istrue();
- s = statuses[0];
- return (s&0xff) ? 1 : (s >> 8) & 0xff;
-}
-
-extern void set(bool code) {
- setstatus(-1, (!code) << 8); /* exit status 1 == 0x100 */
-}
-
-/* take a pipeline and store the exit statuses. Check to see whether any of the children dumped core */
-
-extern void setpipestatus(int stats[], int num) {
- int i;
- for (i = 0; i < (pipelength = num); i++) {
- statprint(-1, stats[i]);
- statuses[i] = stats[i];
- }
-}
-
-/* set a simple status, as opposed to a pipeline */
-
-extern void setstatus(pid_t pid, int i) {
- pipelength = 1;
- statuses[0] = i;
- statprint(pid, i);
-}
-
-/* print a message if termination was with a signal, and if the child dumped core. exit on error if -e is set */
-
-extern void statprint(pid_t pid, int i) {
- if (i & 0xff) {
- char *msg = ((i & 0x7f) < NUMOFSIGNALS ? signals[i & 0x7f].msg : "");
- if (pid != -1)
- fprint(2, "%ld: ", (long)pid);
- if (i & 0x80) {
- if (*msg == '\0')
- fprint(2, "core dumped\n");
- else
- fprint(2, "%s--core dumped\n", msg);
- } else if (*msg != '\0')
- fprint(2, "%s\n", msg);
- }
- if (i != 0 && dashee && !cond)
- rc_exit(getstatus());
-}
-
-/* prepare a list to be passed back. Used whenever $status is dereferenced */
-
-extern List *sgetstatus() {
- List *r = NULL;
- int i;
-
- for (i = 0; i < pipelength; i++) {
- List *q = nnew(List);
- q->w = strstatus(statuses[i]);
- q->m = NULL;
- q->n = r;
- r = q;
- }
-
- return r;
-}
-
-/* return status as a string (used above and for bqstatus) */
-
-extern char *strstatus(int s) {
- int t = s & 0x7f;
-
- if (t != 0) {
- const char *core = (s & 0x80) ? "+core" : "";
- if (t < NUMOFSIGNALS && *signals[t].name != '\0')
- return nprint("%s%s", signals[t].name, core);
- else
- return nprint("-%d%s", t, core); /* unknown signals are negated */
- } else
- return nprint("%d", (s >> 8) & 0xff);
-}
-
-extern void ssetstatus(char **av) {
- int i, j, k, l;
- bool found;
- for (l = 0; av[l] != NULL; l++)
- ; /* count up array length */
- --l;
- for (i = 0; av[i] != NULL; i++) {
- j = a2u(av[i]);
- if (j >= 0) {
- statuses[l - i] = j << 8;
- continue;
- }
- found = FALSE;
- for (k = 0; k < NUMOFSIGNALS; k++) {
- if (streq(signals[k].name, av[i])) {
- statuses[l - i] = k;
- found = TRUE;
- break;
- }
- else {
- size_t len = strlen(signals[k].name);
- if (strncmp(signals[k].name, av[i], len) == 0 && streq(av[i] + len, "+core")) {
- statuses[l - i] = k + 0x80;
- found = TRUE;
- break;
- }
- }
- }
- if (!found) {
- fprint(2, "bad status\n");
- set(FALSE);
- return;
- }
- }
- pipelength = i;
-}
diff --git a/tree.c b/tree.c
@@ -1,172 +0,0 @@
-/* tree.c: functions for manipulating parse-trees. (create, copy, delete) */
-
-#include "rc.h"
-
-/* make a new node, pass it back to yyparse. Used to generate the parsetree. */
-
-extern Node *mk(int /*nodetype*/ t,...) {
- va_list ap;
- Node *n;
- va_start(ap, t);
- switch (t) {
- default:
- panic("unexpected node in mk");
- /* NOTREACHED */
- case nDup:
- n = nalloc(offsetof(Node, u[3]));
- n->u[0].i = va_arg(ap, int);
- n->u[1].i = va_arg(ap, int);
- n->u[2].i = va_arg(ap, int);
- break;
- case nWord: case nQword:
- n = nalloc(offsetof(Node, u[2]));
- n->u[0].s = va_arg(ap, char *);
- n->u[1].s = va_arg(ap, char *);
- break;
- case nBang: case nNowait:
- case nCount: case nFlat: case nRmfn: case nSubshell:
- case nVar: case nCase:
- n = nalloc(offsetof(Node, u[1]));
- n->u[0].p = va_arg(ap, Node *);
- break;
- case nAndalso: case nAssign: case nBackq: case nBody: case nBrace: case nConcat:
- case nElse: case nEpilog: case nIf: case nNewfn: case nCbody:
- case nOrelse: case nPre: case nArgs: case nSwitch:
- case nMatch: case nVarsub: case nWhile: case nLappend:
- n = nalloc(offsetof(Node, u[2]));
- n->u[0].p = va_arg(ap, Node *);
- n->u[1].p = va_arg(ap, Node *);
- break;
- case nForin:
- n = nalloc(offsetof(Node, u[3]));
- n->u[0].p = va_arg(ap, Node *);
- n->u[1].p = va_arg(ap, Node *);
- n->u[2].p = va_arg(ap, Node *);
- break;
- case nPipe:
- n = nalloc(offsetof(Node, u[4]));
- n->u[0].i = va_arg(ap, int);
- n->u[1].i = va_arg(ap, int);
- n->u[2].p = va_arg(ap, Node *);
- n->u[3].p = va_arg(ap, Node *);
- break;
- case nRedir:
- case nNmpipe:
- n = nalloc(offsetof(Node, u[3]));
- n->u[0].i = va_arg(ap, int);
- n->u[1].i = va_arg(ap, int);
- n->u[2].p = va_arg(ap, Node *);
- break;
- }
- n->type = t;
- va_end(ap);
- return n;
-}
-
-/* copy a tree to malloc space. Used when storing the definition of a function */
-
-extern Node *treecpy(Node *s, void *(*alloc)(size_t)) {
- Node *n;
- if (s == NULL)
- return NULL;
- switch (s->type) {
- default:
- panic("unexpected node in treecpy");
- /* NOTREACHED */
- case nDup:
- n = (*alloc)(offsetof(Node, u[3]));
- n->u[0].i = s->u[0].i;
- n->u[1].i = s->u[1].i;
- n->u[2].i = s->u[2].i;
- break;
- case nWord: case nQword:
- n = (*alloc)(offsetof(Node, u[2]));
- n->u[0].s = strcpy((char *) (*alloc)(strlen(s->u[0].s) + 1), s->u[0].s);
- if (s->u[1].s != NULL) {
- size_t i = strlen(s->u[0].s);
- n->u[1].s = (*alloc)(i);
- memcpy(n->u[1].s, s->u[1].s, i);
- } else
- n->u[1].s = NULL;
- break;
- case nBang: case nNowait: case nCase:
- case nCount: case nFlat: case nRmfn: case nSubshell: case nVar:
- n = (*alloc)(offsetof(Node, u[1]));
- n->u[0].p = treecpy(s->u[0].p, alloc);
- break;
- case nAndalso: case nAssign: case nBackq: case nBody: case nBrace: case nConcat:
- case nElse: case nEpilog: case nIf: case nNewfn: case nCbody:
- case nOrelse: case nPre: case nArgs: case nSwitch:
- case nMatch: case nVarsub: case nWhile: case nLappend:
- n = (*alloc)(offsetof(Node, u[2]));
- n->u[0].p = treecpy(s->u[0].p, alloc);
- n->u[1].p = treecpy(s->u[1].p, alloc);
- break;
- case nForin:
- n = (*alloc)(offsetof(Node, u[3]));
- n->u[0].p = treecpy(s->u[0].p, alloc);
- n->u[1].p = treecpy(s->u[1].p, alloc);
- n->u[2].p = treecpy(s->u[2].p, alloc);
- break;
- case nPipe:
- n = (*alloc)(offsetof(Node, u[4]));
- n->u[0].i = s->u[0].i;
- n->u[1].i = s->u[1].i;
- n->u[2].p = treecpy(s->u[2].p, alloc);
- n->u[3].p = treecpy(s->u[3].p, alloc);
- break;
- case nRedir:
- case nNmpipe:
- n = (*alloc)(offsetof(Node, u[3]));
- n->u[0].i = s->u[0].i;
- n->u[1].i = s->u[1].i;
- n->u[2].p = treecpy(s->u[2].p, alloc);
- break;
- }
- n->type = s->type;
- return n;
-}
-
-/* free a function definition that is no longer needed */
-
-extern void treefree(Node *s) {
- if (s == NULL)
- return;
- switch (s->type) {
- default:
- panic("unexpected node in treefree");
- /* NOTREACHED */
- case nDup:
- break;
- case nWord: case nQword:
- efree(s->u[0].s);
- efree(s->u[1].s);
- break;
- case nBang: case nNowait:
- case nCount: case nFlat: case nRmfn:
- case nSubshell: case nVar: case nCase:
- treefree(s->u[0].p);
- break;
- case nAndalso: case nAssign: case nBackq: case nBody: case nBrace: case nConcat:
- case nElse: case nEpilog: case nIf: case nNewfn:
- case nOrelse: case nPre: case nArgs: case nCbody:
- case nSwitch: case nMatch: case nVarsub: case nWhile:
- case nLappend:
- treefree(s->u[1].p);
- treefree(s->u[0].p);
- break;
- case nForin:
- treefree(s->u[2].p);
- treefree(s->u[1].p);
- treefree(s->u[0].p);
- break;
- case nPipe:
- treefree(s->u[2].p);
- treefree(s->u[3].p);
- break;
- case nRedir:
- case nNmpipe:
- treefree(s->u[2].p);
- }
- efree(s);
-}
diff --git a/trip.rc b/trip.rc
Binary files differ.
diff --git a/utils.c b/utils.c
@@ -1,116 +0,0 @@
-/* utils.c: functions of general utility */
-
-#include <errno.h>
-#include <setjmp.h>
-#include "rc.h"
-#include "jbwrap.h"
-
-/* print error with line number on noninteractive shells (i.e., scripts) */
-
-extern void pr_error(char *s) {
- if (s != NULL) {
- if (interactive)
- fprint(2, "%s\n", s);
- else
- fprint(2, "line %d: %s\n", lineno - 1, s);
- }
-}
-
-/* our perror */
-
-extern void uerror(char *s) {
- extern int sys_nerr;
- extern char *sys_errlist[];
- if (errno > sys_nerr)
- return;
- if (s != NULL)
- fprint(2, "%s: %s\n", s, sys_errlist[errno]);
- else
- fprint(2, "%s\n", sys_errlist[errno]);
-}
-
-/* Die horribly. This should never get called. Please let me know if it does. */
-
-#define PANICMSG "rc panic: "
-
-extern void panic(char *s) {
- write(2, PANICMSG, conststrlen(PANICMSG));
- write(2, s, strlen(s));
- write(2, "!\n", 2);
- exit(1);
-}
-
-/* ascii -> unsigned conversion routines. -1 indicates conversion error. */
-
-extern int n2u(char *s, unsigned int base) {
- unsigned int i;
- for (i = 0; *s != '\0'; s++) {
- unsigned int j = (unsigned int) *s - '0';
- if (j >= base) /* small hack with unsigned ints -- one compare for range test */
- return -1;
- i = i * base + j;
- }
- return (int) i;
-}
-
-/* The last word in portable ANSI: a strcmp wrapper for qsort */
-
-extern int starstrcmp(const void *s1, const void *s2) {
- return strcmp(*(char **)s1, *(char **)s2);
-}
-
-/* tests to see if pathname begins with "/", "./", or "../" */
-
-extern bool isabsolute(char *path) {
- return path[0] == '/' || (path[0] == '.' && (path[1] == '/' || (path[1] == '.' && path[2] == '/')));
-}
-
-/* signal-safe read and write (for BSD slow devices). writeall also allows partial writes */
-
-extern void writeall(int fd, char *buf, size_t remain) {
- int i;
- for (i = 0; remain > 0; buf += i, remain -= i) {
- interrupt_happened = FALSE;
- if (!setjmp(slowbuf.j)) {
- slow = TRUE;
- if (interrupt_happened)
- break;
- else if ((i = write(fd, buf, remain)) <= 0)
- break; /* abort silently on errors in write() */
- } else
- break;
- slow = FALSE;
- }
- slow = FALSE;
- sigchk();
-}
-
-extern int rc_read(int fd, char *buf, size_t n) {
- long /*ssize_t*/ r;
- interrupt_happened = FALSE;
- if (!setjmp(slowbuf.j)) {
- slow = TRUE;
- if (!interrupt_happened)
- r = read(fd, buf, n);
- else
- r = -2;
- } else
- r = -2;
- slow = FALSE;
- if (r == -2) {
- errno = EINTR;
- r = -1;
- }
- return r;
-}
-
-/* duplicate a fd and close the old one only if necessary */
-
-extern int mvfd(int i, int j) {
- if (i != j) {
- int s = dup2(i, j);
- close(i);
- return s;
- }
- return 0;
-}
diff --git a/var.c b/var.c
@@ -1,225 +0,0 @@
-/* var.c: provide "public" functions for adding and removing variables from the symbol table */
-
-#include "rc.h"
-
-static void colonassign(char *, List *, bool);
-static void listassign(char *, List *, bool);
-static int hasalias(char *);
-
-static char *const aliases[] = {
- "home", "HOME", "path", "PATH", "cdpath", "CDPATH"
-};
-
-/* assign a variable in List form to a name, stacking if appropriate */
-
-extern void varassign(char *name, List *def, bool stack) {
- Variable *new;
- List *newdef = listcpy(def, ealloc); /* important to do the listcpy first; get_var_place() frees old values */
- new = get_var_place(name, stack);
- new->def = newdef;
- new->extdef = NULL;
-#if READLINE /* need to reset readline() every time TERM or TERMCAP changes */
- if (interactive && (streq(name, "TERM") || streq(name, "TERMCAP"))) {
- extern void rl_reset_terminal(char *);
- rl_reset_terminal(NULL);
- }
-#endif
-}
-
-/* assign a variable in string form. Check to see if it is aliased (e.g., PATH and path) */
-
-extern bool varassign_string(char *extdef) {
- static bool aliasset[arraysize(aliases)] = {
- FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
- };
- char *name = get_name(extdef);
- Variable *new;
- int i;
- if (name == NULL)
- return FALSE; /* add it to bozo env */
- if ((i = hasalias(name)) != -1) {
- aliasset[i] = TRUE;
- i ^= 1; /* set i to the "opposite" case subscript and */
- if (i&1 && aliasset[i]) /* don't alias variables that are already set in upper case */
- return TRUE;
- }
- new = get_var_place(name, FALSE);
- new->def = NULL;
- new->extdef = ealloc(strlen(extdef) + 1);
- strcpy(new->extdef, extdef);
- if (i != -1)
- alias(name, varlookup(name), FALSE);
- return TRUE;
-}
-
-/*
- Return a List based on a name lookup. If the list is in external (string) form,
- convert it to internal (List) form. Treat $n (n is an integer) specially as $*(n).
- Also check to see if $status is being dereferenced. (we lazily evaluate the List
- associated with $status)
-*/
-
-extern List *varlookup(char *name) {
- Variable *look;
- List *ret, *l;
- int sub;
- if (streq(name, "status"))
- return sgetstatus();
- if (streq(name, "apids"))
- return sgetapids();
- if (*name != '\0' && (sub = a2u(name)) != -1) { /* handle $1, $2, etc. */
- for (l = varlookup("*"); l != NULL && sub != 0; --sub)
- l = l->n;
- if (l == NULL)
- return NULL;
- ret = nnew(List);
- ret->w = l->w;
- ret->m = NULL;
- ret->n = NULL;
- return ret;
- }
- look = lookup_var(name);
- if (look == NULL)
- return NULL; /* not found */
- if (look->def != NULL)
- return look->def;
- if (look->extdef == NULL)
- return NULL; /* variable was set to null, e.g., a=() echo foo */
- ret = parse_var(name, look->extdef);
- if (ret == NULL) {
- look->extdef = NULL;
- return NULL;
- }
- return look->def = ret;
-}
-
-/* lookup a variable in external (string) form, converting if necessary. Used by makeenv() */
-
-extern char *varlookup_string(char *name) {
- Variable *look;
- look = lookup_var(name);
- if (look == NULL)
- return NULL;
- if (look->extdef != NULL)
- return look->extdef;
- if (look->def == NULL)
- return NULL;
- return look->extdef = mprint("%F=%-L", name, look->def, "\001");
-}
-
-/* remove a variable from the symtab. "stack" determines whether a level of scoping is popped or not */
-
-extern void varrm(char *name, bool stack) {
- int i = hasalias(name);
- if (streq(name, "*") && !stack) { /* when assigning () to $*, we want to preserve $0 */
- varassign("*", varlookup("0"), FALSE);
- return;
- }
- delete_var(name, stack);
- if (i != -1)
- delete_var(aliases[i^1], stack);
-}
-
-/* assign a value (List) to a variable, using array "a" as input. Used to assign $* */
-
-extern void starassign(char *dollarzero, char **a, bool stack) {
- List *s, *var;
- var = nnew(List);
- var->w = dollarzero;
- if (*a == NULL) {
- var->n = NULL;
- varassign("*", var, stack);
- return;
- }
- var->n = s = nnew(List);
- while (1) {
- s->w = *a++;
- if (*a == NULL) {
- s->n = NULL;
- break;
- } else
- s = s->n = nnew(List);
- }
- varassign("*", var, stack);
-}
-
-/* (ugly name, huh?) assign a colon-separated value to a variable (e.g., PATH) from a List (e.g., path) */
-
-static void colonassign(char *name, List *def, bool stack) {
- List dud;
- if (def == NULL) {
- varassign(name, NULL, stack);
- return;
- }
- dud.w = nprint("%-L", def, ":");
- dud.n = NULL;
- varassign(name, &dud, stack);
-}
-
-/* assign a List variable (e.g., path) from a colon-separated string (e.g., PATH) */
-
-static void listassign(char *name, List *def, bool stack) {
- List *val, *r;
- char *v, *w;
- if (def == NULL) {
- varassign(name, NULL, stack);
- return;
- }
- v = def->w;
- r = val = nnew(List);
- while ((w = strchr(v, ':')) != NULL) {
- *w = '\0';
- r->w = ncpy(v);
- *w = ':';
- v = w + 1;
- r = r->n = nnew(List);
- }
- r->w = ncpy(v);
- r->n = NULL;
- varassign(name, val, stack);
-}
-
-/* check to see if a particular variable is aliased; return -1 on failure, or the index */
-
-static int hasalias(char *name) {
- int i;
- for (i = 0; i < arraysize(aliases); i++)
- if (streq(name, aliases[i]))
- return i;
- return -1;
-}
-
-/* alias a variable to its lowercase equivalent. function pointers are used to specify the conversion function */
-
-extern void alias(char *name, List *s, bool stack) {
- static void (*vectors[])(char *, List *, bool) = {
- varassign, varassign, colonassign, listassign, colonassign, listassign
- };
- int i = hasalias(name);
- if (i != -1)
- (*vectors[i])(aliases[i^1], s, stack); /* xor hack to reverse case of alias entry */
-}
-
-extern void prettyprint_var(int fd, char *name, List *s) {
- int i;
- static const char * const keywords[] = {
- "if", "in", "fn", "for", "else", "switch", "while", "case"
- };
- if (s == NULL) {
- fprint(fd, "%S=()\n", name);
- return;
- }
- if (streq(name, "*")) {
- s = s->n;
- if (s == NULL)
- return; /* Don't print $0, and if $* is not set, skip it */
- }
- for (i = 0; i < arraysize(keywords); i++)
- if (streq(keywords[i], name)) {
- fprint(fd, "%#S=", name);
- goto value;
- }
- fprint(fd, "%S=", name);
-value:
- fprint(fd, s->n == NULL ? "%L\n" : "(%L)\n", s, " ");
-}
diff --git a/version.c b/version.c
@@ -1 +0,0 @@
-const char id[] = "@(#)rc version 1.5b2, 1997-07-01.";
diff --git a/wait.c b/wait.c
@@ -1,129 +0,0 @@
-#include "rc.h"
-
-#include <errno.h>
-#include <setjmp.h>
-#include <sys/wait.h>
-
-#include "jbwrap.h"
-
-bool forked = FALSE;
-
-static pid_t rc_wait(int *);
-
-typedef struct Pid Pid;
-
-static struct Pid {
- pid_t pid;
- int stat;
- bool alive;
- Pid *n;
-} *plist = NULL;
-
-extern pid_t rc_fork() {
- Pid *new;
- pid_t pid = fork();
- switch (pid) {
- case -1:
- uerror("fork");
- rc_error(NULL);
- /* NOTREACHED */
- case 0:
- forked = TRUE;
- sigchk();
- return 0;
- default:
- new = enew(Pid);
- new->pid = pid;
- new->alive = TRUE;
- new->n = plist;
- plist = new;
- return pid;
- }
-}
-
-extern pid_t rc_wait4(pid_t pid, int *stat, bool nointr) {
- Pid *r, *prev;
- int ret;
- /* first look for a child which may already have exited */
-again: for (r = plist, prev = NULL; r != NULL; prev = r, r = r->n)
- if (r->pid == pid)
- break;
- if (r == NULL) {
- errno = ECHILD; /* no children */
- uerror("wait");
- *stat = 0x100; /* exit(1) */
- return -1;
- }
- if (r->alive) {
- while (pid != (ret = rc_wait(stat))) {
- Pid *q;
- if (ret < 0) {
- if (nointr)
- goto again;
- return ret;
- }
- for (q = plist; q != NULL; q = q->n)
- if (q->pid == ret) {
- q->alive = FALSE;
- q->stat = *stat;
- break;
- }
- }
- } else
- *stat = r->stat;
- if (prev == NULL)
- plist = r->n; /* remove element from head of list */
- else
- prev->n = r->n;
- efree(r);
- return pid;
-}
-
-extern List *sgetapids() {
- List *r;
- Pid *p;
- for (r = NULL, p = plist; p != NULL; p = p->n) {
- List *q;
- if (!p->alive)
- continue;
- q = nnew(List);
- q->w = nprint("%d", p->pid);
- q->m = NULL;
- q->n = r;
- r = q;
- }
- return r;
-}
-
-extern void waitforall() {
- int stat;
- while (plist != NULL) {
- int pid = rc_wait4(plist->pid, &stat, FALSE);
- if (pid > 0)
- setstatus(pid, stat);
- else
- set(FALSE);
- sigchk();
- }
-}
-
-/*
- rc_wait: a wait() wrapper that interfaces wait() w/rc signals.
- Note that the signal queue is not checked in this fn; someone
- may want to resume the wait() without delivering any signals.
-*/
-
-static pid_t rc_wait(int *stat) {
- int r;
- interrupt_happened = FALSE;
- if (!setjmp(slowbuf.j)) {
- slow = TRUE;
- if (!interrupt_happened)
- r = wait(stat);
- else
- r = -1;
- } else
- r = -1;
- slow = FALSE;
- return r;
-}
diff --git a/walk.c b/walk.c
@@ -1,358 +0,0 @@
-/* walk.c: walks the parse tree. */
-
-#include <signal.h>
-#include <setjmp.h>
-#include "rc.h"
-#include "jbwrap.h"
-
-/*
- global which indicates whether rc is executing a test;
- used by rc -e so that if (false) does not exit.
-*/
-bool cond = FALSE;
-
-static bool haspreredir(Node *);
-static bool isallpre(Node *);
-static bool dofork(bool);
-static void dopipe(Node *);
-
-/* Tail-recursive version of walk() */
-
-#define WALK(x, y) { n = x; parent = y; goto top; }
-
-/* walk the parse-tree. "obvious". */
-
-extern bool walk(Node *n, bool parent) {
-top: sigchk();
- if (n == NULL) {
- if (!parent)
- exit(0);
- set(TRUE);
- return TRUE;
- }
- switch (n->type) {
- case nArgs: case nBackq: case nConcat: case nCount:
- case nFlat: case nLappend: case nRedir: case nVar:
- case nVarsub: case nWord: case nQword:
- exec(glob(glom(n)), parent); /* simple command */
- break;
- case nBody:
- walk(n->u[0].p, TRUE);
- WALK(n->u[1].p, parent);
- /* WALK doesn't fall through */
- case nNowait: {
- int pid;
- if ((pid = rc_fork()) == 0) {
-#if defined(RC_JOB) && defined(SIGTTOU) && defined(SIGTTIN) && defined(SIGTSTP)
- setsigdefaults(FALSE);
- rc_signal(SIGTTOU, SIG_IGN); /* Berkeleyized version: put it in a new pgroup. */
- rc_signal(SIGTTIN, SIG_IGN);
- rc_signal(SIGTSTP, SIG_IGN);
- setpgid(0, getpid());
-#else
- setsigdefaults(TRUE); /* ignore SIGINT, SIGQUIT, SIGTERM */
-#endif
- mvfd(rc_open("/dev/null", rFrom), 0);
- walk(n->u[0].p, FALSE);
- exit(getstatus());
- }
- if (interactive)
- fprint(2, "%d\n", pid);
- varassign("apid", word(nprint("%d", pid), NULL), FALSE);
- redirq = NULL; /* kill pre-redir queue */
- break;
- }
- case nAndalso: {
- bool oldcond = cond;
- cond = TRUE;
- if (walk(n->u[0].p, TRUE)) {
- cond = oldcond;
- WALK(n->u[1].p, parent);
- } else
- cond = oldcond;
- break;
- }
- case nOrelse: {
- bool oldcond = cond;
- cond = TRUE;
- if (!walk(n->u[0].p, TRUE)) {
- cond = oldcond;
- WALK(n->u[1].p, parent);
- } else
- cond = oldcond;
- break;
- }
- case nBang:
- set(!walk(n->u[0].p, TRUE));
- break;
- case nIf: {
- bool oldcond = cond;
- Node *true_cmd = n->u[1].p, *false_cmd = NULL;
- if (true_cmd != NULL && true_cmd->type == nElse) {
- false_cmd = true_cmd->u[1].p;
- true_cmd = true_cmd->u[0].p;
- }
- cond = TRUE;
- if (!walk(n->u[0].p, TRUE))
- true_cmd = false_cmd; /* run the else clause */
- cond = oldcond;
- WALK(true_cmd, parent);
- }
- case nWhile: {
- Jbwrap j;
- Edata jbreak;
- Estack e1, e2;
- bool testtrue, oldcond = cond;
- cond = TRUE;
- if (!walk(n->u[0].p, TRUE)) { /* prevent spurious breaks inside test */
- cond = oldcond;
- break;
- }
- if (setjmp(j.j))
- break;
- jbreak.jb = &j;
- except(eBreak, jbreak, &e1);
- do {
- Edata block;
- block.b = newblock();
- cond = oldcond;
- except(eArena, block, &e2);
- walk(n->u[1].p, TRUE);
- testtrue = walk(n->u[0].p, TRUE);
- unexcept(); /* eArena */
- cond = TRUE;
- } while (testtrue);
- cond = oldcond;
- unexcept(); /* eBreak */
- break;
- }
- case nForin: {
- List *l, *var = glom(n->u[0].p);
- Jbwrap j;
- Estack e1, e2;
- Edata jbreak;
- if (setjmp(j.j))
- break;
- jbreak.jb = &j;
- except(eBreak, jbreak, &e1);
- for (l = listcpy(glob(glom(n->u[1].p)), nalloc); l != NULL; l = l->n) {
- Edata block;
- assign(var, word(l->w, NULL), FALSE);
- block.b = newblock();
- except(eArena, block, &e2);
- walk(n->u[2].p, TRUE);
- unexcept(); /* eArena */
- }
- unexcept(); /* eBreak */
- break;
- }
- case nSubshell:
- if (dofork(TRUE)) {
- walk(n->u[0].p, FALSE);
- rc_exit(getstatus());
- }
- break;
- case nAssign:
- if (n->u[0].p == NULL)
- rc_error("null variable name");
- assign(glom(n->u[0].p), glob(glom(n->u[1].p)), FALSE);
- set(TRUE);
- break;
- case nPipe:
- dopipe(n);
- break;
- case nNewfn: {
- List *l = glom(n->u[0].p);
- if (l == NULL)
- rc_error("null function name");
- while (l != NULL) {
- if (dashex)
- prettyprint_fn(2, l->w, n->u[1].p);
- fnassign(l->w, n->u[1].p);
- l = l->n;
- }
- set(TRUE);
- break;
- }
- case nRmfn: {
- List *l = glom(n->u[0].p);
- while (l != NULL) {
- if (dashex)
- fprint(2, "fn %S\n", l->w);
- fnrm(l->w);
- l = l->n;
- }
- set(TRUE);
- break;
- }
- case nDup:
- redirq = NULL;
- break; /* Null command */
- case nMatch: {
- List *a = glob(glom(n->u[0].p)), *b = glom(n->u[1].p);
- if (dashex)
- fprint(2, (a != NULL && a->n != NULL) ? "~ (%L) %L\n" : "~ %L %L\n", a, " ", b, " ");
- set(lmatch(a, b));
- break;
- }
- case nSwitch: {
- List *v = glom(n->u[0].p);
- while (1) {
- do {
- n = n->u[1].p;
- if (n == NULL)
- return istrue();
- } while (n->u[0].p == NULL || n->u[0].p->type != nCase);
- if (lmatch(v, glom(n->u[0].p->u[0].p))) {
- for (n = n->u[1].p; n != NULL && (n->u[0].p == NULL || n->u[0].p->type != nCase); n = n->u[1].p)
- walk(n->u[0].p, TRUE);
- break;
- }
- }
- break;
- }
- case nPre: {
- List *v;
- if (n->u[0].p->type == nRedir || n->u[0].p->type == nDup) {
- if (redirq == NULL && !dofork(parent)) /* subshell on first preredir */
- break;
- qredir(n->u[0].p);
- if (!haspreredir(n->u[1].p))
- doredirs(); /* no more preredirs, empty queue */
- walk(n->u[1].p, FALSE);
- rc_exit(getstatus());
- /* NOTREACHED */
- } else if (n->u[0].p->type == nAssign) {
- if (isallpre(n->u[1].p)) {
- walk(n->u[0].p, TRUE);
- WALK(n->u[1].p, parent);
- } else {
- Estack e;
- Edata var;
- v = glom(n->u[0].p->u[0].p);
- assign(v, glob(glom(n->u[0].p->u[1].p)), TRUE);
- var.name = v->w;
- except(eVarstack, var, &e);
- walk(n->u[1].p, parent);
- varrm(v->w, TRUE);
- unexcept(); /* eVarstack */
- }
- } else
- panic("unexpected node in preredir section of walk");
- break;
- }
- case nBrace:
- if (n->u[1].p == NULL) {
- WALK(n->u[0].p, parent);
- } else if (dofork(parent)) {
- walk(n->u[1].p, TRUE); /* Do redirections */
- redirq = NULL; /* Reset redirection queue */
- walk(n->u[0].p, FALSE); /* Do commands */
- rc_exit(getstatus());
- /* NOTREACHED */
- }
- break;
- case nEpilog:
- qredir(n->u[0].p);
- if (n->u[1].p != NULL) {
- WALK(n->u[1].p, parent); /* Do more redirections. */
- } else {
- doredirs(); /* Okay, we hit the bottom. */
- }
- break;
- case nNmpipe:
- rc_error("named pipes cannot be executed as commands");
- /* NOTREACHED */
- default:
- panic("unknown node in walk");
- /* NOTREACHED */
- }
- return istrue();
-}
-
-/* checks to see whether there are any pre-redirections left in the tree */
-
-static bool haspreredir(Node *n) {
- while (n != NULL && n->type == nPre) {
- if (n->u[0].p->type == nDup || n->u[0].p->type == nRedir)
- return TRUE;
- n = n->u[1].p;
- }
- return FALSE;
-}
-
-/* checks to see whether a subtree is all pre-command directives, i.e., assignments and redirs only */
-
-static bool isallpre(Node *n) {
- while (n != NULL && n->type == nPre)
- n = n->u[1].p;
- return n == NULL || n->type == nRedir || n->type == nAssign || n->type == nDup;
-}
-
-/*
- A code-saver. Forks, child returns (for further processing in walk()), and the parent
- waits for the child to finish, setting $status appropriately.
-*/
-
-static bool dofork(bool parent) {
- int pid, sp;
-
- if (!parent || (pid = rc_fork()) == 0)
- return TRUE;
- redirq = NULL; /* clear out the pre-redirection queue in the parent */
- rc_wait4(pid, &sp, TRUE);
- setstatus(-1, sp);
- sigchk();
- return FALSE;
-}
-
-static void dopipe(Node *n) {
- int i, j, sp, pid, fd_prev, fd_out, pids[512], stats[512], p[2];
- bool intr;
- Node *r;
-
- fd_prev = fd_out = 1;
- for (r = n, i = 0; r != NULL && r->type == nPipe; r = r->u[2].p, i++) {
- if (i > 500) /* the only hard-wired limit in rc? */
- rc_error("pipe too long");
- if (pipe(p) < 0) {
- uerror("pipe");
- rc_error(NULL);
- }
- if ((pid = rc_fork()) == 0) {
- redirq = NULL; /* clear preredir queue */
- mvfd(p[0], r->u[1].i);
- if (fd_prev != 1)
- mvfd(fd_prev, fd_out);
- close(p[1]);
- walk(r->u[3].p, FALSE);
- exit(getstatus());
- }
- if (fd_prev != 1)
- close(fd_prev); /* parent must close all pipe fd's */
- pids[i] = pid;
- fd_prev = p[1];
- fd_out = r->u[0].i;
- close(p[0]);
- }
- if ((pid = rc_fork()) == 0) {
- mvfd(fd_prev, fd_out);
- walk(r, FALSE);
- exit(getstatus());
- /* NOTREACHED */
- }
- redirq = NULL; /* clear preredir queue */
- close(fd_prev);
- pids[i++] = pid;
-
- /* collect statuses */
-
- intr = FALSE;
- for (j = 0; j < i; j++) {
- rc_wait4(pids[j], &sp, TRUE);
- stats[j] = sp;
- intr |= (sp == SIGINT);
- }
- setpipestatus(stats, i);
- sigchk();
-}
diff --git a/which.c b/which.c
@@ -1,121 +0,0 @@
-/* which.c: check to see if a file is executable.
-
- This function was originally written with Maarten Litmaath's which.c as
- a template, but was changed in order to accomodate the possibility of
- rc's running setuid or the possibility of executing files not in the
- primary group. Much of this file has been re-vamped by Paul Haahr.
- I re-re-vamped the functions that Paul supplied to correct minor bugs
- and to strip out unneeded functionality.
-*/
-
-#include "rc.h"
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#define X_USR 0100
-#define X_GRP 0010
-#define X_OTH 0001
-#define X_ALL (X_USR|X_GRP|X_OTH)
-
-extern int stat(const char *, struct stat *);
-
-static bool initialized = FALSE;
-static uid_t uid;
-static gid_t gid;
-
-#if HAVE_GETGROUPS
-static int ngroups;
-static GETGROUPS_T *gidset;
-
-/* determine whether gid lies in gidset */
-
-static int ingidset(gid_t g) {
- gid_t i;
- for (i = 0; i < ngroups; ++i)
- if (g == gidset[i])
- return 1;
- return 0;
-}
-#endif
-
-/*
- A home-grown access/stat. Does the right thing for group-executable files.
- Returns a bool instead of this -1 nonsense.
-*/
-
-static bool rc_access(char *path, bool verbose) {
- struct stat st;
- int mask;
- if (stat(path, &st) != 0) {
- if (verbose) /* verbose flag only set for absolute pathname */
- uerror(path);
- return FALSE;
- }
- if (uid == 0)
- mask = X_ALL;
- else if (uid == st.st_uid)
- mask = X_USR;
-#if HAVE_GETGROUPS
- else if (gid == st.st_gid || ingidset(st.st_gid))
-#else
- else if (gid == st.st_gid)
-#endif
- mask = X_GRP;
- else
- mask = X_OTH;
- if (((st.st_mode & S_IFMT) == S_IFREG) && (st.st_mode & mask))
- return TRUE;
- errno = EACCES;
- if (verbose)
- uerror(path);
- return FALSE;
-}
-
-/* return a full pathname by searching $path, and by checking the status of the file */
-
-extern char *which(char *name, bool verbose) {
- static char *test = NULL;
- static size_t testlen = 0;
- List *path;
- int len;
- if (name == NULL) /* no filename? can happen with "> foo" as a command */
- return NULL;
- if (!initialized) {
- initialized = TRUE;
- uid = geteuid();
- gid = getegid();
-#if HAVE_GETGROUPS
- ngroups = getgroups(0, (gid_t *)0);
- gidset = malloc(ngroups * sizeof(gid_t));
- if (!gidset)
- uerror("malloc");
- else
- getgroups(ngroups, gidset);
-#endif
- }
- if (isabsolute(name)) /* absolute pathname? */
- return rc_access(name, verbose) ? name : NULL;
- len = strlen(name);
- for (path = varlookup("path"); path != NULL; path = path->n) {
- size_t need = strlen(path->w) + len + 2; /* one for null terminator, one for the '/' */
- if (testlen < need) {
- efree(test);
- test = ealloc(testlen = need);
- }
- if (*path->w == '\0') {
- strcpy(test, name);
- } else {
- strcpy(test, path->w);
- if (!streq(test, "/")) /* "//" is special to POSIX */
- strcat(test, "/");
- strcat(test, name);
- }
- if (rc_access(test, FALSE))
- return test;
- }
- if (verbose)
- fprint(2, "%s not found\n", name);
- return NULL;
-}
diff --git a/y.tab.c b/y.tab.c
@@ -1,1070 +0,0 @@
-#ifndef lint
-static char const yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
-#endif
-#define YYBYACC 1
-#define YYMAJOR 1
-#define YYMINOR 9
-#define YYLEX yylex()
-#define YYEMPTY -1
-#define yyclearin (yychar=(YYEMPTY))
-#define yyerrok (yyerrflag=0)
-#define YYRECOVERING (yyerrflag!=0)
-/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
-#ifdef c_plusplus
-#ifndef __cplusplus
-#define __cplusplus
-#endif
-#endif
-#ifdef __cplusplus
-extern "C" { char *getenv(const char *); }
-#else
-extern char *getenv();
-extern int yylex();
-extern int yyparse();
-#endif
-#define YYPREFIX "yy"
-#line 8 "parse.y"
-#include "rc.h"
-#ifndef lint
-#define lint /* hush up gcc -Wall, leave out the dumb sccsid's. */
-#endif
-static Node *star, *nolist;
-Node *parsetree; /* not using yylval because bison declares it as an auto */
-#line 28 "parse.y"
-typedef union {
- struct Node *node;
- struct Redir redir;
- struct Pipe pipe;
- struct Dup dup;
- struct Word word;
- char *keyword;
-} YYSTYPE;
-#line 43 "y.tab.c"
-#define ANDAND 257
-#define BACKBACK 258
-#define BANG 259
-#define CASE 260
-#define COUNT 261
-#define DUP 262
-#define ELSE 263
-#define END 264
-#define FLAT 265
-#define FN 266
-#define FOR 267
-#define IF 268
-#define IN 269
-#define OROR 270
-#define PIPE 271
-#define REDIR 272
-#define SREDIR 273
-#define SUB 274
-#define SUBSHELL 275
-#define SWITCH 276
-#define TWIDDLE 277
-#define WHILE 278
-#define WORD 279
-#define HUH 280
-#define YYERRCODE 256
-const short yylhs[] = { -1,
- 0, 0, 22, 22, 8, 8, 13, 13, 3, 3,
- 9, 9, 4, 15, 2, 11, 11, 16, 16, 16,
- 5, 5, 6, 6, 6, 19, 19, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 24, 24, 18, 18, 18,
- 12, 12, 17, 17, 20, 20, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 21, 21,
- 14, 14, 14, 23, 23,
-};
-const short yylen[] = { 2,
- 2, 2, 1, 1, 2, 2, 1, 2, 1, 2,
- 1, 2, 3, 3, 3, 0, 2, 1, 2, 2,
- 3, 3, 1, 2, 2, 1, 4, 0, 1, 2,
- 4, 8, 6, 4, 8, 4, 4, 4, 4, 2,
- 2, 3, 3, 3, 2, 0, 1, 1, 2, 2,
- 1, 3, 1, 1, 1, 3, 2, 5, 2, 2,
- 2, 2, 3, 3, 3, 2, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 0, 2,
- 0, 2, 2, 0, 2,
-};
-const short yydefred[] = { 0,
- 0, 0, 0, 0, 18, 0, 79, 0, 0, 0,
- 0, 0, 0, 0, 0, 67, 0, 0, 81, 0,
- 0, 0, 0, 0, 0, 51, 0, 0, 0, 0,
- 3, 4, 2, 77, 75, 74, 73, 68, 71, 69,
- 0, 78, 72, 76, 70, 54, 53, 55, 0, 47,
- 0, 59, 60, 0, 0, 0, 84, 66, 0, 0,
- 0, 0, 0, 84, 0, 0, 0, 11, 0, 0,
- 62, 61, 0, 0, 30, 0, 84, 84, 84, 5,
- 6, 8, 0, 0, 1, 0, 50, 0, 0, 63,
- 64, 0, 44, 0, 0, 0, 0, 0, 0, 0,
- 0, 79, 13, 12, 10, 65, 82, 0, 17, 0,
- 0, 0, 0, 52, 56, 79, 84, 14, 85, 0,
- 0, 31, 84, 0, 0, 0, 0, 0, 39, 0,
- 0, 84, 0, 58, 84, 0, 0, 0, 0, 0,
- 79, 0, 0, 0, 0, 0, 0, 24, 35, 25,
- 22, 21,
-};
-const short yydgoto[] = { 21,
- 46, 22, 66, 23, 142, 143, 67, 68, 69, 47,
- 75, 27, 28, 70, 57, 29, 48, 30, 122, 94,
- 54, 33, 97, 51,
-};
-const short yysindex[] = { 874,
- 24, 1001, -82, 1001, 0, 1001, 0, -27, -26, 900,
- 1001, -82, -20, -82, -26, 0, 1001, 1134, 0, 900,
- 0, 1134, -203, -30, 1134, 0, -55, 24, 1134, 826,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- -66, 0, 0, 0, 0, 0, 0, 0, 849, 0,
- 1134, 0, 0, 900, 1001, 1134, 0, 0, -52, -52,
- 1134, 1001, 1001, 0, -212, -58, 154, 0, 1134, 426,
- 0, 0, -196, 1001, 0, -203, 0, 0, 0, 0,
- 0, 0, 1001, 1001, 0, -196, 0, -52, 1001, 0,
- 0, -196, 0, -52, -38, 36, 502, -196, -36, -52,
- 502, 0, 0, 0, 0, 0, 0, -52, 0, 502,
- 502, 502, -52, 0, 0, 0, 0, 0, 0, -97,
- -234, 0, 0, 1001, -234, 922, -196, -196, 0, 944,
- 502, 0, -9, 0, 0, -234, 502, 967, 502, -234,
- 0, 967, -45, 154, 967, -234, 448, 0, 0, 0,
- 0, 0,
-};
-const short yyrindex[] = { 134,
- 0, 0, 356, 0, 0, 0, 0, 0, 0, 0,
- 0, 356, 0, 1024, 0, 0, 0, 571, 0, 0,
- 0, 487, 529, 54, 134, 0, 62, 0, 487, 548,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 487, 0, 0, 712, 0, 142, 0, 0, 14, 38,
- 487, 0, 0, 0, -10, 0, -32, 0, 744, 0,
- 0, 0, 749, 0, 0, 529, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 763, 0, 86, 0, 0,
- 0, 779, 0, 110, 0, 0, -34, 788, 0, 380,
- -34, 0, 0, 0, 0, 0, 0, 470, 0, -34,
- -34, -34, 404, 0, 0, 0, 0, 0, 0, 529,
- 6, 0, 0, 724, 30, 0, 805, 813, 0, 0,
- -34, 0, 0, 0, 0, 119, -34, 571, -34, 187,
- 0, 571, 0, -44, 571, 396, 0, 0, 0, 0,
- 0, 0,
-};
-const short yygindex[] = { 0,
- 0, 0, -23, 12, 0, -104, 1319, 2, -127, 1307,
- 7, 0, 57, 0, 70, -13, 84, 0, 0, 420,
- -81, 59, 369, 31,
-};
-#define YYTABLESIZE 1464
-const short yytable[] = { 57,
- 119, 25, 117, 28, 123, 83, 28, 81, 9, 76,
- 145, 50, 55, 56, 145, 26, 87, 145, 124, 62,
- 126, 58, 77, 19, 28, 57, 25, 57, 80, 57,
- 57, 71, 96, 32, 130, 78, 79, 148, 84, 34,
- 150, 89, 61, 26, 63, 105, 26, 20, 57, 19,
- 57, 19, 58, 19, 19, 89, 18, 89, 5, 147,
- 90, 102, 76, 7, 26, 93, 103, 34, 74, 11,
- 34, 48, 19, 20, 79, 20, 118, 20, 20, 149,
- 23, 82, 109, 57, 64, 57, 85, 52, 34, 53,
- 28, 0, 9, 0, 0, 49, 20, 48, 0, 48,
- 65, 48, 48, 72, 0, 0, 76, 0, 120, 19,
- 0, 0, 57, 138, 57, 0, 0, 0, 0, 80,
- 48, 49, 0, 49, 0, 49, 49, 0, 33, 0,
- 26, 0, 91, 20, 0, 0, 19, 0, 19, 0,
- 0, 0, 0, 28, 49, 80, 0, 80, 0, 80,
- 80, 28, 0, 0, 34, 0, 33, 48, 0, 33,
- 20, 0, 20, 104, 5, 132, 0, 114, 80, 0,
- 0, 28, 115, 0, 74, 11, 0, 33, 0, 28,
- 0, 49, 28, 0, 0, 0, 48, 0, 0, 0,
- 0, 81, 28, 0, 0, 0, 27, 0, 0, 0,
- 28, 0, 0, 0, 0, 80, 0, 0, 0, 0,
- 49, 0, 80, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 28, 0, 27, 0, 77, 27, 0, 28,
- 116, 0, 80, 0, 80, 28, 28, 0, 0, 78,
- 79, 0, 0, 33, 0, 27, 57, 57, 57, 57,
- 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
- 57, 57, 57, 0, 57, 57, 57, 57, 57, 26,
- 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 31, 19, 19,
- 19, 19, 19, 34, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 27, 20, 20, 20, 20, 20, 7, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 0, 48, 48, 48, 48,
- 48, 0, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 0,
- 49, 49, 49, 49, 49, 46, 80, 80, 80, 80,
- 80, 0, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 33, 0, 80, 80, 80, 80, 80, 79,
- 28, 46, 0, 46, 0, 46, 46, 28, 28, 0,
- 0, 0, 0, 28, 28, 32, 0, 0, 0, 0,
- 77, 28, 28, 15, 46, 79, 0, 79, 0, 79,
- 79, 49, 0, 78, 79, 0, 0, 0, 0, 59,
- 60, 0, 101, 32, 0, 107, 32, 0, 79, 15,
- 0, 15, 0, 15, 15, 110, 111, 112, 0, 88,
- 27, 46, 0, 0, 32, 0, 0, 151, 0, 0,
- 0, 17, 15, 0, 0, 19, 106, 0, 0, 0,
- 0, 0, 0, 0, 95, 79, 0, 0, 46, 83,
- 46, 99, 100, 17, 0, 131, 0, 19, 0, 108,
- 0, 133, 0, 59, 0, 0, 28, 0, 0, 15,
- 137, 0, 113, 139, 79, 83, 152, 0, 0, 83,
- 83, 119, 0, 0, 0, 0, 0, 0, 0, 0,
- 32, 20, 0, 0, 28, 0, 15, 28, 15, 0,
- 0, 0, 0, 0, 0, 0, 0, 17, 16, 0,
- 0, 19, 0, 20, 0, 28, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 29, 0, 0,
- 0, 0, 0, 0, 0, 83, 16, 0, 0, 16,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 28, 0, 0, 0, 0, 29, 0, 16, 29, 0,
- 0, 0, 0, 0, 0, 0, 0, 20, 0, 0,
- 0, 0, 0, 0, 0, 0, 29, 0, 28, 0,
- 0, 28, 46, 46, 46, 0, 46, 46, 0, 46,
- 46, 46, 46, 46, 18, 46, 46, 46, 46, 28,
- 46, 46, 46, 46, 46, 0, 79, 79, 79, 79,
- 79, 0, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 0, 16, 79, 79, 79, 79, 79, 32,
- 15, 15, 15, 0, 15, 15, 0, 15, 15, 15,
- 15, 15, 29, 15, 15, 15, 15, 0, 15, 15,
- 15, 15, 15, 2, 34, 35, 4, 0, 36, 0,
- 6, 37, 38, 39, 40, 28, 0, 41, 0, 0,
- 42, 43, 44, 45, 16, 2, 34, 35, 4, 0,
- 36, 0, 6, 37, 38, 39, 40, 0, 0, 41,
- 0, 45, 42, 43, 44, 45, 16, 83, 83, 83,
- 83, 0, 83, 36, 83, 83, 83, 83, 83, 0,
- 0, 83, 0, 28, 83, 83, 83, 83, 83, 45,
- 28, 0, 45, 28, 0, 0, 28, 28, 41, 2,
- 3, 36, 4, 5, 36, 0, 6, 7, 8, 9,
- 45, 0, 40, 10, 11, 0, 12, 13, 14, 15,
- 16, 28, 36, 0, 28, 16, 41, 0, 42, 41,
- 0, 0, 16, 0, 0, 0, 0, 43, 16, 16,
- 40, 0, 28, 40, 29, 0, 0, 41, 0, 0,
- 0, 29, 0, 0, 37, 0, 42, 29, 29, 42,
- 0, 40, 38, 0, 0, 43, 0, 28, 43, 0,
- 0, 0, 0, 0, 0, 0, 45, 42, 0, 0,
- 28, 28, 37, 0, 0, 37, 43, 0, 36, 0,
- 38, 0, 0, 38, 0, 0, 0, 0, 0, 0,
- 0, 17, 0, 37, 0, 19, 0, 0, 28, 0,
- 0, 38, 0, 41, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 17, 0, 0, 40, 19, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 42, 0, 0, 0, 0, 0, 17,
- 0, 0, 43, 19, 0, 0, 0, 0, 0, 0,
- 0, 20, 0, 0, 0, 0, 0, 0, 0, 37,
- 0, 0, 0, 0, 0, 17, 0, 38, 0, 19,
- 0, 0, 89, 0, 20, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 17, 0, 0,
- 0, 19, 134, 0, 0, 0, 0, 0, 45, 20,
- 0, 18, 0, 0, 0, 45, 0, 0, 0, 17,
- 36, 45, 45, 19, 135, 0, 0, 36, 0, 0,
- 0, 0, 0, 36, 36, 20, 18, 0, 0, 0,
- 28, 0, 17, 0, 0, 41, 19, 0, 0, 0,
- 0, 0, 41, 28, 28, 0, 0, 20, 41, 40,
- 0, 0, 18, 0, 0, 0, 40, 0, 0, 0,
- 0, 0, 40, 0, 0, 42, 17, 0, 0, 20,
- 19, 0, 42, 0, 43, 0, 0, 0, 42, 0,
- 0, 43, 0, 0, 0, 0, 0, 43, 0, 46,
- 0, 37, 20, 46, 0, 0, 0, 0, 37, 38,
- 0, 0, 0, 0, 37, 0, 38, 0, 0, 0,
- 0, 0, 38, 2, 34, 35, 4, 5, 36, 18,
- 6, 37, 38, 39, 40, 0, 20, 10, 11, 0,
- 42, 43, 44, 45, 16, 0, 2, 34, 35, 4,
- 0, 36, 0, 6, 37, 38, 39, 40, 0, 46,
- 41, 0, 0, 42, 43, 44, 45, 16, 0, 1,
- 0, 2, 3, 0, 4, 5, 0, 0, 6, 7,
- 8, 9, 0, 0, 0, 10, 11, 0, 12, 13,
- 14, 15, 16, 0, 0, 0, 0, 2, 34, 35,
- 4, 0, 36, 0, 6, 37, 38, 39, 40, 17,
- 0, 41, 0, 19, 42, 43, 44, 45, 16, 2,
- 34, 35, 4, 0, 36, 0, 6, 37, 38, 39,
- 40, 0, 0, 41, 0, 0, 42, 43, 44, 45,
- 16, 2, 34, 35, 4, 0, 36, 0, 6, 37,
- 38, 39, 40, 0, 0, 41, 0, 0, 42, 43,
- 44, 45, 16, 0, 2, 3, 141, 4, 5, 20,
- 0, 6, 7, 8, 9, 0, 0, 0, 10, 11,
- 0, 12, 13, 14, 15, 16, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 18, 0, 2, 34,
- 35, 4, 0, 36, 0, 6, 37, 38, 39, 40,
- 0, 0, 41, 0, 0, 42, 43, 44, 45, 16,
- 0, 46, 46, 46, 46, 0, 46, 0, 46, 46,
- 46, 46, 46, 0, 0, 46, 0, 0, 46, 46,
- 46, 46, 46, 0, 0, 0, 26, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 24, 0,
- 0, 0, 0, 0, 26, 0, 0, 0, 26, 0,
- 0, 26, 0, 0, 0, 26, 0, 0, 0, 0,
- 73, 0, 0, 24, 0, 0, 0, 86, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 26, 0, 0,
- 0, 0, 26, 0, 0, 0, 0, 26, 0, 92,
- 0, 0, 0, 0, 0, 26, 0, 0, 0, 98,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 2, 3, 0, 4, 5, 0, 0, 6, 7,
- 8, 9, 0, 26, 0, 10, 11, 26, 12, 13,
- 14, 15, 16, 0, 0, 121, 26, 26, 26, 125,
- 0, 0, 0, 0, 0, 0, 0, 0, 127, 128,
- 129, 0, 0, 0, 0, 0, 0, 26, 0, 0,
- 0, 0, 0, 26, 26, 26, 0, 0, 26, 136,
- 0, 26, 0, 0, 0, 140, 144, 146, 0, 0,
- 144, 0, 0, 144,
-};
-const short yycheck[] = { 10,
- 10, 0, 41, 38, 41, 61, 41, 38, 41, 23,
- 138, 94, 40, 40, 142, 10, 30, 145, 100, 40,
- 102, 10, 257, 10, 59, 36, 25, 38, 59, 40,
- 41, 20, 56, 10, 116, 270, 271, 142, 94, 10,
- 145, 94, 12, 38, 14, 69, 41, 10, 59, 36,
- 61, 38, 41, 40, 41, 94, 123, 94, 262, 141,
- 49, 274, 76, 10, 59, 54, 125, 38, 272, 273,
- 41, 10, 59, 36, 271, 38, 41, 40, 41, 125,
- 125, 25, 76, 94, 15, 96, 28, 4, 59, 6,
- 125, -1, 125, -1, -1, 10, 59, 36, -1, 38,
- 17, 40, 41, 20, -1, -1, 120, -1, 97, 96,
- -1, -1, 123, 123, 125, -1, -1, -1, -1, 10,
- 59, 36, -1, 38, -1, 40, 41, -1, 10, -1,
- 125, -1, 49, 96, -1, -1, 123, -1, 125, -1,
- -1, -1, -1, 10, 59, 36, -1, 38, -1, 40,
- 41, 10, -1, -1, 125, -1, 38, 96, -1, 41,
- 123, -1, 125, 10, 262, 263, -1, 84, 59, -1,
- -1, 38, 89, -1, 272, 273, -1, 59, -1, 38,
- -1, 96, 41, -1, -1, -1, 125, -1, -1, -1,
- -1, 38, 59, -1, -1, -1, 10, -1, -1, -1,
- 59, -1, -1, -1, -1, 96, -1, -1, -1, -1,
- 125, -1, 59, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 257, -1, 38, -1, 257, 41, -1, 264,
- 269, -1, 123, -1, 125, 270, 271, -1, -1, 270,
- 271, -1, -1, 125, -1, 59, 257, 258, 259, 260,
- 261, 262, 263, 264, 265, 266, 267, 268, 269, 270,
- 271, 272, 273, -1, 275, 276, 277, 278, 279, 264,
- 257, 258, 259, 260, 261, 262, 263, 264, 265, 266,
- 267, 268, 269, 270, 271, 272, 273, 264, 275, 276,
- 277, 278, 279, 264, 257, 258, 259, 260, 261, 262,
- 263, 264, 265, 266, 267, 268, 269, 270, 271, 272,
- 273, 125, 275, 276, 277, 278, 279, 264, 257, 258,
- 259, 260, 261, 262, 263, 264, 265, 266, 267, 268,
- 269, 270, 271, 272, 273, -1, 275, 276, 277, 278,
- 279, -1, 257, 258, 259, 260, 261, 262, 263, 264,
- 265, 266, 267, 268, 269, 270, 271, 272, 273, -1,
- 275, 276, 277, 278, 279, 10, 257, 258, 259, 260,
- 261, -1, 263, 264, 265, 266, 267, 268, 269, 270,
- 271, 272, 264, -1, 275, 276, 277, 278, 279, 10,
- 257, 36, -1, 38, -1, 40, 41, 264, 257, -1,
- -1, -1, -1, 270, 271, 10, -1, -1, -1, -1,
- 257, 270, 271, 10, 59, 36, -1, 38, -1, 40,
- 41, 2, -1, 270, 271, -1, -1, -1, -1, 10,
- 11, -1, 64, 38, -1, 10, 41, -1, 59, 36,
- -1, 38, -1, 40, 41, 77, 78, 79, -1, 30,
- 264, 96, -1, -1, 59, -1, -1, 10, -1, -1,
- -1, 36, 59, -1, -1, 40, 41, -1, -1, -1,
- -1, -1, -1, -1, 55, 96, -1, -1, 123, 10,
- 125, 62, 63, 36, -1, 117, -1, 40, -1, 70,
- -1, 123, -1, 74, -1, -1, 10, -1, -1, 96,
- 132, -1, 83, 135, 125, 36, 59, -1, -1, 40,
- 41, 10, -1, -1, -1, -1, -1, -1, -1, -1,
- 125, 96, -1, -1, 38, -1, 123, 41, 125, -1,
- -1, -1, -1, -1, -1, -1, -1, 36, 10, -1,
- -1, 40, -1, 96, -1, 59, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 10, -1, -1,
- -1, -1, -1, -1, -1, 96, 38, -1, -1, 41,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 10, -1, -1, -1, -1, 38, -1, 59, 41, -1,
- -1, -1, -1, -1, -1, -1, -1, 96, -1, -1,
- -1, -1, -1, -1, -1, -1, 59, -1, 38, -1,
- -1, 125, 257, 258, 259, -1, 261, 262, -1, 264,
- 265, 266, 267, 268, 123, 270, 271, 272, 273, 59,
- 275, 276, 277, 278, 279, -1, 257, 258, 259, 260,
- 261, -1, 263, 264, 265, 266, 267, 268, 269, 270,
- 271, 272, -1, 125, 275, 276, 277, 278, 279, 264,
- 257, 258, 259, -1, 261, 262, -1, 264, 265, 266,
- 267, 268, 125, 270, 271, 272, 273, -1, 275, 276,
- 277, 278, 279, 258, 259, 260, 261, -1, 263, -1,
- 265, 266, 267, 268, 269, 125, -1, 272, -1, -1,
- 275, 276, 277, 278, 279, 258, 259, 260, 261, -1,
- 263, -1, 265, 266, 267, 268, 269, -1, -1, 272,
- -1, 10, 275, 276, 277, 278, 279, 258, 259, 260,
- 261, -1, 263, 10, 265, 266, 267, 268, 269, -1,
- -1, 272, -1, 257, 275, 276, 277, 278, 279, 38,
- 264, -1, 41, 10, -1, -1, 270, 271, 10, 258,
- 259, 38, 261, 262, 41, -1, 265, 266, 267, 268,
- 59, -1, 10, 272, 273, -1, 275, 276, 277, 278,
- 279, 38, 59, -1, 41, 257, 38, -1, 10, 41,
- -1, -1, 264, -1, -1, -1, -1, 10, 270, 271,
- 38, -1, 59, 41, 257, -1, -1, 59, -1, -1,
- -1, 264, -1, -1, 10, -1, 38, 270, 271, 41,
- -1, 59, 10, -1, -1, 38, -1, 257, 41, -1,
- -1, -1, -1, -1, -1, -1, 125, 59, -1, -1,
- 270, 271, 38, -1, -1, 41, 59, -1, 125, -1,
- 38, -1, -1, 41, -1, -1, -1, -1, -1, -1,
- -1, 36, -1, 59, -1, 40, -1, -1, 125, -1,
- -1, 59, -1, 125, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 36, -1, -1, 125, 40, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 125, -1, -1, -1, -1, -1, 36,
- -1, -1, 125, 40, -1, -1, -1, -1, -1, -1,
- -1, 96, -1, -1, -1, -1, -1, -1, -1, 125,
- -1, -1, -1, -1, -1, 36, -1, 125, -1, 40,
- -1, -1, 94, -1, 96, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 36, -1, -1,
- -1, 40, 41, -1, -1, -1, -1, -1, 257, 96,
- -1, 123, -1, -1, -1, 264, -1, -1, -1, 36,
- 257, 270, 271, 40, 41, -1, -1, 264, -1, -1,
- -1, -1, -1, 270, 271, 96, 123, -1, -1, -1,
- 257, -1, 36, -1, -1, 257, 40, -1, -1, -1,
- -1, -1, 264, 270, 271, -1, -1, 96, 270, 257,
- -1, -1, 123, -1, -1, -1, 264, -1, -1, -1,
- -1, -1, 270, -1, -1, 257, 36, -1, -1, 96,
- 40, -1, 264, -1, 257, -1, -1, -1, 270, -1,
- -1, 264, -1, -1, -1, -1, -1, 270, -1, 36,
- -1, 257, 96, 40, -1, -1, -1, -1, 264, 257,
- -1, -1, -1, -1, 270, -1, 264, -1, -1, -1,
- -1, -1, 270, 258, 259, 260, 261, 262, 263, 123,
- 265, 266, 267, 268, 269, -1, 96, 272, 273, -1,
- 275, 276, 277, 278, 279, -1, 258, 259, 260, 261,
- -1, 263, -1, 265, 266, 267, 268, 269, -1, 96,
- 272, -1, -1, 275, 276, 277, 278, 279, -1, 256,
- -1, 258, 259, -1, 261, 262, -1, -1, 265, 266,
- 267, 268, -1, -1, -1, 272, 273, -1, 275, 276,
- 277, 278, 279, -1, -1, -1, -1, 258, 259, 260,
- 261, -1, 263, -1, 265, 266, 267, 268, 269, 36,
- -1, 272, -1, 40, 275, 276, 277, 278, 279, 258,
- 259, 260, 261, -1, 263, -1, 265, 266, 267, 268,
- 269, -1, -1, 272, -1, -1, 275, 276, 277, 278,
- 279, 258, 259, 260, 261, -1, 263, -1, 265, 266,
- 267, 268, 269, -1, -1, 272, -1, -1, 275, 276,
- 277, 278, 279, -1, 258, 259, 260, 261, 262, 96,
- -1, 265, 266, 267, 268, -1, -1, -1, 272, 273,
- -1, 275, 276, 277, 278, 279, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 123, -1, 258, 259,
- 260, 261, -1, 263, -1, 265, 266, 267, 268, 269,
- -1, -1, 272, -1, -1, 275, 276, 277, 278, 279,
- -1, 258, 259, 260, 261, -1, 263, -1, 265, 266,
- 267, 268, 269, -1, -1, 272, -1, -1, 275, 276,
- 277, 278, 279, -1, -1, -1, 0, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 0, -1,
- -1, -1, -1, -1, 18, -1, -1, -1, 22, -1,
- -1, 25, -1, -1, -1, 29, -1, -1, -1, -1,
- 22, -1, -1, 25, -1, -1, -1, 29, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 51, -1, -1,
- -1, -1, 56, -1, -1, -1, -1, 61, -1, 51,
- -1, -1, -1, -1, -1, 69, -1, -1, -1, 61,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 258, 259, -1, 261, 262, -1, -1, 265, 266,
- 267, 268, -1, 97, -1, 272, 273, 101, 275, 276,
- 277, 278, 279, -1, -1, 97, 110, 111, 112, 101,
- -1, -1, -1, -1, -1, -1, -1, -1, 110, 111,
- 112, -1, -1, -1, -1, -1, -1, 131, -1, -1,
- -1, -1, -1, 137, 138, 139, -1, -1, 142, 131,
- -1, 145, -1, -1, -1, 137, 138, 139, -1, -1,
- 142, -1, -1, 145,
-};
-#define YYFINAL 21
-#ifndef YYDEBUG
-#define YYDEBUG 0
-#endif
-#define YYMAXTOKEN 280
-#if YYDEBUG
-char *yyname[] = {
-"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,"'$'",0,"'&'",0,"'('","')'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"';'",0,
-"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'^'",0,
-"'`'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,"ANDAND","BACKBACK","BANG","CASE","COUNT","DUP","ELSE","END",
-"FLAT","FN","FOR","IF","IN","OROR","PIPE","REDIR","SREDIR","SUB","SUBSHELL",
-"SWITCH","TWIDDLE","WHILE","WORD","HUH",
-};
-const char * const yyrule[] = {
-"$accept : rc",
-"rc : line end",
-"rc : error end",
-"end : END",
-"end : '\\n'",
-"cmdsa : cmd ';'",
-"cmdsa : cmd '&'",
-"line : cmd",
-"line : cmdsa line",
-"body : cmd",
-"body : cmdsan body",
-"cmdsan : cmdsa",
-"cmdsan : cmd '\\n'",
-"brace : '{' body '}'",
-"paren : '(' body ')'",
-"assign : first '=' word",
-"epilog :",
-"epilog : redir epilog",
-"redir : DUP",
-"redir : REDIR word",
-"redir : SREDIR word",
-"case : CASE words ';'",
-"case : CASE words '\\n'",
-"cbody : cmd",
-"cbody : case cbody",
-"cbody : cmdsan cbody",
-"iftail : cmd",
-"iftail : brace ELSE optnl cmd",
-"cmd :",
-"cmd : simple",
-"cmd : brace epilog",
-"cmd : IF paren optnl iftail",
-"cmd : FOR '(' word IN words ')' optnl cmd",
-"cmd : FOR '(' word ')' optnl cmd",
-"cmd : WHILE paren optnl cmd",
-"cmd : SWITCH '(' word ')' optnl '{' cbody '}'",
-"cmd : TWIDDLE optcaret word words",
-"cmd : cmd ANDAND optnl cmd",
-"cmd : cmd OROR optnl cmd",
-"cmd : cmd PIPE optnl cmd",
-"cmd : redir cmd",
-"cmd : assign cmd",
-"cmd : BANG optcaret cmd",
-"cmd : SUBSHELL optcaret cmd",
-"cmd : FN words brace",
-"cmd : FN words",
-"optcaret :",
-"optcaret : '^'",
-"simple : first",
-"simple : simple word",
-"simple : simple redir",
-"first : comword",
-"first : first '^' sword",
-"sword : comword",
-"sword : keyword",
-"word : sword",
-"word : word '^' sword",
-"comword : '$' sword",
-"comword : '$' sword SUB words ')'",
-"comword : COUNT sword",
-"comword : FLAT sword",
-"comword : '`' sword",
-"comword : '`' brace",
-"comword : BACKBACK word brace",
-"comword : BACKBACK word sword",
-"comword : '(' nlwords ')'",
-"comword : REDIR brace",
-"comword : WORD",
-"keyword : FOR",
-"keyword : IN",
-"keyword : WHILE",
-"keyword : IF",
-"keyword : SWITCH",
-"keyword : FN",
-"keyword : ELSE",
-"keyword : CASE",
-"keyword : TWIDDLE",
-"keyword : BANG",
-"keyword : SUBSHELL",
-"words :",
-"words : words word",
-"nlwords :",
-"nlwords : nlwords '\\n'",
-"nlwords : nlwords word",
-"optnl :",
-"optnl : optnl '\\n'",
-};
-#endif
-#ifdef YYSTACKSIZE
-#undef YYMAXDEPTH
-#define YYMAXDEPTH YYSTACKSIZE
-#else
-#ifdef YYMAXDEPTH
-#define YYSTACKSIZE YYMAXDEPTH
-#else
-#define YYSTACKSIZE 500
-#define YYMAXDEPTH 500
-#endif
-#endif
-int yydebug;
-int yynerrs;
-int yyerrflag;
-int yychar;
-short *yyssp;
-YYSTYPE *yyvsp;
-YYSTYPE yyval;
-YYSTYPE yylval;
-short yyss[YYSTACKSIZE];
-YYSTYPE yyvs[YYSTACKSIZE];
-#define yystacksize YYSTACKSIZE
-#line 169 "parse.y"
-
-void initparse() {
- star = treecpy(mk(nVar,mk(nWord,"*",NULL)), ealloc);
- nolist = treecpy(mk(nVar,mk(nWord,"ifs",NULL)), ealloc);
-}
-
-#line 590 "y.tab.c"
-#define YYABORT goto yyabort
-#define YYREJECT goto yyabort
-#define YYACCEPT goto yyaccept
-#define YYERROR goto yyerrlab
-
-int
-yyparse()
-{
- register int yym, yyn, yystate;
-#if YYDEBUG
- register char *yys;
-
- if ((yys = getenv("YYDEBUG")))
- {
- yyn = *yys;
- if (yyn >= '0' && yyn <= '9')
- yydebug = yyn - '0';
- }
-#endif
-
- yynerrs = 0;
- yyerrflag = 0;
- yychar = (-1);
-
- yyssp = yyss;
- yyvsp = yyvs;
- *yyssp = yystate = 0;
-
-yyloop:
- if ((yyn = yydefred[yystate])) goto yyreduce;
- if (yychar < 0)
- {
- if ((yychar = yylex()) < 0) yychar = 0;
-#if YYDEBUG
- if (yydebug)
- {
- yys = 0;
- if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
- if (!yys) yys = "illegal-symbol";
- printf("%sdebug: state %d, reading %d (%s)\n",
- YYPREFIX, yystate, yychar, yys);
- }
-#endif
- }
- if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
- yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
- {
-#if YYDEBUG
- if (yydebug)
- printf("%sdebug: state %d, shifting to state %d\n",
- YYPREFIX, yystate, yytable[yyn]);
-#endif
- if (yyssp >= yyss + yystacksize - 1)
- {
- goto yyoverflow;
- }
- *++yyssp = yystate = yytable[yyn];
- *++yyvsp = yylval;
- yychar = (-1);
- if (yyerrflag > 0) --yyerrflag;
- goto yyloop;
- }
- if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
- yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
- {
- yyn = yytable[yyn];
- goto yyreduce;
- }
- if (yyerrflag) goto yyinrecovery;
-#if defined(lint) || defined(__GNUC__)
- goto yynewerror;
-#endif
-yynewerror:
- yyerror("syntax error");
-#if defined(lint) || defined(__GNUC__)
- goto yyerrlab;
-#endif
-yyerrlab:
- ++yynerrs;
-yyinrecovery:
- if (yyerrflag < 3)
- {
- yyerrflag = 3;
- for (;;)
- {
- if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
- yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
- {
-#if YYDEBUG
- if (yydebug)
- printf("%sdebug: state %d, error recovery shifting\
- to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
-#endif
- if (yyssp >= yyss + yystacksize - 1)
- {
- goto yyoverflow;
- }
- *++yyssp = yystate = yytable[yyn];
- *++yyvsp = yylval;
- goto yyloop;
- }
- else
- {
-#if YYDEBUG
- if (yydebug)
- printf("%sdebug: error recovery discarding state %d\n",
- YYPREFIX, *yyssp);
-#endif
- if (yyssp <= yyss) goto yyabort;
- --yyssp;
- --yyvsp;
- }
- }
- }
- else
- {
- if (yychar == 0) goto yyabort;
-#if YYDEBUG
- if (yydebug)
- {
- yys = 0;
- if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
- if (!yys) yys = "illegal-symbol";
- printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
- YYPREFIX, yystate, yychar, yys);
- }
-#endif
- yychar = (-1);
- goto yyloop;
- }
-yyreduce:
-#if YYDEBUG
- if (yydebug)
- printf("%sdebug: state %d, reducing by rule %d (%s)\n",
- YYPREFIX, yystate, yyn, yyrule[yyn]);
-#endif
- yym = yylen[yyn];
- yyval = yyvsp[1-yym];
- switch (yyn)
- {
-case 1:
-#line 49 "parse.y"
-{ parsetree = yyvsp[-1].node; YYACCEPT; }
-break;
-case 2:
-#line 50 "parse.y"
-{ yyerrok; parsetree = NULL; YYABORT; }
-break;
-case 3:
-#line 53 "parse.y"
-{ if (!heredoc(1)) YYABORT; }
-break;
-case 4:
-#line 54 "parse.y"
-{ if (!heredoc(0)) YYABORT; }
-break;
-case 6:
-#line 58 "parse.y"
-{ yyval.node = (yyvsp[-1].node != NULL ? mk(nNowait,yyvsp[-1].node) : yyvsp[-1].node); }
-break;
-case 8:
-#line 62 "parse.y"
-{ yyval.node = (yyvsp[-1].node != NULL ? mk(nBody,yyvsp[-1].node,yyvsp[0].node) : yyvsp[0].node); }
-break;
-case 10:
-#line 66 "parse.y"
-{ yyval.node = (yyvsp[-1].node == NULL ? yyvsp[0].node : yyvsp[0].node == NULL ? yyvsp[-1].node : mk(nBody,yyvsp[-1].node,yyvsp[0].node)); }
-break;
-case 12:
-#line 69 "parse.y"
-{ yyval.node = yyvsp[-1].node; if (!heredoc(0)) YYABORT; }
-break;
-case 13:
-#line 71 "parse.y"
-{ yyval.node = yyvsp[-1].node; }
-break;
-case 14:
-#line 73 "parse.y"
-{ yyval.node = yyvsp[-1].node; }
-break;
-case 15:
-#line 75 "parse.y"
-{ yyval.node = mk(nAssign,yyvsp[-2].node,yyvsp[0].node); }
-break;
-case 16:
-#line 77 "parse.y"
-{ yyval.node = NULL; }
-break;
-case 17:
-#line 78 "parse.y"
-{ yyval.node = mk(nEpilog,yyvsp[-1].node,yyvsp[0].node); }
-break;
-case 18:
-#line 81 "parse.y"
-{ yyval.node = mk(nDup,yyvsp[0].dup.type,yyvsp[0].dup.left,yyvsp[0].dup.right); }
-break;
-case 19:
-#line 82 "parse.y"
-{ yyval.node = mk(nRedir,yyvsp[-1].redir.type,yyvsp[-1].redir.fd,yyvsp[0].node);
- if (yyvsp[-1].redir.type == rHeredoc && !qdoc(yyvsp[0].node, yyval.node)) YYABORT; /* queue heredocs up */
- }
-break;
-case 20:
-#line 85 "parse.y"
-{ yyval.node = mk(nRedir,yyvsp[-1].redir.type,yyvsp[-1].redir.fd,yyvsp[0].node);
- if (yyvsp[-1].redir.type == rHeredoc && !qdoc(yyvsp[0].node, yyval.node)) YYABORT; /* queue heredocs up */
- }
-break;
-case 21:
-#line 89 "parse.y"
-{ yyval.node = mk(nCase, yyvsp[-1].node); }
-break;
-case 22:
-#line 90 "parse.y"
-{ yyval.node = mk(nCase, yyvsp[-1].node); }
-break;
-case 23:
-#line 92 "parse.y"
-{ yyval.node = mk(nCbody, yyvsp[0].node, NULL); }
-break;
-case 24:
-#line 93 "parse.y"
-{ yyval.node = mk(nCbody, yyvsp[-1].node, yyvsp[0].node); }
-break;
-case 25:
-#line 94 "parse.y"
-{ yyval.node = mk(nCbody, yyvsp[-1].node, yyvsp[0].node); }
-break;
-case 27:
-#line 97 "parse.y"
-{ yyval.node = mk(nElse,yyvsp[-3].node,yyvsp[0].node); }
-break;
-case 28:
-#line 99 "parse.y"
-{ yyval.node = NULL; }
-break;
-case 30:
-#line 101 "parse.y"
-{ yyval.node = mk(nBrace,yyvsp[-1].node,yyvsp[0].node); }
-break;
-case 31:
-#line 102 "parse.y"
-{ yyval.node = mk(nIf,yyvsp[-2].node,yyvsp[0].node); }
-break;
-case 32:
-#line 103 "parse.y"
-{ yyval.node = mk(nForin,yyvsp[-5].node,yyvsp[-3].node,yyvsp[0].node); }
-break;
-case 33:
-#line 104 "parse.y"
-{ yyval.node = mk(nForin,yyvsp[-3].node,star,yyvsp[0].node); }
-break;
-case 34:
-#line 105 "parse.y"
-{ yyval.node = mk(nWhile,yyvsp[-2].node,yyvsp[0].node); }
-break;
-case 35:
-#line 106 "parse.y"
-{ yyval.node = mk(nSwitch,yyvsp[-5].node,yyvsp[-1].node); }
-break;
-case 36:
-#line 107 "parse.y"
-{ yyval.node = mk(nMatch,yyvsp[-1].node,yyvsp[0].node); }
-break;
-case 37:
-#line 108 "parse.y"
-{ yyval.node = mk(nAndalso,yyvsp[-3].node,yyvsp[0].node); }
-break;
-case 38:
-#line 109 "parse.y"
-{ yyval.node = mk(nOrelse,yyvsp[-3].node,yyvsp[0].node); }
-break;
-case 39:
-#line 110 "parse.y"
-{ yyval.node = mk(nPipe,yyvsp[-2].pipe.left,yyvsp[-2].pipe.right,yyvsp[-3].node,yyvsp[0].node); }
-break;
-case 40:
-#line 111 "parse.y"
-{ yyval.node = (yyvsp[0].node != NULL ? mk(nPre,yyvsp[-1].node,yyvsp[0].node) : yyvsp[-1].node); }
-break;
-case 41:
-#line 112 "parse.y"
-{ yyval.node = (yyvsp[0].node != NULL ? mk(nPre,yyvsp[-1].node,yyvsp[0].node) : yyvsp[-1].node); }
-break;
-case 42:
-#line 113 "parse.y"
-{ yyval.node = mk(nBang,yyvsp[0].node); }
-break;
-case 43:
-#line 114 "parse.y"
-{ yyval.node = mk(nSubshell,yyvsp[0].node); }
-break;
-case 44:
-#line 115 "parse.y"
-{ yyval.node = mk(nNewfn,yyvsp[-1].node,yyvsp[0].node); }
-break;
-case 45:
-#line 116 "parse.y"
-{ yyval.node = mk(nRmfn,yyvsp[0].node); }
-break;
-case 49:
-#line 122 "parse.y"
-{ yyval.node = (yyvsp[0].node != NULL ? mk(nArgs,yyvsp[-1].node,yyvsp[0].node) : yyvsp[-1].node); }
-break;
-case 50:
-#line 123 "parse.y"
-{ yyval.node = mk(nArgs,yyvsp[-1].node,yyvsp[0].node); }
-break;
-case 52:
-#line 126 "parse.y"
-{ yyval.node = mk(nConcat,yyvsp[-2].node,yyvsp[0].node); }
-break;
-case 54:
-#line 129 "parse.y"
-{ yyval.node = mk(nWord,yyvsp[0].keyword, NULL); }
-break;
-case 56:
-#line 132 "parse.y"
-{ yyval.node = mk(nConcat,yyvsp[-2].node,yyvsp[0].node); }
-break;
-case 57:
-#line 134 "parse.y"
-{ yyval.node = mk(nVar,yyvsp[0].node); }
-break;
-case 58:
-#line 135 "parse.y"
-{ yyval.node = mk(nVarsub,yyvsp[-3].node,yyvsp[-1].node); }
-break;
-case 59:
-#line 136 "parse.y"
-{ yyval.node = mk(nCount,yyvsp[0].node); }
-break;
-case 60:
-#line 137 "parse.y"
-{ yyval.node = mk(nFlat, yyvsp[0].node); }
-break;
-case 61:
-#line 138 "parse.y"
-{ yyval.node = mk(nBackq,nolist,yyvsp[0].node); }
-break;
-case 62:
-#line 139 "parse.y"
-{ yyval.node = mk(nBackq,nolist,yyvsp[0].node); }
-break;
-case 63:
-#line 140 "parse.y"
-{ yyval.node = mk(nBackq,yyvsp[-1].node,yyvsp[0].node); }
-break;
-case 64:
-#line 141 "parse.y"
-{ yyval.node = mk(nBackq,yyvsp[-1].node,yyvsp[0].node); }
-break;
-case 65:
-#line 142 "parse.y"
-{ yyval.node = yyvsp[-1].node; }
-break;
-case 66:
-#line 143 "parse.y"
-{ yyval.node = mk(nNmpipe,yyvsp[-1].redir.type,yyvsp[-1].redir.fd,yyvsp[0].node); }
-break;
-case 67:
-#line 144 "parse.y"
-{ yyval.node = (yyvsp[0].word.w[0] == '\'') ? mk(nQword, yyvsp[0].word.w+1, NULL) : mk(nWord,yyvsp[0].word.w, yyvsp[0].word.m); }
-break;
-case 68:
-#line 146 "parse.y"
-{ yyval.keyword = "for"; }
-break;
-case 69:
-#line 147 "parse.y"
-{ yyval.keyword = "in"; }
-break;
-case 70:
-#line 148 "parse.y"
-{ yyval.keyword = "while"; }
-break;
-case 71:
-#line 149 "parse.y"
-{ yyval.keyword = "if"; }
-break;
-case 72:
-#line 150 "parse.y"
-{ yyval.keyword = "switch"; }
-break;
-case 73:
-#line 151 "parse.y"
-{ yyval.keyword = "fn"; }
-break;
-case 74:
-#line 152 "parse.y"
-{ yyval.keyword = "else"; }
-break;
-case 75:
-#line 153 "parse.y"
-{ yyval.keyword = "case"; }
-break;
-case 76:
-#line 154 "parse.y"
-{ yyval.keyword = "~"; }
-break;
-case 77:
-#line 155 "parse.y"
-{ yyval.keyword = "!"; }
-break;
-case 78:
-#line 156 "parse.y"
-{ yyval.keyword = "@"; }
-break;
-case 79:
-#line 158 "parse.y"
-{ yyval.node = NULL; }
-break;
-case 80:
-#line 159 "parse.y"
-{ yyval.node = (yyvsp[-1].node != NULL ? (yyvsp[0].node != NULL ? mk(nLappend,yyvsp[-1].node,yyvsp[0].node) : yyvsp[-1].node) : yyvsp[0].node); }
-break;
-case 81:
-#line 161 "parse.y"
-{ yyval.node = NULL; }
-break;
-case 83:
-#line 163 "parse.y"
-{ yyval.node = (yyvsp[-1].node != NULL ? (yyvsp[0].node != NULL ? mk(nLappend,yyvsp[-1].node,yyvsp[0].node) : yyvsp[-1].node) : yyvsp[0].node); }
-break;
-#line 1015 "y.tab.c"
- }
- yyssp -= yym;
- yystate = *yyssp;
- yyvsp -= yym;
- yym = yylhs[yyn];
- if (yystate == 0 && yym == 0)
- {
-#if YYDEBUG
- if (yydebug)
- printf("%sdebug: after reduction, shifting from state 0 to\
- state %d\n", YYPREFIX, YYFINAL);
-#endif
- yystate = YYFINAL;
- *++yyssp = YYFINAL;
- *++yyvsp = yyval;
- if (yychar < 0)
- {
- if ((yychar = yylex()) < 0) yychar = 0;
-#if YYDEBUG
- if (yydebug)
- {
- yys = 0;
- if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
- if (!yys) yys = "illegal-symbol";
- printf("%sdebug: state %d, reading %d (%s)\n",
- YYPREFIX, YYFINAL, yychar, yys);
- }
-#endif
- }
- if (yychar == 0) goto yyaccept;
- goto yyloop;
- }
- if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
- yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
- yystate = yytable[yyn];
- else
- yystate = yydgoto[yym];
-#if YYDEBUG
- if (yydebug)
- printf("%sdebug: after reduction, shifting from state %d \
-to state %d\n", YYPREFIX, *yyssp, yystate);
-#endif
- if (yyssp >= yyss + yystacksize - 1)
- {
- goto yyoverflow;
- }
- *++yyssp = yystate;
- *++yyvsp = yyval;
- goto yyloop;
-yyoverflow:
- yyerror("yacc stack overflow");
-yyabort:
- return (1);
-yyaccept:
- return (0);
-}
diff --git a/y.tab.h b/y.tab.h
@@ -1,33 +0,0 @@
-#define ANDAND 257
-#define BACKBACK 258
-#define BANG 259
-#define CASE 260
-#define COUNT 261
-#define DUP 262
-#define ELSE 263
-#define END 264
-#define FLAT 265
-#define FN 266
-#define FOR 267
-#define IF 268
-#define IN 269
-#define OROR 270
-#define PIPE 271
-#define REDIR 272
-#define SREDIR 273
-#define SUB 274
-#define SUBSHELL 275
-#define SWITCH 276
-#define TWIDDLE 277
-#define WHILE 278
-#define WORD 279
-#define HUH 280
-typedef union {
- struct Node *node;
- struct Redir redir;
- struct Pipe pipe;
- struct Dup dup;
- struct Word word;
- char *keyword;
-} YYSTYPE;
-extern YYSTYPE yylval;