From 53cf1b1c1c3f0c2b5067afccc2976b99a574a089 Mon Sep 17 00:00:00 2001 From: tim Date: Wed, 14 May 1997 15:30:41 +0000 Subject: Initial revision --- CHANGES | 278 ------ COPYRIGHT | 26 - EXAMPLES | 749 ---------------- Makefile.in | 80 -- README | 197 ----- addon.c | 22 - addon.h | 38 - builtins.c | 44 +- config.h.in | 44 - configure | 2541 ----------------------------------------------------- configure.in | 287 ------ cpp | 38 - except.c | 140 --- exec.c | 132 --- execve.c | 61 -- fn.c | 257 ------ footobar.c | 337 ------- getopt.c | 50 -- glob.c | 278 ------ glom.c | 433 --------- group.h | 9 - hash.c | 304 ------- heredoc.c | 156 ---- history/history.1 | 234 ----- history/history.c | 341 ------- input.c | 363 -------- install-sh | 250 ------ jbwrap.h | 9 - lex.c | 395 --------- list.c | 57 -- main.c | 121 --- match.c | 99 --- mksignal | 76 -- nalloc.c | 139 --- open.c | 25 - parse.y | 174 ---- print.c | 482 ---------- proto.h | 40 - rc.1 | 1881 --------------------------------------- rc.h | 406 --------- redir.c | 77 -- rlimit.h | 42 - signal.c | 80 -- status.c | 147 ---- tree.c | 172 ---- trip.rc | Bin 14684 -> 0 bytes utils.c | 116 --- var.c | 225 ----- version.c | 1 - wait.c | 129 --- walk.c | 358 -------- which.c | 121 --- y.tab.c | 1070 ---------------------- y.tab.h | 33 - 54 files changed, 25 insertions(+), 14139 deletions(-) delete mode 100644 CHANGES delete mode 100644 COPYRIGHT delete mode 100644 EXAMPLES delete mode 100644 Makefile.in delete mode 100644 README delete mode 100644 addon.c delete mode 100644 addon.h delete mode 100644 config.h.in delete mode 100755 configure delete mode 100644 configure.in delete mode 100644 cpp delete mode 100644 except.c delete mode 100644 exec.c delete mode 100644 execve.c delete mode 100644 fn.c delete mode 100644 footobar.c delete mode 100644 getopt.c delete mode 100644 glob.c delete mode 100644 glom.c delete mode 100644 group.h delete mode 100644 hash.c delete mode 100644 heredoc.c delete mode 100644 history/history.1 delete mode 100644 history/history.c delete mode 100644 input.c delete mode 100755 install-sh delete mode 100644 jbwrap.h delete mode 100644 lex.c delete mode 100644 list.c delete mode 100644 main.c delete mode 100644 match.c delete mode 100755 mksignal delete mode 100644 nalloc.c delete mode 100644 open.c delete mode 100644 parse.y delete mode 100644 print.c delete mode 100644 proto.h delete mode 100644 rc.1 delete mode 100644 rc.h delete mode 100644 redir.c delete mode 100644 rlimit.h delete mode 100644 signal.c delete mode 100644 status.c delete mode 100644 tree.c delete mode 100644 trip.rc delete mode 100644 utils.c delete mode 100644 var.c delete mode 100644 version.c delete mode 100644 wait.c delete mode 100644 walk.c delete mode 100644 which.c delete mode 100644 y.tab.c delete mode 100644 y.tab.h diff --git a/CHANGES b/CHANGES deleted file mode 100644 index 0543c11..0000000 --- a/CHANGES +++ /dev/null @@ -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 deleted file mode 100644 index 279f66c..0000000 --- a/COPYRIGHT +++ /dev/null @@ -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 deleted file mode 100644 index 90bd8df..0000000 --- a/EXAMPLES +++ /dev/null @@ -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 ) - -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 -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; 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 -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 deleted file mode 100644 index ed89d84..0000000 --- a/Makefile.in +++ /dev/null @@ -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 deleted file mode 100644 index 30e9f9a..0000000 --- a/README +++ /dev/null @@ -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 ( 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 - <<>> - (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, -( after 1997-07-27). diff --git a/addon.c b/addon.c deleted file mode 100644 index df3fcd7..0000000 --- a/addon.c +++ /dev/null @@ -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 -#include -#include - -#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 deleted file mode 100644 index 25f2312..0000000 --- a/addon.h +++ /dev/null @@ -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 index 1f9b56e..77f75df 100644 --- a/builtins.c +++ b/builtins.c @@ -7,16 +7,17 @@ because of a bad umask. */ -#include "rc.h" - #include #include #include - +#include "rc.h" #include "jbwrap.h" #include "sigmsgs.h" +#ifndef NOLIMITS +#include +#include +#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 deleted file mode 100644 index 3c8bde8..0000000 --- a/config.h.in +++ /dev/null @@ -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 deleted file mode 100755 index 9460c76..0000000 --- a/configure +++ /dev/null @@ -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 <&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 <&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 < -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 < -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 -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 <&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 < -#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 <&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 <&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 <&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 < -#include -#include -#include -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 -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 -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 < -#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 ""... $ac_c" 1>&6 -echo "configure:1201: checking for signal names in " >&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 ""... $ac_c" 1>&6 -echo "configure:1220: checking for signal names in " >&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 or " 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 -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 < -#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 -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 <&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 < -#if STDC_HEADERS -#include -#include -#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 < -#if STDC_HEADERS -#include -#include -#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 -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 < -/* 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 <&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 <&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 < -#include - -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 < -#define _KERNEL -#include -#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 < -#if RLIMIT_NEEDS_KERNEL -#define _KERNEL -#endif -#include - -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 < -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 < -#include -#include -#if RLIMIT_NEEDS_KERNEL -#define _KERNEL -#endif -#include -#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 < -#include -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 < conftest.$ac_ext < -#include - -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 <> 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 <&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 <&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 <&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 <&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 </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 < 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 <> $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 <> $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 <> $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 <> $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 deleted file mode 100644 index 86a97bb..0000000 --- a/configure.in +++ /dev/null @@ -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 , 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 , 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 or ) - ;; - 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 -#include - ], [ -int f; -f = RLIMIT_DATA; - ], rc_cv_kernel_rlimit=no, [ AC_TRY_COMPILE([ -#include -#define _KERNEL -#include -#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 -#if RLIMIT_NEEDS_KERNEL -#define _KERNEL -#endif -#include - ], 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 -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 -#include -#include -#if RLIMIT_NEEDS_KERNEL -#define _KERNEL -#endif -#include -#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 -#include - -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 deleted file mode 100644 index e3ac656..0000000 --- a/cpp +++ /dev/null @@ -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 deleted file mode 100644 index 241d887..0000000 --- a/except.c +++ /dev/null @@ -1,140 +0,0 @@ -#include -#include -#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 deleted file mode 100644 index 6a0082e..0000000 --- a/exec.c +++ /dev/null @@ -1,132 +0,0 @@ -/* exec.c */ -#include -#include -#include -#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, , . 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 deleted file mode 100644 index b21b30c..0000000 --- a/execve.c +++ /dev/null @@ -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 -#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 deleted file mode 100644 index 053ed89..0000000 --- a/fn.c +++ /dev/null @@ -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 -#include -#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 deleted file mode 100644 index 27955ba..0000000 --- a/footobar.c +++ /dev/null @@ -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 deleted file mode 100644 index 423b84a..0000000 --- a/getopt.c +++ /dev/null @@ -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 deleted file mode 100644 index 043f767..0000000 --- a/glob.c +++ /dev/null @@ -1,278 +0,0 @@ -/* glob.c: rc's (ugly) globber. This code is not elegant, but it works */ - -#include -#include -#include "rc.h" - -/* Lifted from autoconf documentation.*/ -#if HAVE_DIRENT_H -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# if HAVE_SYS_NDIR_H -# include -# endif -# if HAVE_SYS_DIR_H -# include -# endif -# if HAVE_NDIR_H -# include -# 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 deleted file mode 100644 index e835ed2..0000000 --- a/glom.c +++ /dev/null @@ -1,433 +0,0 @@ -/* glom.c: builds an argument list out of words, variables, etc. */ - -#include -#include -#include -#include -#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 deleted file mode 100644 index 8e78468..0000000 --- a/group.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Solaris / `gcc -ansi' only defines NGROUPS_MAX in if -_POSIX_C_SOURCE is defined. */ -#define _POSIX_C_SOURCE 1 -#include -#undef _POSIX_C_SOURCE - -#if defined(NGROUPS) && !defined(NGROUPS_MAX) -#define NGROUPS_MAX NGROUPS -#endif diff --git a/hash.c b/hash.c deleted file mode 100644 index 9f75b6c..0000000 --- a/hash.c +++ /dev/null @@ -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 deleted file mode 100644 index ba4fd3a..0000000 --- a/heredoc.c +++ /dev/null @@ -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 deleted file mode 100644 index 18ed28f..0000000 --- a/history/history.1 +++ /dev/null @@ -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 deleted file mode 100644 index e6aa29d..0000000 --- a/history/history.c +++ /dev/null @@ -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 -#include -#include - -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 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 deleted file mode 100644 index 3b60677..0000000 --- a/input.c +++ /dev/null @@ -1,363 +0,0 @@ -/* input.c: i/o routines for files and pseudo-files (strings) */ - -#include -#include -#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 deleted file mode 100755 index ebc6691..0000000 --- a/install-sh +++ /dev/null @@ -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 deleted file mode 100644 index 7d0358b..0000000 --- a/jbwrap.h +++ /dev/null @@ -1,9 +0,0 @@ -#include - -/* 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 deleted file mode 100644 index a763ce4..0000000 --- a/lex.c +++ /dev/null @@ -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 deleted file mode 100644 index fba6f6a..0000000 --- a/list.c +++ /dev/null @@ -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 deleted file mode 100644 index 68624d7..0000000 --- a/main.c +++ /dev/null @@ -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 deleted file mode 100644 index 6f87614..0000000 --- a/match.c +++ /dev/null @@ -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 deleted file mode 100755 index 9902ed8..0000000 --- a/mksignal +++ /dev/null @@ -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 ^ -awk ' - { sum = sum + 1; } - END { print "#define NUMOFSIGNALS", sum } -' diff --git a/nalloc.c b/nalloc.c deleted file mode 100644 index a809504..0000000 --- a/nalloc.c +++ /dev/null @@ -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 deleted file mode 100644 index 2b6ee75..0000000 --- a/open.c +++ /dev/null @@ -1,25 +0,0 @@ -/* open.c: to insulate from the rest of rc. */ - -#include -#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 deleted file mode 100644 index f1f5526..0000000 --- a/parse.y +++ /dev/null @@ -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 SREDIR -%type PIPE -%type DUP -%type WORD -%type keyword -%type 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 deleted file mode 100644 index e0dba12..0000000 --- a/print.c +++ /dev/null @@ -1,482 +0,0 @@ -/* print.c -- formatted printing routines (Paul Haahr, 12/91) */ - -#include "rc.h" -#include - -#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 deleted file mode 100644 index 4e0fb5a..0000000 --- a/proto.h +++ /dev/null @@ -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 -#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 -#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 deleted file mode 100644 index 140eb66..0000000 --- a/rc.1 +++ /dev/null @@ -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 deleted file mode 100644 index e540117..0000000 --- a/rc.h +++ /dev/null @@ -1,406 +0,0 @@ -#include "config.h" - -#if HAVE_SYS_TYPES_H -#include -#endif - -#if HAVE_UNISTD_H -#include -#endif - -#include "proto.h" - -/* datatypes */ - -/* braindamaged IBM header files #define true and false */ -#undef FALSE -#undef TRUE - -#include - -#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, /* % */ - FMT_f2set = 256 /* %. */ -}; - -/* 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 deleted file mode 100644 index b582341..0000000 --- a/redir.c +++ /dev/null @@ -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 deleted file mode 100644 index f6e179b..0000000 --- a/rlimit.h +++ /dev/null @@ -1,42 +0,0 @@ -/* What a mess. This file attempts to straighten everything out. */ - -#if HAVE_SETRLIMIT - -#if HAVE_SYS_RESOURCE_H -# include -# if RLIMIT_NEEDS_KERNEL -# define _KERNEL -# endif -# include -# if RLIMIT_NEEDS_KERNEL -# undef _KERNEL -# endif -#else -# include -#endif - -#if HAVE_LIMITS_H -# include -#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 deleted file mode 100644 index 1c3f812..0000000 --- a/signal.c +++ /dev/null @@ -1,80 +0,0 @@ -/* signal.c: a Hugh-approved signal handler. */ - -#include -#include -#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 deleted file mode 100644 index 428e414..0000000 --- a/status.c +++ /dev/null @@ -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 deleted file mode 100644 index aaea645..0000000 --- a/tree.c +++ /dev/null @@ -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 deleted file mode 100644 index 64d660f..0000000 Binary files a/trip.rc and /dev/null differ diff --git a/utils.c b/utils.c deleted file mode 100644 index 71ef61b..0000000 --- a/utils.c +++ /dev/null @@ -1,116 +0,0 @@ -/* utils.c: functions of general utility */ - -#include -#include -#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 deleted file mode 100644 index b0bc60b..0000000 --- a/var.c +++ /dev/null @@ -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 deleted file mode 100644 index 68b5dc1..0000000 --- a/version.c +++ /dev/null @@ -1 +0,0 @@ -const char id[] = "@(#)rc version 1.5b2, 1997-07-01."; diff --git a/wait.c b/wait.c deleted file mode 100644 index 171d97e..0000000 --- a/wait.c +++ /dev/null @@ -1,129 +0,0 @@ -#include "rc.h" - -#include -#include -#include - -#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 deleted file mode 100644 index ed9f965..0000000 --- a/walk.c +++ /dev/null @@ -1,358 +0,0 @@ -/* walk.c: walks the parse tree. */ - -#include -#include -#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 deleted file mode 100644 index 372cc92..0000000 --- a/which.c +++ /dev/null @@ -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 -#include -#include -#include - -#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 deleted file mode 100644 index 4538689..0000000 --- a/y.tab.c +++ /dev/null @@ -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 deleted file mode 100644 index 76f8b74..0000000 --- a/y.tab.h +++ /dev/null @@ -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; -- cgit v1.2.3