From: Michael D. Lowis Date: Mon, 13 Mar 2017 13:56:46 +0000 (-0400) Subject: Initial commit X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=3b3ab9cbd8483a22d1af91a97116c6c9a8b46c35;p=proto%2Frc.git Initial commit --- 3b3ab9cbd8483a22d1af91a97116c6c9a8b46c35 diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..d231e38 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,40 @@ +The current maintainer of rc is Toby Goodwin . Please +send all bug reports to him, or via github: + + https://github.com/rakitzis/rc/issues + +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 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 or HTTP 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. + +Toby would like to thank these people for their contributions since he +took over maintenance of rc. Aharon Robbins, Arvid Requate, Bengt +Kleberg, Brynjulv Hauksson, Byron Rakitzis, Callum Gibson, Chris +Siebenmann, Christian Neukirchen, Dale Scheetz, Dan Moniz, David Luyer, +David Swasey, Decklin Foster, Donn Cave, Erik Quanstrom, Gary Carvell, +Gerry Tomlinson, Gert-Jan Vons, Ian Lance Taylor, Jakub Wilk, Jeremy +Fitzhardinge, Marc Moorcroft, Mark H Wilkinson, Mark K Gardner, Raymond +Venneker, Rich $alz, Rob Savoye, Scott Schwartz, Stefan Dalibor, Steve +Simon, Thomas Nordin, Tom Culliton, Tom Tromey, Vincent Broman, Wolfgang +Zekoll. diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..8d93017 --- /dev/null +++ b/COPYING @@ -0,0 +1,22 @@ +/* rc -- the Plan 9 shell, reimplemented for Unix + + Copyright (c) 1991, 1999, 2001-2003, 2014, 2015 Byron Rakitzis + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Byron Rakitzis +*/ diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..5ba1cf3 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,905 @@ +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. + +Changes since rc-1.5b2 + + Configuration: rc now uses GNU automake. + + Portability: use sigsetjmp() when available. + + Portability: improve tests for quad_t. + + Configuration: don't leave FIFOs in /tmp when configuring. + + Configuration: let configure find `-ltermcap' when using readline. + + Configuration: pick up default path from config.cache. + + Bug: sense of most HAVE_RESTARTABLE_SYSCALLS tests was wrong. + + Bug: print prompts with `-i', even with editline / readline. + + Testing: just say `false' (not `/bin/false'). + + Bug: confusion over gid_t versus GETGROUPS_T in which.c. + + Feature: `-V' option added to report version number. + + Configuration: remove version.c; `id' is defined in main.c now. + + Bug: clear list of living children after fork(); `{ ls & wait } |cat' + no longer hangs or panics. + + Testing: add regression test for above. + + Tidiness: all the system call wrappers to prevent calls being + restarted now live in system-bsd.c. The configure script decides + whether to build system.c or system-bsd.c. Also, signal.c is more + careful to only declare slowbuf if it will be needed. + + Tidiness: similarly, configure decides whether to build execve.c or + not. + + Portability: test for ssize_t and use it where available; use long if + there's no ssize_t. + + Portability: use sigsetjmp where it's available and appropriate. If + no sigsetjmp, just use sigjmp; this probably fails in a traditional + SysV environment. + + Portability: test explicitly for SysV SIGCLD semantics. Main (and + dubious) benefit is that you can now define a function called `sigcld' + on systems where there is no signal called SIGCLD! + + Bug: rc has its own memory allocator; don't use malloc directly. + + Bug: the rc_wait() wrapper is only needed on systems which restart + system calls. On Linux, in particular, the wrapper leads to a race + which causes rc to hang (or panic in later versions). Other systems + apparently don't exercise this race. + + Bug: waitforall() must return if rc_wait4() returns with errno == + EINTR. Otherwise, the rc builtin `wait' cannot be interrupted if + there are background processes (although apparently only if there is a + handler for SIGINT). + + Portability: dreadful hack to track down the real locations of + signal.h to find signal names. rc now builds under CygWin32! + + Portability: replace above dreadful hack with mksignal.c, contributed + by Vincent Broman. + + Portability: use POSIX wait() macros (WIFEXITED and friends). + Unfortunately, POSIX omitted to supply WIFDUMPED, so this doesn't buy + a great deal. + + Distribution: remove the dependencies of y.tab.[ch] on parse.y from + Makefile.am. The justification for this is that, unless you're + hacking on rc's grammar, there's no reason to use anything other + than the distributed files (which were generated with byacc and very + lightly edited to silence a few gcc warnings). + + Enhancement: the example in addon.c wasn't very useful, since it + depended on files which weren't included with the distribution. There + is now a working, if trivial, example. + + Tidiness: the code was compiled with as many gcc warnings enabled as + I could find. Very few problems turned up. Some unused function + arguments were removed. Where unused arguments could not be removed + (because the function is one of a set that must all have the same + prototype), they were renamed to `ignore'. + + Portability: some versions of readline define the name `Function', + which rc also uses. Its use in rc has been renamed to `rc_Function'. + + Documentation: the `history' man page didn't explain what end of line + does in editing mode. It now does. + + Bug: the interaction with readline was broken, particularly with + respect to signal handling. I've incorporated some changes from Tom + Culliton which should sort this out. Unfortunately, we now have 3 + different code paths for readline 2.1, readline 2.2, and editline :-(. + + Configuration: if you say `--with-readline' or `--with-editline' it is + now an error if the appropriate library is not found. + + Bug: rc didn't work on RedHat 5 systems. This is because of + peculiarities in the handling of signals and system calls on this + system (the C library attempts to fake restartable system calls). + The fix involves testing at configure time for sigaction() and + SA_INTERRUPT: if both exist, we set up sys_signal() to be an "always + interrupt" wrapper around sigaction(). (If we don't have sigaction(), + we use signal() and check for restartable system calls as usual.) + + Portability: on AIX, lconv is defined by the system header files. + Rename lconv in print.c to avoid the clash. + + Testing: add a test that `cd' prints the new directory if we are + interactive and the directory was found via $cdpath. + +1998-07-23 + + Testing: fix silly typo in above test. + + Configuration: `--with-vrl' added to support Gert-Jan Vons's readline + library. + +1998-07-24 + + Portability: the autoconf macro AC_FUNC_SETPGRP doesn't work on OSF1: that + system supports arguments to setpgrp(), but also has a prototype in + to say that it is void. Fix this by defining our own + RC_FUNC_SETPGRP for now. + + Bug: was included twice in some source files. + + Configuration: automake wants `make distclean' to remove *.tab.c. + Rename y.tab.[ch] to parse.[ch] to avoid this. + +1998-07-27 + + Portability: on Ultrix, `make trip' fails with `malloc: Invalid + argument'. Problem is that getgroups(0, NULL) in which.c returns -1. + Add new configure test to check for POSIX getgroups() and fall back to + NGROUPS if it's not available. The magic is done by "getgroups.h". + + Tidiness: extract magic into "wait.h". + +1998-10-20 + + Tidiness: include prototype for add_history() when doing editline. + + Documentation: document the `-V' flag and mention Linux's + /proc/self/fd as alternative to /dev/fd. + +1998-10-21 + + Bug: shells need to be prepared for bogus applications to have set + their input file descriptor to non-blocking, and set it back. + + Tidiness: is in "proto.h", so nothing else needs to + include it explicitly. + + Documentation: document the ^A bug. + +1998-10-22 + + Tidiness: makenonblock() was a rather poor choice of name for + a function which makes a file descriptor *not* nonblocking :-). + +1998-10-26 + + Portability: apparently some systems declare `char *basename(const + char *)' in system header files. Changing our basename() (in + history.c) to match this prototype allows it to be compiled on such + systems, and is harmless. (Harmless, that is, if no system declares + `char *basename(char *)'.) + +1998-10-28 + + Bug: system-bsd.c needs to include "wait.h". + + Warnings: some versions of gcc warn about "ambiguous" `else' clauses. + + Portability: assigning va_list objects doesn't work everywhere (Linux + on the PowerPC, specifically). Use the C 9x invention va_copy() + instead, if it exists, otherwise fall back to assignment. + + Documentation: help HP-UX users by mentioning that you need `cc -Ae'. + Also, HP-UX make will build rc in a separate directory. + + Tidiness: remove unused functions from print.c. Anybody wanting to + use this library in another project should follow the pointer in the + documentation to an improved version. + +1998-10-29 + + Bug: the "null character ignored" warning was printed with the wrong + line number. Fix by adding an offset argument to pr_error. + + Portability: work around readline's broken treatment of a non-blocking + input file descriptor. + + Testing: add `testing' auxiliary program; use `testing' to generate + null character on the fly (since it's a nuisance having a literal + null character in trip.rc); reset sigexit in `fn fail'; add test for + nonblocking input file descriptor; fix test for cdpath. + + Portability: include before . + +1998-10-30 + + Portability: rename basename() to rc_basename(), since the former is + quite widespread, and has a variety of different definitions (none of + them, of course, static). + + Portability: work around i386 GCC 2.7.2.3 optimization bug triggered + by a (really quite simple) expression in history.c. + +1998-12-04 + + Bug: a debugging statement was left in history.c by mistake. + + Bug: `history' needs to check for `me' character preceded by `/', as + well as all the other options. An invocation like ../rc-1.5/- no + longer loops. + + Documentation: it seems better to have but a single URL in the README + file, which indirects to the other places of interest. + +1998-12-08 + + Portability: use AM_PROG_CC_STDC. This obviates the need for a + special hack on HP-UX. + + Documentation: document all the flags to `whatis'. + +1998-12-09 + + Tidiness: latest autoconf version has fixed AC_FUNC_SETPGRP, so we + no longer need to supply our own. + + Portability: test for va_copy() needs to include . + +1998-12-10 + + Tidiness: move most of the configure.in nastiness into acinclude.m4. + +1998-12-11 + + Tidiness: the release date now only needs to be changed in one place. + +1999-01-05 + + Documentation: the Bell Labs rc now has the list flattening operator, + but spelt $"foo. + +1999-01-11 + + Release: rc-1.5b4. + +1999-01-19 + + Documentation: document the `-s' option. Also, arrange the option + documentation in alphabetical order. + + Tidiness: just install `history' to `$(bindir)/-'; don't create an + extra link (which `make clean' failed to remove). + +1999-01-22 + + Bug: `-s' should not imply `-i'. + + Testing: add regression test for `-s' behaviour. + +1999-01-27 + + Documentation: default path was out of date; minor consistency + improvements. + + Release: rc-1.5b5. + +1999-02-15 + + Portability: AM_INIT_AUTOMAKE calls AC_ARG_PROGRAM and + AC_PROG_INSTALL. Don't do it explicitly. For once, the configure + script gets smaller! Program name transformations work right now. + + Documentation: note that rc has no `set' builtin; fix weird variable + name example; any character except `=' may be used in a variable name; + document bqstatus; document rc's exit status; other tidying. + +1999-03-01 + + Documentation: document the yacc-imposed limit on ; separated commands + in a line. + +1999-05-06 + + Portability: tgetent() might be in -lncurses instead of -ltermcap. + +1999-05-10 + + Portability: Linux *almost* has SysV SIGCLD semantics, and we need to + detect them. + + Bug: if we reset SIGCLD to SIG_DFL, we need to record the fact in the + sighandlers[] array. + +1999-05-12 + + Documentation: note that `$(a.b)' syntax only mostly works, and that + list definitions in exported functions are noisier than they need to + be. + + Release: rc-1.5b6. + +1999-05-19 + + Documentation: minor fixes to man page. + +1999-05-26 + + Tidiness: `make distclean' now removes sigmsgs.[ch]. + +1999-05-28 + + Release: rc-1.6. + +1999-08-19 + + Portability: the proposed C 9x __va_copy() macro is called that, not + va_copy(), as I thought. Furthermore, it is defined to be a macro, so + we don't need to use autoconf to check for it. + +1999-10-11 + + Bug: absolute globs don't need special case in doglob(). Avoids + creating path names like `//tmp', which is a UNC path under CygWin. + +1999-10-12 + + Portability: status.c assumes traditional Unix layout of 0 and 1 exit + statuses in the parent, which is not shared by BeOS. Add mkstatval.c. + +1999-10-13 + + Bug: a read(2) error in fdgchar() should call rc_raise(), not + rc_exit(). This bug is easily tickled on systems (like Linux) which + allow you to open(2) but not read(2) directories: `. /tmp'. In all + previous versions of rc, this caused the shell to exit. + + Portability: use POSIX strerror() where it's available; fake it with + sys_errlist[] where not. + + Feature: replace `-V' with `version' variable. + +1999-10-14 + + Portability: exporting `path' causes indigestion in CygWin. Since + it's virtually impossible for a child `rc' process to inherit `path' + (which I consider a bug, but it's not going to be fixed now), simply + don't export `path'. + + Portability: add /usr/bsd to default default path. + + Documentation: failing to search $path for a `.' command is at least + an incompatibility with Tenth Edition rc, and probably a bug. + +1999-11-10 + + Feature: make `version' a list. + +1999-11-11 + + Documentation: when running configure, you need to set LDFLAGS for + `-L' options, not LIBS. + + Release: rc-1.6b1. + +1999-12-10 + + Bug: absolute globs do still need a special case. `/*' works again now, but + we still avoid creating names like `//tmp/foo'. + + Bug: avoid a putative race condition in signal.c. + + Documentation: extra parentheses around `~' and `!' expressions are + forbidden. Tom Duff's paper is not distributed with rc, but is + available on the web. + + Release: rc-1.6b2. + +2000-04-19 + + Bug: isatty() tests in input.c are relevant to any fd, not just 0. + Now `. -i /dev/tty' works right. + + Bug: fn sigexit wasn't always cleared in child shells. + + Bug: `~ () '*'' dumped core. + +2000-05-25 + + Portability: need special runes for read() returning EIO under job + control systems. + +2000-06-20 + + Feature: add `-I' flag (definitively not interactive) for + compatibility with Plan 9 rc. + +2000-11-27 + + Portability: configure fails to detect strerror() on NetBSD; we need + to include . + +2001-06-18 + + Bug: you can't pass a short to a stdargs function! + +2001-09-27 + + Documentation: we don't consider that `.' failing to search path is + a bug. + + Feature: ^A in lists is now handled transparently. + +2001-10-01 + + Bug: it's no longer possible to use parentheses to sneak a word that + needs quoting past the "quoting detector", so `fn x { echo $(x.y) }' + now works both in the current rc and its descendants. + + Documentation: mention the catastrophic effects of a semantic error + in fn prompt. + +2001-10-03 + + Feature: exported lists no longer use redundant parentheses. + +2001-10-04 + + Bug: semantic errors in `fn prompt' no longer throw rc into a tailspin. + + Feature: don't export $cdpath or $home (the lower-case versions). + +2001-10-12 + + Release: rc-1.6b3. + +2001-10-25 + + Feature: large file support (thanks Scott Schwartz, Chris + Siebenmann). + +2001-10-29 + + Bug: space vs tab confusion in commented out Makefile rules to + rebuild parser (thanks Gary Carvell). + +2001-10-31 + + Documentation: subscripted variables don't work in here documents. + + Release: rc-1.6c4. + +2001-11-01 + + Bug: more wrongly ordered header file includes (thanks Callum + Gibson). + +2001-11-06 + + Portability: rename print.c::utoa() to rc_utoa() to avoid QNX name + clash; use "sh -c 'test ...'" in trip.rc for missing standalone + `test' on QNX (thanks Stefan Dalibor). + +2001-11-20 + + Documentation: tighten up various descriptions, and include some + more examples. + + Release: rc-1.6c5. + +2001-11-23 + + Bug: parselimit() was broken in various ways (thanks Chris + Siebenmann). + +2002-02-08 + + Bug: yet more wrongly ordered header file includes. + + Release: rc-1.6c6. + +2002-04-03 + + Feature: make $version less magical, and exportable if it's changed + from its default value. Same for $prompt (thank Erik Quanstrom). + + Bug: make $bqstatus and $status not exportable. + + Feature: "stuttering" colons for multiple replacements in the + history programs (thanks Callum Gibson). + +2002-05-22 + + Documentation: possible warning in tripping.c (thanks Dan Moniz). + + Release: rc-1.6c7. + +2002-06-18 + + Release: rc-1.7. + +2002-07-25 + + Bug: fix globbing of broken symlinks. + +2002-07-31 + + Bug: readline doesn't handle EIO either. + +2002-08-15 + + Bug: variables that are sometimes exported (i.e. $prompt and + $version) need to be made exportable if they are inherited from the + environment. + + Portability: don't call sigaction() for SIGKILL or SIGSTOP; don't + hand a garbage signal mask to sigaction() (thanks Jeremy + Fitzhardinge). Also, remove use of SA_INTERRUPT (SUSv3, BSD, + etc. have SA_RESTART with the inverted meaning). + +2002-08-20 + + Bug: don't call ealloc(0) on systems where getgroups() doesn't + return egid (thanks Chris Siebenmann). + +2002-11-27 + + Bug: history dumps core if more colons than substitutions (thanks + Callum Gibson); history fails to avoid itself if it's the only + command; history writes and reads outside allocated memory. + + Configuration: upgrade to autoconf-2.56 and automake-1.7.1. + +2003-07-17 + + Testing: remove test for large file support, as it causes + indigestion on file systems that don't support sparse files (thanks + Scott Schwartz). + +2003-07-22 + + Release: rc-1.7.1. + +2003-09-24 + + Tidiness: minor improvements to input.c. + +2014-02-26 + + Bug: fix for CVE-2014-1936 from Jakub Wilk. + +2014-06-29 + + Documentation: update email and web addresses. + +2014-08-31 + + Feature: support quoting for filename completion in GNU readline. + +2014-09-01 + + Bug: quoting of glob characters was broken (thanks Christian + Neukirchen); fix the "sneaky parens" bug properly (thanks Wolfgang + Zekoll). + + Feature: allow $"x as a synonym for $^x + + Release: rc-1.7.2. + +2015-04-03 + + Packaging: the rc.spec file was very out-of-date. + +2015-04-04 + + Portability: the comment from 1999-08-19 may well have been true at + the time, but the final version of the C99 standard called varargs + copying macro va_copy(). + +2015-04-07 + + Portability: look in -ltinfo for tgetent. + + Packaging: various autoconf / automake updates and tweaks. + +2015-04-14 + + Bug: in initinput(), the call ugchar(EOF) used the ungetcount member + of the top Input structure without initializing it. Thanks to Jeff + Johnson for finding this, Robert Scheck for reporting it, and Uli + Drepper for implementing MALLOC_PERTURB_, a cheap way to find uses of + uninitialized memory. + +2015-04-18 + + Licensing: tweaked to match exactly the "zlib with acknowledgement" + license which is used by nunit and is already approved by various + distros. + +2015-04-20 + + Release: rc-1.7.3. + +2015-05-12 + + Licensing: due to GPL compatibility concerns, the license is changed + again to the "zlib" license. (N.B. This license change was agreed and + approved by Byron Rakitzis, who is the copyright holder.) + + Testing: swap arguments to mktemp to be kinder to NetBSD (thanks Piotr + Meyer). + +2015-05-13 + + Release: rc-1.7.4. diff --git a/EXAMPLES b/EXAMPLES new file mode 100644 index 0000000..9f4b5c8 --- /dev/null +++ b/EXAMPLES @@ -0,0 +1,749 @@ +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 disk 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/INSTALL b/INSTALL new file mode 100644 index 0000000..007e939 --- /dev/null +++ b/INSTALL @@ -0,0 +1,370 @@ +Installation Instructions +************************* + +Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation, +Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf limitation. Until the limitation is lifted, you can use +this workaround: + + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..00c5dff --- /dev/null +++ b/Makefile.am @@ -0,0 +1,71 @@ +## Process this file with automake to produce Makefile.in + +EDIT=@EDIT@ + +if AMC_HISTORY +man_MANS = rc.1 history.1 +HISTORY = history +else +man_MANS = rc.1 +endif + +if AMC_NO_HASHBANG +EXECVE = execve.o +endif + +if AMC_RESTART +SYSTEM = system-bsd.o +else +SYSTEM = system.o +endif + +bin_PROGRAMS = rc +noinst_PROGRAMS = mksignal mkstatval tripping $(HISTORY) + +rc_SOURCES = builtins.c except.c exec.c fn.c footobar.c getopt.c glob.c glom.c hash.c heredoc.c input.c lex.c list.c main.c match.c nalloc.c open.c parse.c print.c redir.c signal.c status.c tree.c utils.c var.c wait.c walk.c which.c + +EXTRA_rc_SOURCES = addon.c edit-edit.c edit-editline.c edit-null.c edit-readline.c edit-vrl.c execve.c system.c system-bsd.c + +rc_DEPENDENCIES = sigmsgs.o $(ADDON) $(EDIT) $(EXECVE) $(SYSTEM) +rc_LDADD = sigmsgs.o $(ADDON) $(EDIT) $(EXECVE) $(SYSTEM) + +noinst_HEADERS = edit.h getgroups.h input.h jbwrap.h parse.h proto.h rc.h rlimit.h stat.h wait.h + +BUILT_SOURCES = sigmsgs.c + +EXTRA_DIST = EXAMPLES addon.c addon.h history.1 parse.y rc.1 trip.rc + +sigmsgs.c sigmsgs.h: mksignal + ./mksignal + +# Newer automake's buildtime dependency tracking can't seem to figure +# this one out. +status.o: statval.h + +statval.h: mkstatval + ./mkstatval > statval.h + +DISTCLEANFILES = sigmsgs.c sigmsgs.h statval.h + +# Of course, parse.c and parse.h depend on parse.y. However, unless +# you're hacking on rc's grammar, it's not useful to have this +# dependency expressed, since the distributed parse.[ch] (generated with +# byacc, and lightly edited to remove a couple of gcc warnings) are +# portable (I hope). +#parse.c parse.h: $(srcdir)/parse.y +# $(YACC) -d $(srcdir)/parse.y +# mv y.tab.c parse.c +# mv y.tab.h parse.h + +check: trip + +trip: rc tripping + ./rc -p < $(srcdir)/trip.rc + +install-exec-hook: +if AMC_HISTORY + $(INSTALL_PROGRAM) history $(bindir)/- ;\ + rm -f $(bindir)/--; $(LN) $(bindir)/- $(bindir)/-- ;\ + rm -f $(bindir)/-p; $(LN) $(bindir)/- $(bindir)/-p ;\ + rm -f $(bindir)/--p; $(LN) $(bindir)/- $(bindir)/--p +endif diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..8838aae --- /dev/null +++ b/Makefile.in @@ -0,0 +1,955 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +bin_PROGRAMS = rc$(EXEEXT) +noinst_PROGRAMS = mksignal$(EXEEXT) mkstatval$(EXEEXT) \ + tripping$(EXEEXT) $(am__EXEEXT_1) +subdir = . +DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \ + $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/config.h.in mkinstalldirs depcomp $(noinst_HEADERS) \ + COPYING compile install-sh missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" +@AMC_HISTORY_TRUE@am__EXEEXT_1 = history$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) +history_SOURCES = history.c +history_OBJECTS = history.$(OBJEXT) +history_LDADD = $(LDADD) +mksignal_SOURCES = mksignal.c +mksignal_OBJECTS = mksignal.$(OBJEXT) +mksignal_LDADD = $(LDADD) +mkstatval_SOURCES = mkstatval.c +mkstatval_OBJECTS = mkstatval.$(OBJEXT) +mkstatval_LDADD = $(LDADD) +am_rc_OBJECTS = builtins.$(OBJEXT) except.$(OBJEXT) exec.$(OBJEXT) \ + fn.$(OBJEXT) footobar.$(OBJEXT) getopt.$(OBJEXT) \ + glob.$(OBJEXT) glom.$(OBJEXT) hash.$(OBJEXT) heredoc.$(OBJEXT) \ + input.$(OBJEXT) lex.$(OBJEXT) list.$(OBJEXT) main.$(OBJEXT) \ + match.$(OBJEXT) nalloc.$(OBJEXT) open.$(OBJEXT) \ + parse.$(OBJEXT) print.$(OBJEXT) redir.$(OBJEXT) \ + signal.$(OBJEXT) status.$(OBJEXT) tree.$(OBJEXT) \ + utils.$(OBJEXT) var.$(OBJEXT) wait.$(OBJEXT) walk.$(OBJEXT) \ + which.$(OBJEXT) +rc_OBJECTS = $(am_rc_OBJECTS) +am__DEPENDENCIES_1 = +tripping_SOURCES = tripping.c +tripping_OBJECTS = tripping.$(OBJEXT) +tripping_LDADD = $(LDADD) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = history.c mksignal.c mkstatval.c $(rc_SOURCES) \ + $(EXTRA_rc_SOURCES) tripping.c +DIST_SOURCES = history.c mksignal.c mkstatval.c $(rc_SOURCES) \ + $(EXTRA_rc_SOURCES) tripping.c +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +AM_RECURSIVE_TARGETS = cscope +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +ADDON = @ADDON@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EDIT = @EDIT@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LN = @LN@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@AMC_HISTORY_FALSE@man_MANS = rc.1 +@AMC_HISTORY_TRUE@man_MANS = rc.1 history.1 +@AMC_HISTORY_TRUE@HISTORY = history +@AMC_NO_HASHBANG_TRUE@EXECVE = execve.o +@AMC_RESTART_FALSE@SYSTEM = system.o +@AMC_RESTART_TRUE@SYSTEM = system-bsd.o +rc_SOURCES = builtins.c except.c exec.c fn.c footobar.c getopt.c glob.c glom.c hash.c heredoc.c input.c lex.c list.c main.c match.c nalloc.c open.c parse.c print.c redir.c signal.c status.c tree.c utils.c var.c wait.c walk.c which.c +EXTRA_rc_SOURCES = addon.c edit-edit.c edit-editline.c edit-null.c edit-readline.c edit-vrl.c execve.c system.c system-bsd.c +rc_DEPENDENCIES = sigmsgs.o $(ADDON) $(EDIT) $(EXECVE) $(SYSTEM) +rc_LDADD = sigmsgs.o $(ADDON) $(EDIT) $(EXECVE) $(SYSTEM) +noinst_HEADERS = edit.h getgroups.h input.h jbwrap.h parse.h proto.h rc.h rlimit.h stat.h wait.h +BUILT_SOURCES = sigmsgs.c +EXTRA_DIST = EXAMPLES addon.c addon.h history.1 parse.y rc.1 trip.rc +DISTCLEANFILES = sigmsgs.c sigmsgs.h statval.h +all: $(BUILT_SOURCES) config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) + +history$(EXEEXT): $(history_OBJECTS) $(history_DEPENDENCIES) $(EXTRA_history_DEPENDENCIES) + @rm -f history$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(history_OBJECTS) $(history_LDADD) $(LIBS) + +mksignal$(EXEEXT): $(mksignal_OBJECTS) $(mksignal_DEPENDENCIES) $(EXTRA_mksignal_DEPENDENCIES) + @rm -f mksignal$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(mksignal_OBJECTS) $(mksignal_LDADD) $(LIBS) + +mkstatval$(EXEEXT): $(mkstatval_OBJECTS) $(mkstatval_DEPENDENCIES) $(EXTRA_mkstatval_DEPENDENCIES) + @rm -f mkstatval$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(mkstatval_OBJECTS) $(mkstatval_LDADD) $(LIBS) + +rc$(EXEEXT): $(rc_OBJECTS) $(rc_DEPENDENCIES) $(EXTRA_rc_DEPENDENCIES) + @rm -f rc$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(rc_OBJECTS) $(rc_LDADD) $(LIBS) + +tripping$(EXEEXT): $(tripping_OBJECTS) $(tripping_DEPENDENCIES) $(EXTRA_tripping_DEPENDENCIES) + @rm -f tripping$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tripping_OBJECTS) $(tripping_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addon.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builtins.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edit-edit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edit-editline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edit-null.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edit-readline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edit-vrl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/except.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/exec.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/execve.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/footobar.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glob.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glom.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heredoc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/history.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/input.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lex.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/match.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mksignal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkstatval.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nalloc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/open.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/redir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system-bsd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tree.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tripping.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/var.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wait.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/walk.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/which.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(PROGRAMS) $(MANS) $(HEADERS) config.h +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: all check install install-am install-exec-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \ + clean-binPROGRAMS clean-cscope clean-generic \ + clean-noinstPROGRAMS cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-compile \ + distclean-generic distclean-hdr distclean-tags distcleancheck \ + distdir distuninstallcheck dvi dvi-am html html-am info \ + info-am install install-am install-binPROGRAMS install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-exec-hook install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-man uninstall-man1 + + +sigmsgs.c sigmsgs.h: mksignal + ./mksignal + +# Newer automake's buildtime dependency tracking can't seem to figure +# this one out. +status.o: statval.h + +statval.h: mkstatval + ./mkstatval > statval.h + +# Of course, parse.c and parse.h depend on parse.y. However, unless +# you're hacking on rc's grammar, it's not useful to have this +# dependency expressed, since the distributed parse.[ch] (generated with +# byacc, and lightly edited to remove a couple of gcc warnings) are +# portable (I hope). +#parse.c parse.h: $(srcdir)/parse.y +# $(YACC) -d $(srcdir)/parse.y +# mv y.tab.c parse.c +# mv y.tab.h parse.h + +check: trip + +trip: rc tripping + ./rc -p < $(srcdir)/trip.rc + +install-exec-hook: +@AMC_HISTORY_TRUE@ $(INSTALL_PROGRAM) history $(bindir)/- ;\ +@AMC_HISTORY_TRUE@ rm -f $(bindir)/--; $(LN) $(bindir)/- $(bindir)/-- ;\ +@AMC_HISTORY_TRUE@ rm -f $(bindir)/-p; $(LN) $(bindir)/- $(bindir)/-p ;\ +@AMC_HISTORY_TRUE@ rm -f $(bindir)/--p; $(LN) $(bindir)/- $(bindir)/--p + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/MyMakefile b/MyMakefile new file mode 100644 index 0000000..68909c5 --- /dev/null +++ b/MyMakefile @@ -0,0 +1,23 @@ +CPPFLAGS = -DHAVE_CONFIG_H -I. +CCCMD = $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LDLIBS) +RCOBJS = builtins.o except.o builtins.o except.o exec.o 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 parse.o print.o redir.o signal.o status.o tree.o utils.o var.o wait.o walk.o which.o sigmsgs.o edit-null.o system.o + +all: rc + +# Generate signal messages +mksignal: mksignal.o +sigmsgs.c sigmsgs.h: mksignal + ./mksignal +builtins.o: sigmsgs.h + +# Generate mkstatval +mkstatval: mkstatval.o +statval.h: mkstatval + ./mkstatval > statval.h +status.o: statval.h + +rc: $(RCOBJS) + $(CCCMD) + +clean: + $(RM) rc *.o diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..3b55faf --- /dev/null +++ b/NEWS @@ -0,0 +1,24 @@ +Highlights of changes since rc-1.7. See ChangeLog for further details. + +Portability. A fix to the autoconfiguration means that the nasty +longjmp() code is now omitted for all modern Unix systems; previously rc +only did the Right Thing on Linux. The test for large files in trip.rc +was removed, as this causes indigestion on file systems that don't +support sparse files (the configuration and implementation of large file +support is still present of course). + +Bug fixes. Fix a use of uninitialized memory. Fix for CVE-2014-1936. +Broken symlinks now glob correctly. The variables $prompt and $version +are now exported if they are inherited from the environment when rc +starts. EIO handling is now enabled for readline too. A few bogosities +in the history program were fixed. A regression introduced by the fix +for the $(a.b) quoting bug was fixed, and that bug was correctly fixed. + +New features. Added $"x as a synonym for $^x. Minimal support for +various alternative line editing libraries. Filename completion with GNU +readline now quotes special characters. + +Documentation. Licence updated to the zlib licence. + +Toby Goodwin +2015-05-13 diff --git a/README b/README new file mode 100644 index 0000000..1431b04 --- /dev/null +++ b/README @@ -0,0 +1,38 @@ +This is release rc-1.7.4. + +See COPYING for copying information. All files are + + Copyright 1991, 1999, 2001-2003, 2014, 2015 Byron Rakitzis. + +See INSTALL for build and installation information. + + +BUGS + +Send bug reports to . 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 "INCOMPATIBILITIES" 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. + + +WWW + +More information on releases of rc can be found at this web page. + + http://tobold.org/article/rc diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..3f9ec93 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,210 @@ +dnl This macro sets HAVE_POSIX_GETGROUPS if the +dnl getgroups() function accepts a zero first argument. +AC_DEFUN([RC_FUNC_GETGROUPS], [ + AC_CACHE_CHECK(for POSIX getgroups, rc_cv_func_posix_getgroups, AC_TRY_RUN([ +#include +#include +int main(void) { + return getgroups(0, (void *)0) == -1; +} + ], rc_cv_func_posix_getgroups=yes, rc_cv_func_posix_getgroups=no, rc_cv_func_posix_getgroups=yes)) + case "$rc_cv_func_posix_getgroups" in + yes) AC_DEFINE(HAVE_POSIX_GETGROUPS, 1, [Define to 1 if you have the `getgroups' function with POSIX semantics.]) ;; + esac +]) + + +dnl We can't use AC_CHECK_FUNCS for sigsetjmp(), since it's a macro in +dnl some places. +AC_DEFUN([RC_FUNC_SIGSETJMP], [ + AC_CACHE_CHECK(for sigsetjmp, rc_cv_sigsetjmp, + AC_TRY_LINK([ +#include + ], [ +sigjmp_buf e; +sigsetjmp(e, 1); + ], rc_cv_sigsetjmp=yes, rc_cv_sigsetjmp=no)) + case "$rc_cv_sigsetjmp" in + yes) AC_DEFINE(HAVE_SIGSETJMP, 1, [Define to 1 if you have the `sigsetjmp' function or macro.]) ;; + esac +]) + +dnl Similarly, AC_CHECK_FUNCS doesn't find strerror() on NetBSD. +AC_DEFUN([RC_FUNC_STRERROR], [ + AC_CACHE_CHECK(for strerror, rc_cv_strerror, + AC_TRY_LINK([ +#include + ], [ +strerror(0); + ], rc_cv_strerror=yes, rc_cv_strerror=no)) + case "$rc_cv_strerror" in + yes) AC_DEFINE(HAVE_STRERROR, 1, [Define to 1 if you have the `strerror' function or macro.]) ;; + esac +]) + +dnl HPUX needs _KERNEL defined to pick up RLIMIT_foo defines. (Why?) +AC_DEFUN([RC_NEED_KERNEL], [ + 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 "$rc_cv_kernel_rlimit" in + yes) AC_DEFINE(RLIMIT_NEEDS_KERNEL, 1, [Define to 1 if `_KERNEL' must be defined for `RLIMIT_*' macros.]) ;; + esac +]) + +dnl Look for rlim_t in sys/types.h and sys/resource.h +AC_DEFUN([RC_TYPE_RLIM_T], [ + 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 "$rc_cv_have_rlim_t" in + yes) AC_DEFINE(HAVE_RLIM_T, 1, [Define to 1 if you have the `rlim_t' type.]) ;; + no) AC_CACHE_CHECK(for native quad_t, rc_cv_have_quad_t, + AC_TRY_COMPILE([ +#include + ], [ +typedef quad_t align_t; +align_t a; +a = (quad_t)0; + ], rc_cv_have_quad_t=yes, rc_cv_have_quad_t=no)) + + case "$rc_cv_have_quad_t" in + yes) AC_DEFINE(HAVE_QUAD_T, 1, [Define to 1 if you have the `quad_t' type.]) + 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 "$rc_cv_rlim_t_is_quad_t" in + yes) AC_DEFINE(RLIM_T_IS_QUAD_T, 1, [Define to 1 if `rlim_t' is `quad_t'.]) ;; + esac + ;; + esac + ;; + esac +]) + + +dnl Check type of sig_atomic_t. +AC_DEFUN([RC_TYPE_SIG_ATOMIC_T], [ + AC_CACHE_CHECK(for sig_atomic_t, rc_cv_sig_atomic_t, + AC_EGREP_HEADER(sig_atomic_t, signal.h, + rc_cv_sig_atomic_t=yes, rc_cv_sig_atomic_t=no)) + case "$rc_cv_sig_atomic_t" in + no) AC_DEFINE(sig_atomic_t, int, [Define to 1 if you have the `sig_atomic_t' type.]) ;; + esac +]) + + +dnl Do we have SysV SIGCLD semantics? In other words, if we set the +dnl action for SIGCLD to SIG_IGN does wait() always say ECHILD? Linux, +dnl of course, is bizarre here. It basically implements the SysV +dnl semantics, but if the parent calls wait() before the child calls +dnl exit(), wait() returns with the PID of the child as normal. (Real +dnl SysV waits for all children to exit, then returns with ECHILD.) +dnl Anyway, this is why the `sleep(1)' is there. +AC_DEFUN([RC_SYS_V_SIGCLD], [ + AC_CACHE_CHECK(for SysV SIGCLD semantics, rc_cv_sysv_sigcld, + AC_TRY_RUN([ +#include +#include +#include +#include +#include +int main(void) { + int i; + signal(SIGCLD, SIG_IGN); + switch (fork()) { + case -1: + return 1; + case 0: + return 0; + default: + sleep(1); + if (wait(&i) == -1 && errno == ECHILD) return 0; + else return 1; + } +} + ], rc_cv_sysv_sigcld=yes, rc_cv_sysv_sigcld=no, rc_cv_sysv_sigcld=yes)) + case "$rc_cv_sysv_sigcld" in + yes) AC_DEFINE(HAVE_SYSV_SIGCLD, 1, [Has SysV SIGCLD]) ;; + esac +]) + + +dnl Do we have /dev/fd or /proc/self/fd? +AC_DEFUN([RC_SYS_DEV_FD], [ + 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 + ) +]) + + +dnl Can mknod make FIFOs? +AC_DEFUN([RC_SYS_MKNOD_FIFO], [ + AC_CACHE_CHECK(for mknod FIFOs, rc_cv_sys_fifo, + AC_TRY_RUN([ +#include +#include + +main() { + exit(mknod("/tmp/rc$$.0", S_IFIFO | 0666, 0) != 0); +} + ], rc_cv_sys_fifo=yes, rc_cv_sys_fifo=no, rc_cv_sys_fifo=no)) + rm -f /tmp/rc$$.0 + case "$rc_cv_sys_fifo" in + yes) AC_DEFINE(HAVE_FIFO) ;; + esac +]) + +dnl Where is tgetent()? +AC_DEFUN([RC_LIB_TGETENT], [ + AC_CHECK_LIB(tinfo, tgetent, + rc_lib_tgetent=-ltinfo, + AC_CHECK_LIB(termcap, tgetent, + rc_lib_tgetent=-ltermcap, + AC_CHECK_LIB(ncurses, tgetent, + rc_lib_tgetent=-lncurses, + AC_MSG_ERROR(tgetent not found) + ) + ) + ) +]) diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..d2198f2 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1150 @@ +# generated automatically by aclocal 1.14.1 -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Copyright (C) 2002-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.14' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.14.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.14.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([acinclude.m4]) diff --git a/addon.c b/addon.c new file mode 100644 index 0000000..6e6c232 --- /dev/null +++ b/addon.c @@ -0,0 +1,25 @@ +/* + This file is NOT BUILT by default. Together with addon.h, it + provides an example of how to add new builtins to rc. +*/ + +#include "rc.h" +#include "addon.h" + +void b_sum(char **av) { + long sum = 0; + + while (*++av) + sum += atol(*av); + fprint(1, "%ld\n", sum); + set(TRUE); +} + +void b_prod(char **av) { + long sum = 1; + + while (*++av) + sum *= atol(*av); + fprint(1, "%ld\n", sum); + set(TRUE); +} diff --git a/addon.h b/addon.h new file mode 100644 index 0000000..4a69375 --- /dev/null +++ b/addon.h @@ -0,0 +1,31 @@ +/* + This file is NOT BUILT by default. Together with addon.c, it + provides an example of how to add new builtins to rc. + + To define a new builtin, it must appear in the macro ADDONS, which + is a comma-separated list of pairs of function pointers (the + implementation of the new builtin) and string literals (the name of + the new builtin). + + Any new builtin functions must also have proper prototypes in this + file. This is always of the same form. + + void b_NAME(char **av); + + The first argument, av[0], is the name of the builtin. The last + argument is followed by a NULL pointer. + + Builtins report their exit status using set(TRUE) or set(FALSE). + +*/ + +#if RC_ADDON + +#define ADDONS \ + { b_sum, "+" }, \ + { b_prod, "x" }, + +extern void b_sum(char **av); +extern void b_prod(char **av); + +#endif diff --git a/builtins.c b/builtins.c new file mode 100644 index 0000000..75ac9cf --- /dev/null +++ b/builtins.c @@ -0,0 +1,558 @@ +/* builtins.c: the collection of rc's builtin commands */ + +/* + NOTE: rc's builtins do not call "rc_error" because they are + commands, and rc errors usually arise from syntax errors. e.g., + you probably don't want interpretation of a shell script to stop + because of a bad umask. +*/ + +#include "rc.h" + +#include +#include +#include +#include + +#include "addon.h" +#include "input.h" +#include "jbwrap.h" +#include "rlimit.h" +#include "sigmsgs.h" + +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 +static void b_limit(char **); +#endif + +#if RC_ECHO +static void b_echo(char **); +#endif + +static struct { + builtin_t *p; + char *name; +} builtins[] = { + { b_break, "break" }, + { b_builtin, "builtin" }, + { b_cd, "cd" }, +#if RC_ECHO + { b_echo, "echo" }, +#endif + { b_eval, "eval" }, + { b_exec, "exec" }, + { b_exit, "exit" }, +#if HAVE_SETRLIMIT + { b_limit, "limit" }, +#endif + { b_newpgrp, "newpgrp" }, + { b_return, "return" }, + { b_shift, "shift" }, + { b_umask, "umask" }, + { b_wait, "wait" }, + { b_whatis, "whatis" }, + { b_dot, "." }, +#ifdef ADDONS + ADDONS +#endif +}; + +extern builtin_t *isbuiltin(char *s) { + int i; + for (i = 0; i < arraysize(builtins); i++) + if (streq(builtins[i].name, s)) + return builtins[i].p; + return NULL; +} + +/* funcall() is the wrapper used to invoke shell functions. pushes $*, and "return" returns here. */ + +extern void funcall(char **av) { + Jbwrap j; + Estack e1, e2; + Edata jreturn, star; + if (sigsetjmp(j.j, 1)) + return; + starassign(*av, av+1, TRUE); + jreturn.jb = &j; + star.name = "*"; + except(eReturn, jreturn, &e1); + except(eVarstack, star, &e2); + walk(treecpy(fnlookup(*av), nalloc), TRUE); + varrm("*", TRUE); + unexcept(); /* eVarstack */ + unexcept(); /* eReturn */ +} + +static void arg_count(char *name) { + fprint(2, RC "too many arguments to %s\n", name); + set(FALSE); +} + +static void badnum(char *num) { + fprint(2, RC "`%s' is a bad number\n", num); + set(FALSE); +} + +/* a dummy command. (exec() performs "exec" simply by not forking) */ + +extern void b_exec(char **ignore) { +} + +#if RC_ECHO +/* echo -n omits a newline. echo -- -n echos '-n' */ + +static void b_echo(char **av) { + char *format = "%A\n"; + if (*++av != NULL) { + if (streq(*av, "-n")) + format = "%A", av++; + else if (streq(*av, "--")) + av++; + } + fprint(1, format, av); + set(TRUE); +} +#endif + +/* cd. traverse $cdpath if the directory given is not an absolute pathname */ + +static void b_cd(char **av) { + List *s, nil; + char *path = NULL; + size_t t, pathlen = 0; + if (*++av == NULL) { + s = varlookup("home"); + *av = (s == NULL) ? "/" : s->w; + } else if (av[1] != NULL) { + arg_count("cd"); + return; + } + if (isabsolute(*av) || streq(*av, ".") || streq(*av, "..")) { /* absolute pathname? */ + if (chdir(*av) < 0) { + set(FALSE); + uerror(*av); + } else + set(TRUE); + } else { + s = varlookup("cdpath"); + if (s == NULL) { + s = &nil; + nil.w = ""; + nil.n = NULL; + } + do { + if (s != &nil && *s->w != '\0') { + t = strlen(*av) + strlen(s->w) + 2; + if (t > pathlen) + path = nalloc(pathlen = t); + strcpy(path, s->w); + if (!streq(s->w, "/")) /* "//" is special to POSIX */ + strcat(path, "/"); + strcat(path, *av); + } else { + pathlen = 0; + path = *av; + } + if (chdir(path) >= 0) { + set(TRUE); + if (interactive && *s->w != '\0' && !streq(s->w, ".")) + fprint(1, "%s\n", path); + return; + } + s = s->n; + } while (s != NULL); + fprint(2, "couldn't cd to %s\n", *av); + set(FALSE); + } +} + +static void b_umask(char **av) { + int i; + if (*++av == NULL) { + set(TRUE); + i = umask(0); + umask(i); + fprint(1, "0%o\n", i); + } else if (av[1] == NULL) { + i = o2u(*av); + if ((unsigned int) i > 0777) { + fprint(2, "bad umask\n"); + set(FALSE); + } else { + umask(i); + set(TRUE); + } + } else { + arg_count("umask"); + return; + } +} + +static void b_exit(char **av) { + if (*++av != NULL) + ssetstatus(av); + rc_exit(getstatus()); +} + +/* raise a "return" exception, i.e., return from a function. if an integer argument is present, set $status to it */ + +static void b_return(char **av) { + if (*++av != NULL) + ssetstatus(av); + rc_raise(eReturn); +} + +/* raise a "break" exception for breaking out of for and while loops */ + +static void b_break(char **av) { + if (av[1] != NULL) { + arg_count("break"); + return; + } + rc_raise(eBreak); +} + +/* shift $* n places (default 1) */ + +static void b_shift(char **av) { + int shift = (av[1] == NULL ? 1 : a2u(av[1])); + List *s, *dollarzero; + if (av[1] != NULL && av[2] != NULL) { + arg_count("shift"); + return; + } + if (shift < 0) { + badnum(av[1]); + return; + } + s = varlookup("*")->n; + dollarzero = varlookup("0"); + while (s != NULL && shift != 0) { + s = s->n; + --shift; + } + if (s == NULL && shift != 0) { + fprint(2, "cannot shift\n"); + set(FALSE); + } else { + varassign("*", append(dollarzero, s), FALSE); + set(TRUE); + } +} + +/* dud function */ + +extern void b_builtin(char **ignore) { +} + +/* wait for a given process, or all outstanding processes */ + +static void b_wait(char **av) { + int status; + pid_t pid; + if (av[1] == NULL) { + waitforall(); + return; + } + if (av[2] != NULL) { + arg_count("wait"); + return; + } + if ((pid = a2u(av[1])) < 0) { + badnum(av[1]); + return; + } + if (rc_wait4(pid, &status, FALSE) > 0) + setstatus(pid, status); + else + set(FALSE); + sigchk(); +} + +/* + whatis without arguments prints all variables and functions. Otherwise, check to see if a name + is defined as a variable, function or pathname. +*/ + +#define not(b) ((b)^TRUE) +#define show(b) (not(eff|vee|pee|bee|ess)|(b)) + +static bool issig(char *s) { + int i; + for (i = 0; i < NUMOFSIGNALS; i++) + if (streq(s, signals[i].name)) + return TRUE; + return FALSE; +} + +static void b_whatis(char **av) { + bool ess, eff, vee, pee, bee; + bool f, found; + int i, ac, c; + List *s; + Node *n; + char *e; + for (rc_optind = ac = 0; av[ac] != NULL; ac++) + ; /* count the arguments for getopt */ + ess = eff = vee = pee = bee = FALSE; + while ((c = rc_getopt(ac, av, "sfvpb")) != -1) + switch (c) { + default: set(FALSE); return; + case 's': ess = TRUE; break; + case 'f': eff = TRUE; break; + case 'v': vee = TRUE; break; + case 'p': pee = TRUE; break; + case 'b': bee = TRUE; break; + } + av += rc_optind; + if (*av == NULL) { + if (vee|eff) + whatare_all_vars(eff, vee); + if (ess) + whatare_all_signals(); + if (bee) + for (i = 0; i < arraysize(builtins); i++) + fprint(1, "builtin %s\n", builtins[i].name); + if (pee) + fprint(2, "whatis -p: must specify argument\n"); + if (show(FALSE)) /* no options? */ + whatare_all_vars(TRUE, TRUE); + set(TRUE); + return; + } + found = TRUE; + for (i = 0; av[i] != NULL; i++) { + f = FALSE; + errno = ENOENT; + if (show(vee) && (s = varlookup(av[i])) != NULL) { + f = TRUE; + prettyprint_var(1, av[i], s); + } + if (((show(ess)&&issig(av[i])) || show(eff)) && (n = fnlookup(av[i])) != NULL) { + f = TRUE; + prettyprint_fn(1, av[i], n); + } else if (show(bee) && isbuiltin(av[i]) != NULL) { + f = TRUE; + fprint(1, "builtin %s\n", av[i]); + } else if (show(pee) && (e = which(av[i], FALSE)) != NULL) { + f = TRUE; + fprint(1, "%S\n", e); + } + if (!f) { + found = FALSE; + if (errno != ENOENT) + uerror(av[i]); + else + fprint(2, "%s not found\n", av[i]); + } + } + set(found); +} + +/* push a string to be eval'ed onto the input stack. evaluate it */ + +static void b_eval(char **av) { + bool i = interactive; + if (av[1] == NULL) + return; + interactive = FALSE; + pushstring(av + 1, i); /* don't reset line numbers on noninteractive eval */ + doit(TRUE); + interactive = i; +} + +/* + push a file to be interpreted onto the input stack. with "-i" treat this as an interactive + input source. +*/ + +extern void b_dot(char **av) { + int fd; + bool old_i = interactive, i = FALSE; + Estack e; + Edata star; + av++; + if (*av == NULL) + return; + if (streq(*av, "-i")) { + av++; + i = TRUE; + } + if (dasheye) { /* rc -i file has to do the right thing. reset the dasheye state to FALSE, though. */ + dasheye = FALSE; + i = TRUE; + } + if (*av == NULL) + return; + fd = rc_open(*av, rFrom); + if (fd < 0) { + uerror(*av); + set(FALSE); + return; + } + starassign(*av, av+1, TRUE); + interactive = i; + pushfd(fd); + star.name = "*"; + except(eVarstack, star, &e); + doit(TRUE); + varrm("*", TRUE); + unexcept(); /* eVarstack */ + interactive = old_i; +} + +/* put rc into a new pgrp. Used on the NeXT where the Terminal program is broken (sigh) */ + +static void b_newpgrp(char **av) { + if (av[1] != NULL) { + arg_count("newpgrp"); + return; + } + setpgid(rc_pid, rc_pid); /* XXX check return value */ + tcsetpgrp(2, rc_pid); /* XXX check return value */ +} + +/* Berkeley limit support was cleaned up by Paul Haahr. */ + +#if HAVE_SETRLIMIT +static const struct Suffix + kbsuf = { NULL, 1024, "k" }, + mbsuf = { &kbsuf, 1024*1024, "m" }, + gbsuf = { &mbsuf, 1024*1024*1024, "g" }, + stsuf = { NULL, 1, "s" }, + mtsuf = { &stsuf, 60, "m" }, + htsuf = { &mtsuf, 60*60, "h" }; +#define SIZESUF &gbsuf +#define TIMESUF &htsuf +#define NOSUF ((struct Suffix *) NULL) /* for RLIMIT_NOFILE on SunOS 4.1 */ + +static const struct Limit limits[] = { + { "cputime", RLIMIT_CPU, TIMESUF }, + { "filesize", RLIMIT_FSIZE, SIZESUF }, + { "datasize", RLIMIT_DATA, SIZESUF }, + { "stacksize", RLIMIT_STACK, SIZESUF }, + { "coredumpsize", RLIMIT_CORE, SIZESUF }, +#ifdef RLIMIT_NOFILE /* SUSv2, but not universal */ + { "descriptors", RLIMIT_NOFILE, NOSUF }, +#endif +#ifdef RLIMIT_AS /* SUSv2, but not universal */ + { "memoryuse", RLIMIT_AS, SIZESUF }, +#endif +#if defined(RLIMIT_VMEM) && !defined(RLIMIT_AS) /* old name for AS */ + { "memoryuse", RLIMIT_VMEM, SIZESUF }, +#endif +#ifdef RLIMIT_RSS + { "memoryrss", RLIMIT_RSS, SIZESUF }, +#endif +#ifdef RLIMIT_NPROC + { "maxproc", RLIMIT_NPROC, NOSUF }, +#endif +#ifdef RLIMIT_MEMLOCK + { "memorylocked", RLIMIT_MEMLOCK, SIZESUF }, +#endif +#ifdef RLIMIT_LOCKS + { "filelocks", RLIMIT_LOCKS, NOSUF }, +#endif + { NULL, 0, NULL } +}; + +static void printlimit(const struct Limit *limit, bool hard) { + struct rlimit rlim; + rlim_t lim; + getrlimit(limit->flag, &rlim); + if (hard) + lim = rlim.rlim_max; + else + lim = rlim.rlim_cur; + if (lim == RLIM_INFINITY) + fprint(1, "%s \tunlimited\n", limit->name); + else { + const struct Suffix *suf; + for (suf = limit->suffix; suf != NULL; suf = suf->next) + if (lim % suf->amount == 0 && (lim != 0 || suf->amount > 1)) { + lim /= suf->amount; + break; + } + fprint(1, RLIM_FMT, limit->name, (RLIM_CONV)lim, (suf == NULL || lim == 0) ? "" : suf->name); + } +} + +static bool parselimit(const struct Limit *resource, rlim_t *limit, char *s) { + char *t; + int len = strlen(s); + const struct Suffix *suf = resource->suffix; + + *limit = 1; + if (streq(s, "unlimited")) { + *limit = RLIM_INFINITY; + return TRUE; + } + if (suf == TIMESUF && (t = strchr(s, ':')) != NULL) { + int min, sec; + *t++ = '\0'; + min = a2u(s); sec = a2u(t); + if (min == -1 || sec == -1) return FALSE; + *limit = 60 * min + sec; + } else { + int n; + for (; suf != NULL; suf = suf->next) + if (streq(suf->name, s + len - strlen(suf->name))) { + s[len - strlen(suf->name)] = '\0'; + *limit *= suf->amount; + break; + } + n = a2u(s); + if (n == -1) return FALSE; + *limit *= n; + } + return TRUE; +} + +static void b_limit(char **av) { + const struct Limit *lp = limits; + bool hard = FALSE; + if (*++av != NULL && streq(*av, "-h")) { + av++; + hard = TRUE; + } + if (*av == NULL) { + for (; lp->name != NULL; lp++) + printlimit(lp, hard); + return; + } + for (;; lp++) { + if (lp->name == NULL) { + fprint(2, "no such limit\n"); + set(FALSE); + return; + } + if (streq(*av, lp->name)) + break; + } + if (*++av == NULL) + printlimit(lp, hard); + else { + struct rlimit rlim; + rlim_t pl; + getrlimit(lp->flag, &rlim); + if (!parselimit(lp, &pl, *av)) { + fprint(2, "bad limit\n"); + set(FALSE); + return; + } + if (hard) + rlim.rlim_max = pl; + else + rlim.rlim_cur = pl; + if (setrlimit(lp->flag, &rlim) == -1) { + uerror("setrlimit"); + set(FALSE); + } else + set(TRUE); + } +} +#endif diff --git a/compile b/compile new file mode 100755 index 0000000..531136b --- /dev/null +++ b/compile @@ -0,0 +1,347 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-10-14.11; # UTC + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..b094a45 --- /dev/null +++ b/config.h.in @@ -0,0 +1,194 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* The default interpreter */ +#undef DEFAULTINTERP + +/* The default path */ +#undef DEFAULTPATH + +/* Define to the type of elements in the array set by `getgroups'. Usually + this is either `int' or `gid_t'. */ +#undef GETGROUPS_T + +/* Define to 1 if your kernel understands `#!' magic numbers */ +#undef HASH_BANG + +/* Define to 1 if you have /dev/fd. */ +#undef HAVE_DEV_FD + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the `mkfifo' function. */ +#undef HAVE_FIFO + +/* Define to 1 if you have the `getgroups' function. */ +#undef HAVE_GETGROUPS + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `lstat' function. */ +#undef HAVE_LSTAT + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mkfifo' function. */ +#undef HAVE_MKFIFO + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the `getgroups' function with POSIX semantics. */ +#undef HAVE_POSIX_GETGROUPS + +/* Define to 1 if you have /proc/self/fd. */ +#undef HAVE_PROC_SELF_FD + +/* Define to 1 if you have the `quad_t' type. */ +#undef HAVE_QUAD_T + +/* Define to 1 if system calls automatically restart after interruption by a + signal. */ +#undef HAVE_RESTARTABLE_SYSCALLS + +/* Define to 1 if you have the `rlim_t' type. */ +#undef HAVE_RLIM_T + +/* Define to 1 if you have the `setpgrp' function. */ +#undef HAVE_SETPGRP + +/* Define to 1 if you have the `setrlimit' function. */ +#undef HAVE_SETRLIMIT + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the `sigsetjmp' function or macro. */ +#undef HAVE_SIGSETJMP + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strerror' function or macro. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Has SysV SIGCLD */ +#undef HAVE_SYSV_SIGCLD + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 to encode exported environment names. */ +#undef PROTECT_ENV + +/* Define to 1 to use addon functions. */ +#undef RC_ADDON + +/* Define to 1 to include `echo' as a builtin. */ +#undef RC_ECHO + +/* Define to 1 to use job-control-style backgrounding. */ +#undef RC_JOB + +/* Release date */ +#undef RELDATE + +/* Define to 1 if `_KERNEL' must be defined for `RLIMIT_*' macros. */ +#undef RLIMIT_NEEDS_KERNEL + +/* Define to 1 if `rlim_t' is `quad_t'. */ +#undef RLIM_T_IS_QUAD_T + +/* Define to 1 if the `setpgrp' function takes no argument. */ +#undef SETPGRP_VOID + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to `int' if doesn't define. */ +#undef gid_t + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to 1 if you have the `sig_atomic_t' type. */ +#undef sig_atomic_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* Define to `long' if does not define. */ +#undef ssize_t + +/* Define to `int' if doesn't define. */ +#undef uid_t diff --git a/configure b/configure new file mode 100755 index 0000000..9211d95 --- /dev/null +++ b/configure @@ -0,0 +1,8025 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for rc 1.7.4. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='rc' +PACKAGE_TARNAME='rc' +PACKAGE_VERSION='1.7.4' +PACKAGE_STRING='rc 1.7.4' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +ac_unique_file="rc.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +EDIT +ADDON +AMC_ADDON_FALSE +AMC_ADDON_TRUE +AMC_HISTORY_FALSE +AMC_HISTORY_TRUE +AMC_NO_HASHBANG_FALSE +AMC_NO_HASHBANG_TRUE +AMC_RESTART_FALSE +AMC_RESTART_TRUE +EGREP +GREP +LN +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_dependency_tracking +enable_largefile +enable_builtin_echo +enable_job +enable_protect_env +enable_def_interp +enable_def_path +with_history +with_addon +with_edit +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +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=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -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_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$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 ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$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 | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$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 ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + 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 | -n) + 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 ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$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_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=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 ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# 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 the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + 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 + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # 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 <<_ACEOF +\`configure' configures rc 1.7.4 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/rc] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --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 +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of rc 1.7.4:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --disable-largefile omit support for large files + --disable-builtin-echo Don't include `echo' as a builtin + --disable-job Don't do job-control-style backgrounding + --disable-protect-env Don't protect environment names + --enable-def-interp=/bin/foo + Use /bin/foo as default interpreter [/bin/sh] + --enable-def-path=\"/usr/local/bin/\",\"/usr/bin\" + Default path [All of these that exist + (/usr/local/bin /usr/bin /usr/bsd /usr/ucb /bin .)] + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-history Build history subprograms + --with-addon[=foo.c] Extra builtins, from addon.c by default + --with-edit=(edit,editline,readline,vrl) Command line editing library + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +rc configure 1.7.4 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* 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_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by rc $as_me 1.7.4, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +RELDATE=`date -I` + +cat >>confdefs.h <<_ACEOF +#define RELDATE "$RELDATE" +_ACEOF + + + +am__api_version='1.14' + +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 + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# 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 +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +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. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&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_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='rc' + VERSION='1.7.4' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +ac_config_headers="$ac_config_headers config.h" + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_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 $# != 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 + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +case "$GCC" in +yes) CFLAGS="-Wall $CFLAGS" ;; +esac + + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if ${ac_cv_sys_largefile_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if ${ac_cv_sys_file_offset_bits+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if ${ac_cv_sys_large_files+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi + + +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LN"; then + ac_cv_prog_LN="$LN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LN=$ac_cv_prog_LN +if test -n "$LN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LN" >&5 +$as_echo "$LN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$LN" && break +done + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + 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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + 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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#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)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/resource.h sys/time.h sys/types.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 +$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } +if eval \${$as_ac_Header+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_ac_Header=yes" +else + eval "$as_ac_Header=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$as_ac_Header + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + 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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + 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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#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)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 +$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } +if ${ac_cv_header_sys_wait_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +int +main () +{ + int s; + wait (&s); + s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_sys_wait_h=yes +else + ac_cv_header_sys_wait_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 +$as_echo "$ac_cv_header_sys_wait_h" >&6; } +if test $ac_cv_header_sys_wait_h = yes; then + +$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 +$as_echo_n "checking for uid_t in sys/types.h... " >&6; } +if ${ac_cv_type_uid_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "uid_t" >/dev/null 2>&1; then : + ac_cv_type_uid_t=yes +else + ac_cv_type_uid_t=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 +$as_echo "$ac_cv_type_uid_t" >&6; } +if test $ac_cv_type_uid_t = no; then + +$as_echo "#define uid_t int" >>confdefs.h + + +$as_echo "#define gid_t int" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking type of array argument to getgroups" >&5 +$as_echo_n "checking type of array argument to getgroups... " >&6; } +if ${ac_cv_type_getgroups+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_type_getgroups=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Thanks to Mike Rendell for this test. */ +$ac_includes_default +#define NGID 256 +#undef MAX +#define MAX(x, y) ((x) > (y) ? (x) : (y)) + +int +main () +{ + gid_t gidset[NGID]; + int i, n; + union { gid_t gval; long int 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 int but getgroups modifies an array + of ints. */ + return n > 0 && gidset[n] != val.gval; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_type_getgroups=gid_t +else + ac_cv_type_getgroups=int +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +if test $ac_cv_type_getgroups = cross; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "getgroups.*int.*gid_t" >/dev/null 2>&1; then : + ac_cv_type_getgroups=gid_t +else + ac_cv_type_getgroups=int +fi +rm -f conftest* + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_getgroups" >&5 +$as_echo "$ac_cv_type_getgroups" >&6; } + +cat >>confdefs.h <<_ACEOF +#define GETGROUPS_T $ac_cv_type_getgroups +_ACEOF + + +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 +$as_echo_n "checking for uid_t in sys/types.h... " >&6; } +if ${ac_cv_type_uid_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "uid_t" >/dev/null 2>&1; then : + ac_cv_type_uid_t=yes +else + ac_cv_type_uid_t=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 +$as_echo "$ac_cv_type_uid_t" >&6; } +if test $ac_cv_type_uid_t = no; then + +$as_echo "#define uid_t int" >>confdefs.h + + +$as_echo "#define gid_t int" >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" +if test "x$ac_cv_type_ssize_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define ssize_t long +_ACEOF + +fi + + +for ac_func in getgroups lstat setpgrp setrlimit sigaction +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +case "$ac_cv_func_sigaction" in +no) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for restartable system calls" >&5 +$as_echo_n "checking for restartable system calls... " >&6; } +if ${ac_cv_sys_restartable_syscalls+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run test program while cross compiling +See \`config.log' for more details" "$LINENO" 5; } +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Exit 0 (true) if wait returns something other than -1, + i.e. the pid of the child, which means that wait was restarted + after getting the signal. */ + +$ac_includes_default +#include +#ifdef HAVE_SYS_WAIT_H +# include +#endif + +/* Some platforms explicitly require an extern "C" signal handler + when using C++. */ +#ifdef __cplusplus +extern "C" void ucatch (int dummy) { } +#else +void ucatch (dummy) int dummy; { } +#endif + +int +main () +{ + int i = fork (), status; + + if (i == 0) + { + sleep (3); + kill (getppid (), SIGINT); + sleep (3); + return 0; + } + + signal (SIGINT, ucatch); + + status = wait (&i); + if (status == -1) + wait (&i); + + return status == -1; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_sys_restartable_syscalls=yes +else + ac_cv_sys_restartable_syscalls=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_restartable_syscalls" >&5 +$as_echo "$ac_cv_sys_restartable_syscalls" >&6; } +if test $ac_cv_sys_restartable_syscalls = yes; then + +$as_echo "#define HAVE_RESTARTABLE_SYSCALLS 1" >>confdefs.h + +fi + ;; +esac + if test "$ac_cv_sys_restartable_syscalls" = yes; then + AMC_RESTART_TRUE= + AMC_RESTART_FALSE='#' +else + AMC_RESTART_TRUE='#' + AMC_RESTART_FALSE= +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for POSIX getgroups" >&5 +$as_echo_n "checking for POSIX getgroups... " >&6; } +if ${rc_cv_func_posix_getgroups+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + rc_cv_func_posix_getgroups=yes +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int main(void) { + return getgroups(0, (void *)0) == -1; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + rc_cv_func_posix_getgroups=yes +else + rc_cv_func_posix_getgroups=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rc_cv_func_posix_getgroups" >&5 +$as_echo "$rc_cv_func_posix_getgroups" >&6; } + case "$rc_cv_func_posix_getgroups" in + yes) +$as_echo "#define HAVE_POSIX_GETGROUPS 1" >>confdefs.h + ;; + esac + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sigsetjmp" >&5 +$as_echo_n "checking for sigsetjmp... " >&6; } +if ${rc_cv_sigsetjmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + +sigjmp_buf e; +sigsetjmp(e, 1); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + rc_cv_sigsetjmp=yes +else + rc_cv_sigsetjmp=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rc_cv_sigsetjmp" >&5 +$as_echo "$rc_cv_sigsetjmp" >&6; } + case "$rc_cv_sigsetjmp" in + yes) +$as_echo "#define HAVE_SIGSETJMP 1" >>confdefs.h + ;; + esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether setpgrp takes no argument" >&5 +$as_echo_n "checking whether setpgrp takes no argument... " >&6; } +if ${ac_cv_func_setpgrp_void+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + as_fn_error $? "cannot check setpgrp when cross compiling" "$LINENO" 5 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +/* If this system has a BSD-style setpgrp which takes arguments, + setpgrp(1, 1) will fail with ESRCH and return -1, in that case + exit successfully. */ + return setpgrp (1,1) != -1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_setpgrp_void=no +else + ac_cv_func_setpgrp_void=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setpgrp_void" >&5 +$as_echo "$ac_cv_func_setpgrp_void" >&6; } +if test $ac_cv_func_setpgrp_void = yes; then + +$as_echo "#define SETPGRP_VOID 1" >>confdefs.h + +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strerror" >&5 +$as_echo_n "checking for strerror... " >&6; } +if ${rc_cv_strerror+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + +strerror(0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + rc_cv_strerror=yes +else + rc_cv_strerror=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rc_cv_strerror" >&5 +$as_echo "$rc_cv_strerror" >&6; } + case "$rc_cv_strerror" in + yes) +$as_echo "#define HAVE_STRERROR 1" >>confdefs.h + ;; + esac + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if _KERNEL is required for RLIMIT defines" >&5 +$as_echo_n "checking if _KERNEL is required for RLIMIT defines... " >&6; } +if ${rc_cv_kernel_rlimit+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +int +main () +{ + +int f; +f = RLIMIT_DATA; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + rc_cv_kernel_rlimit=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#define _KERNEL +#include +#undef _KERNEL + +int +main () +{ + +int f; +f = RLIMIT_DATA; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + rc_cv_kernel_rlimit=yes +else + rc_cv_kernel_rlimit=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rc_cv_kernel_rlimit" >&5 +$as_echo "$rc_cv_kernel_rlimit" >&6; } + case "$rc_cv_kernel_rlimit" in + yes) +$as_echo "#define RLIMIT_NEEDS_KERNEL 1" >>confdefs.h + ;; + esac + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rlim_t" >&5 +$as_echo_n "checking for rlim_t... " >&6; } +if ${rc_cv_have_rlim_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#if RLIMIT_NEEDS_KERNEL +#define _KERNEL +#endif +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "rlim_t" >/dev/null 2>&1; then : + rc_cv_have_rlim_t=yes +else + rc_cv_have_rlim_t=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rc_cv_have_rlim_t" >&5 +$as_echo "$rc_cv_have_rlim_t" >&6; } + + case "$rc_cv_have_rlim_t" in + yes) +$as_echo "#define HAVE_RLIM_T 1" >>confdefs.h + ;; + no) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for native quad_t" >&5 +$as_echo_n "checking for native quad_t... " >&6; } +if ${rc_cv_have_quad_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + +typedef quad_t align_t; +align_t a; +a = (quad_t)0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + rc_cv_have_quad_t=yes +else + rc_cv_have_quad_t=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rc_cv_have_quad_t" >&5 +$as_echo "$rc_cv_have_quad_t" >&6; } + + case "$rc_cv_have_quad_t" in + yes) +$as_echo "#define HAVE_QUAD_T 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if rlimit values are quad_t" >&5 +$as_echo_n "checking if rlimit values are quad_t... " >&6; } +if ${rc_cv_rlim_t_is_quad_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + $ac_cv_type_quad_t +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#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)); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + rc_cv_rlim_t_is_quad_t=yes +else + rc_cv_rlim_t_is_quad_t=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rc_cv_rlim_t_is_quad_t" >&5 +$as_echo "$rc_cv_rlim_t_is_quad_t" >&6; } + + case "$rc_cv_rlim_t_is_quad_t" in + yes) +$as_echo "#define RLIM_T_IS_QUAD_T 1" >>confdefs.h + ;; + esac + ;; + esac + ;; + esac + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sig_atomic_t" >&5 +$as_echo_n "checking for sig_atomic_t... " >&6; } +if ${rc_cv_sig_atomic_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "sig_atomic_t" >/dev/null 2>&1; then : + rc_cv_sig_atomic_t=yes +else + rc_cv_sig_atomic_t=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rc_cv_sig_atomic_t" >&5 +$as_echo "$rc_cv_sig_atomic_t" >&6; } + case "$rc_cv_sig_atomic_t" in + no) +$as_echo "#define sig_atomic_t int" >>confdefs.h + ;; + esac + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SysV SIGCLD semantics" >&5 +$as_echo_n "checking for SysV SIGCLD semantics... " >&6; } +if ${rc_cv_sysv_sigcld+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + rc_cv_sysv_sigcld=yes +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include +#include +int main(void) { + int i; + signal(SIGCLD, SIG_IGN); + switch (fork()) { + case -1: + return 1; + case 0: + return 0; + default: + sleep(1); + if (wait(&i) == -1 && errno == ECHILD) return 0; + else return 1; + } +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + rc_cv_sysv_sigcld=yes +else + rc_cv_sysv_sigcld=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rc_cv_sysv_sigcld" >&5 +$as_echo "$rc_cv_sysv_sigcld" >&6; } + case "$rc_cv_sysv_sigcld" in + yes) +$as_echo "#define HAVE_SYSV_SIGCLD 1" >>confdefs.h + ;; + esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether #! works in shell scripts" >&5 +$as_echo_n "checking whether #! works in shell scripts... " >&6; } +if ${ac_cv_sys_interpreter+:} false; then : + $as_echo_n "(cached) " >&6 +else + echo '#! /bin/cat +exit 69 +' >conftest +chmod u+x conftest +(SHELL=/bin/sh; export SHELL; ./conftest >/dev/null 2>&1) +if test $? -ne 69; then + ac_cv_sys_interpreter=yes +else + ac_cv_sys_interpreter=no +fi +rm -f conftest +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_interpreter" >&5 +$as_echo "$ac_cv_sys_interpreter" >&6; } +interpval=$ac_cv_sys_interpreter + +case "$ac_cv_sys_interpreter" in +yes) +$as_echo "#define HASH_BANG 1" >>confdefs.h + ;; +esac + if test "$ac_cv_sys_interpreter" = no; then + AMC_NO_HASHBANG_TRUE= + AMC_NO_HASHBANG_FALSE='#' +else + AMC_NO_HASHBANG_TRUE='#' + AMC_NO_HASHBANG_FALSE= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/fd" >&5 +$as_echo_n "checking for /dev/fd... " >&6; } +if ${rc_cv_sys_dev_fd+:} false; then : + $as_echo_n "(cached) " >&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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rc_cv_sys_dev_fd" >&5 +$as_echo "$rc_cv_sys_dev_fd" >&6; } + +case "$rc_cv_sys_dev_fd" in +yes) +$as_echo "#define HAVE_DEV_FD 1" >>confdefs.h + ;; +odd) +$as_echo "#define HAVE_PROC_SELF_FD 1" >>confdefs.h + ;; +no) for ac_func in mkfifo +do : + ac_fn_c_check_func "$LINENO" "mkfifo" "ac_cv_func_mkfifo" +if test "x$ac_cv_func_mkfifo" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MKFIFO 1 +_ACEOF + +fi +done + ;; +esac + +case "$ac_cv_func_mkfifo" in +yes) +$as_echo "#define HAVE_FIFO 1" >>confdefs.h + ;; +no) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mknod FIFOs" >&5 +$as_echo_n "checking for mknod FIFOs... " >&6; } +if ${rc_cv_sys_fifo+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + rc_cv_sys_fifo=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include + +main() { + exit(mknod("/tmp/rc$$.0", S_IFIFO | 0666, 0) != 0); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + rc_cv_sys_fifo=yes +else + rc_cv_sys_fifo=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rc_cv_sys_fifo" >&5 +$as_echo "$rc_cv_sys_fifo" >&6; } + rm -f /tmp/rc$$.0 + case "$rc_cv_sys_fifo" in + yes) $as_echo "#define HAVE_FIFO 1" >>confdefs.h + ;; + esac + ;; +esac + +# Check whether --enable-builtin-echo was given. +if test "${enable_builtin_echo+set}" = set; then : + enableval=$enable_builtin_echo; test "x$enableval" != "xno" && +$as_echo "#define RC_ECHO 1" >>confdefs.h + +else + $as_echo "#define RC_ECHO 1" >>confdefs.h + +fi + + +# Check whether --enable-job was given. +if test "${enable_job+set}" = set; then : + enableval=$enable_job; test "x$enableval" != "xno" && +$as_echo "#define RC_JOB 1" >>confdefs.h + +else + $as_echo "#define RC_JOB 1" >>confdefs.h + +fi + + +# Check whether --enable-protect-env was given. +if test "${enable_protect_env+set}" = set; then : + enableval=$enable_protect_env; test "x$enableval" != "xno" && +$as_echo "#define PROTECT_ENV 1" >>confdefs.h + +else + $as_echo "#define PROTECT_ENV 1" >>confdefs.h + +fi + + +# Check whether --enable-def-interp was given. +if test "${enable_def_interp+set}" = set; then : + enableval=$enable_def_interp; + case "$enableval" in + no) + ;; + yes) + +$as_echo "#define DEFAULTINTERP \"/bin/sh\"" >>confdefs.h + + ;; + *) + cat >>confdefs.h <<_ACEOF +#define DEFAULTINTERP "$enableval" +_ACEOF + + esac + +else + $as_echo "#define DEFAULTINTERP \"/bin/sh\"" >>confdefs.h + +fi + + +# Check whether --enable-def-path was given. +if test "${enable_def_path+set}" = set; then : + enableval=$enable_def_path; + case "$enableval" in + no|yes) ;; + *) +cat >>confdefs.h <<_ACEOF +#define DEFAULTPATH $enableval +_ACEOF + ;; + esac + +else + enable_def_path=yes +fi + + +case "$enable_def_path" in +yes) { $as_echo "$as_me:${as_lineno-$LINENO}: checking extant directories for default path" >&5 +$as_echo_n "checking extant directories for default path... " >&6; } +if ${rc_cv_def_path+:} false; then : + $as_echo_n "(cached) " >&6 +else + + rc_cv_def_path='' + for i in /usr/local/bin /usr/bin /usr/bsd /usr/ucb /bin .; do + if test -d $i; then + case "$rc_cv_def_path" in + '') rc_cv_def_path=\"$i\" ;; + *) rc_cv_def_path=$rc_cv_def_path,\"$i\" ;; + esac + fi + done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $rc_cv_def_path" >&5 +$as_echo "$rc_cv_def_path" >&6; } + cat >>confdefs.h <<_ACEOF +#define DEFAULTPATH $rc_cv_def_path +_ACEOF + + ;; +esac + + +# Check whether --with-history was given. +if test "${with_history+set}" = set; then : + withval=$with_history; + case "$withval" in + yes) rc_history=yes ;; + *) rc_history=no ;; + esac + +else + rc_history=no +fi + + if test "$rc_history" = yes; then + AMC_HISTORY_TRUE= + AMC_HISTORY_FALSE='#' +else + AMC_HISTORY_TRUE='#' + AMC_HISTORY_FALSE= +fi + + + + +# Check whether --with-addon was given. +if test "${with_addon+set}" = set; then : + withval=$with_addon; + case "$withval" in + yes) ADDON=addon.o ;; + no) ADDON='' ;; + *) ADDON=`echo $withval |sed 's/\.c$/\.o/'` ;; + esac + +fi + + if test "$ADDON" != ""; then + AMC_ADDON_TRUE= + AMC_ADDON_FALSE='#' +else + AMC_ADDON_TRUE='#' + AMC_ADDON_FALSE= +fi + +case "$ADDON" in +?*) +$as_echo "#define RC_ADDON 1" >>confdefs.h + ;; +esac + + + +EDIT=edit-null.o + +# Check whether --with-edit was given. +if test "${with_edit+set}" = set; then : + withval=$with_edit; + case $withval in + yes) + as_fn_error $? "must specify which library" "$LINENO" 5 + # might consider searching + ;; + no|null) + ;; + edit|bsd) + EDIT=edit-edit.o + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltinfo" >&5 +$as_echo_n "checking for tgetent in -ltinfo... " >&6; } +if ${ac_cv_lib_tinfo_tgetent+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltinfo $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_tinfo_tgetent=yes +else + ac_cv_lib_tinfo_tgetent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tinfo_tgetent" >&5 +$as_echo "$ac_cv_lib_tinfo_tgetent" >&6; } +if test "x$ac_cv_lib_tinfo_tgetent" = xyes; then : + rc_lib_tgetent=-ltinfo +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltermcap" >&5 +$as_echo_n "checking for tgetent in -ltermcap... " >&6; } +if ${ac_cv_lib_termcap_tgetent+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltermcap $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_termcap_tgetent=yes +else + ac_cv_lib_termcap_tgetent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_termcap_tgetent" >&5 +$as_echo "$ac_cv_lib_termcap_tgetent" >&6; } +if test "x$ac_cv_lib_termcap_tgetent" = xyes; then : + rc_lib_tgetent=-ltermcap +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncurses" >&5 +$as_echo_n "checking for tgetent in -lncurses... " >&6; } +if ${ac_cv_lib_ncurses_tgetent+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ncurses_tgetent=yes +else + ac_cv_lib_ncurses_tgetent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tgetent" >&5 +$as_echo "$ac_cv_lib_ncurses_tgetent" >&6; } +if test "x$ac_cv_lib_ncurses_tgetent" = xyes; then : + rc_lib_tgetent=-lncurses +else + as_fn_error $? "tgetent not found" "$LINENO" 5 + +fi + + +fi + + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for el_init in -ledit" >&5 +$as_echo_n "checking for el_init in -ledit... " >&6; } +if ${ac_cv_lib_edit_el_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ledit $rc_lib_tgetent $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char el_init (); +int +main () +{ +return el_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_edit_el_init=yes +else + ac_cv_lib_edit_el_init=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_el_init" >&5 +$as_echo "$ac_cv_lib_edit_el_init" >&6; } +if test "x$ac_cv_lib_edit_el_init" = xyes; then : + + LIBS="$LIBS -ledit $rc_lib_tgetent" + +else + as_fn_error $? "edit library not found" "$LINENO" 5 +fi + + ;; + editline) + EDIT=edit-editline.o + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltinfo" >&5 +$as_echo_n "checking for tgetent in -ltinfo... " >&6; } +if ${ac_cv_lib_tinfo_tgetent+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltinfo $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_tinfo_tgetent=yes +else + ac_cv_lib_tinfo_tgetent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tinfo_tgetent" >&5 +$as_echo "$ac_cv_lib_tinfo_tgetent" >&6; } +if test "x$ac_cv_lib_tinfo_tgetent" = xyes; then : + rc_lib_tgetent=-ltinfo +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltermcap" >&5 +$as_echo_n "checking for tgetent in -ltermcap... " >&6; } +if ${ac_cv_lib_termcap_tgetent+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltermcap $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_termcap_tgetent=yes +else + ac_cv_lib_termcap_tgetent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_termcap_tgetent" >&5 +$as_echo "$ac_cv_lib_termcap_tgetent" >&6; } +if test "x$ac_cv_lib_termcap_tgetent" = xyes; then : + rc_lib_tgetent=-ltermcap +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncurses" >&5 +$as_echo_n "checking for tgetent in -lncurses... " >&6; } +if ${ac_cv_lib_ncurses_tgetent+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ncurses_tgetent=yes +else + ac_cv_lib_ncurses_tgetent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tgetent" >&5 +$as_echo "$ac_cv_lib_ncurses_tgetent" >&6; } +if test "x$ac_cv_lib_ncurses_tgetent" = xyes; then : + rc_lib_tgetent=-lncurses +else + as_fn_error $? "tgetent not found" "$LINENO" 5 + +fi + + +fi + + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for el_ring_bell in -leditline" >&5 +$as_echo_n "checking for el_ring_bell in -leditline... " >&6; } +if ${ac_cv_lib_editline_el_ring_bell+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-leditline $rc_lib_tgetent $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char el_ring_bell (); +int +main () +{ +return el_ring_bell (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_editline_el_ring_bell=yes +else + ac_cv_lib_editline_el_ring_bell=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_editline_el_ring_bell" >&5 +$as_echo "$ac_cv_lib_editline_el_ring_bell" >&6; } +if test "x$ac_cv_lib_editline_el_ring_bell" = xyes; then : + + LIBS="$LIBS -leditline $rc_lib_tgetent" + +else + as_fn_error $? "editline library not found" "$LINENO" 5 +fi + + ;; + readline|gnu) + EDIT=edit-readline.o + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltinfo" >&5 +$as_echo_n "checking for tgetent in -ltinfo... " >&6; } +if ${ac_cv_lib_tinfo_tgetent+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltinfo $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_tinfo_tgetent=yes +else + ac_cv_lib_tinfo_tgetent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tinfo_tgetent" >&5 +$as_echo "$ac_cv_lib_tinfo_tgetent" >&6; } +if test "x$ac_cv_lib_tinfo_tgetent" = xyes; then : + rc_lib_tgetent=-ltinfo +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltermcap" >&5 +$as_echo_n "checking for tgetent in -ltermcap... " >&6; } +if ${ac_cv_lib_termcap_tgetent+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltermcap $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_termcap_tgetent=yes +else + ac_cv_lib_termcap_tgetent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_termcap_tgetent" >&5 +$as_echo "$ac_cv_lib_termcap_tgetent" >&6; } +if test "x$ac_cv_lib_termcap_tgetent" = xyes; then : + rc_lib_tgetent=-ltermcap +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncurses" >&5 +$as_echo_n "checking for tgetent in -lncurses... " >&6; } +if ${ac_cv_lib_ncurses_tgetent+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ncurses_tgetent=yes +else + ac_cv_lib_ncurses_tgetent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tgetent" >&5 +$as_echo "$ac_cv_lib_ncurses_tgetent" >&6; } +if test "x$ac_cv_lib_ncurses_tgetent" = xyes; then : + rc_lib_tgetent=-lncurses +else + as_fn_error $? "tgetent not found" "$LINENO" 5 + +fi + + +fi + + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +$as_echo_n "checking for readline in -lreadline... " >&6; } +if ${ac_cv_lib_readline_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline $rc_lib_tgetent $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_readline_readline=yes +else + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +$as_echo "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes; then : + + LIBS="$LIBS -lreadline $rc_lib_tgetent" + +else + as_fn_error $? "readline library not found" "$LINENO" 5 +fi + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + +int +main () +{ + + rl_catch_signals = 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +else + as_fn_error $? "readline >= 4.0 not found" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ;; + vrl) + EDIT=edit-vrl.o + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltinfo" >&5 +$as_echo_n "checking for tgetent in -ltinfo... " >&6; } +if ${ac_cv_lib_tinfo_tgetent+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltinfo $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_tinfo_tgetent=yes +else + ac_cv_lib_tinfo_tgetent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tinfo_tgetent" >&5 +$as_echo "$ac_cv_lib_tinfo_tgetent" >&6; } +if test "x$ac_cv_lib_tinfo_tgetent" = xyes; then : + rc_lib_tgetent=-ltinfo +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltermcap" >&5 +$as_echo_n "checking for tgetent in -ltermcap... " >&6; } +if ${ac_cv_lib_termcap_tgetent+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltermcap $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_termcap_tgetent=yes +else + ac_cv_lib_termcap_tgetent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_termcap_tgetent" >&5 +$as_echo "$ac_cv_lib_termcap_tgetent" >&6; } +if test "x$ac_cv_lib_termcap_tgetent" = xyes; then : + rc_lib_tgetent=-ltermcap +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncurses" >&5 +$as_echo_n "checking for tgetent in -lncurses... " >&6; } +if ${ac_cv_lib_ncurses_tgetent+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tgetent (); +int +main () +{ +return tgetent (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ncurses_tgetent=yes +else + ac_cv_lib_ncurses_tgetent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tgetent" >&5 +$as_echo "$ac_cv_lib_ncurses_tgetent" >&6; } +if test "x$ac_cv_lib_ncurses_tgetent" = xyes; then : + rc_lib_tgetent=-lncurses +else + as_fn_error $? "tgetent not found" "$LINENO" 5 + +fi + + +fi + + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iline_peekch in -lvrl" >&5 +$as_echo_n "checking for iline_peekch in -lvrl... " >&6; } +if ${ac_cv_lib_vrl_iline_peekch+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lvrl $rc_lib_tgetent $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char iline_peekch (); +int +main () +{ +return iline_peekch (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_vrl_iline_peekch=yes +else + ac_cv_lib_vrl_iline_peekch=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_vrl_iline_peekch" >&5 +$as_echo "$ac_cv_lib_vrl_iline_peekch" >&6; } +if test "x$ac_cv_lib_vrl_iline_peekch" = xyes; then : + + LIBS="$LIBS -lvrl $rc_lib_tgetent" + +else + as_fn_error $? "vrl library not found" "$LINENO" 5 +fi + + ;; + *) + as_fn_error $? "unknown editing library $withval" "$LINENO" 5 + ;; + esac + +fi + + + + + + + +ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# 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, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# 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. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMC_RESTART_TRUE}" && test -z "${AMC_RESTART_FALSE}"; then + as_fn_error $? "conditional \"AMC_RESTART\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMC_NO_HASHBANG_TRUE}" && test -z "${AMC_NO_HASHBANG_FALSE}"; then + as_fn_error $? "conditional \"AMC_NO_HASHBANG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMC_HISTORY_TRUE}" && test -z "${AMC_HISTORY_FALSE}"; then + as_fn_error $? "conditional \"AMC_HISTORY\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMC_ADDON_TRUE}" && test -z "${AMC_ADDON_FALSE}"; then + as_fn_error $? "conditional \"AMC_ADDON\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by rc $as_me 1.7.4, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +rc config.status 1.7.4 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #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. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..acc75dc --- /dev/null +++ b/configure.ac @@ -0,0 +1,247 @@ +dnl Our package name, version, ... +AC_INIT([rc], [1.7.4]) + +dnl ... and release date +RELDATE=`date -I` +AC_DEFINE_UNQUOTED(RELDATE, "$RELDATE", [Release date]) + +dnl Get things going... +AC_CONFIG_SRCDIR([rc.h]) +AM_INIT_AUTOMAKE + +AC_CONFIG_HEADERS(config.h) + +dnl Find a standard C compiler +AC_PROG_CC + +dnl If we're using gcc, specify `-Wall'. I've also checked the code +dnl with `-pedantic -W -Wall -Wpointer-arith -Wstrict-prototypes +dnl -Wmissing-prototypes', and checked that all the warnings generated +dnl are harmless. +case "$GCC" in +yes) CFLAGS="-Wall $CFLAGS" ;; +esac + +AC_SYS_LARGEFILE + +AC_PROG_CPP +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 +AC_HEADER_SYS_WAIT + +AC_TYPE_GETGROUPS +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_TYPE_UID_T +AC_CHECK_TYPE(ssize_t, long) + +AC_CHECK_FUNCS(getgroups lstat setpgrp setrlimit sigaction) + +dnl We prefer system calls that don't restart. If we have sigaction() +dnl we'll use it. Otherwise, we check whether good ol' signal() +dnl produces interruptible system calls. +case "$ac_cv_func_sigaction" in +no) AC_SYS_RESTARTABLE_SYSCALLS ;; +esac +AM_CONDITIONAL(AMC_RESTART, test "$ac_cv_sys_restartable_syscalls" = yes) + +RC_FUNC_GETGROUPS + +RC_FUNC_SIGSETJMP + +AC_FUNC_SETPGRP + +RC_FUNC_STRERROR + +RC_NEED_KERNEL + +RC_TYPE_RLIM_T + +RC_TYPE_SIG_ATOMIC_T + +RC_SYS_V_SIGCLD + +dnl Does the kernel handle `#! /interpreter'? +AC_SYS_INTERPRETER +case "$ac_cv_sys_interpreter" in +yes) AC_DEFINE(HASH_BANG, 1, [Define to 1 if your kernel understands `#!' magic numbers]) ;; +esac +AM_CONDITIONAL(AMC_NO_HASHBANG, test "$ac_cv_sys_interpreter" = no) + + +dnl What do we do for command arguments? We want /dev/fd or Linux's +dnl /proc/self/fd. Failing that, we'll try for POSIX mkfifo(), or a +dnl mknod() that makes FIFOs. +RC_SYS_DEV_FD +case "$rc_cv_sys_dev_fd" in +yes) AC_DEFINE(HAVE_DEV_FD, 1, [Define to 1 if you have /dev/fd.]) ;; +odd) AC_DEFINE(HAVE_PROC_SELF_FD, 1, [Define to 1 if you have /proc/self/fd.]) ;; +no) AC_CHECK_FUNCS(mkfifo) ;; +esac + +case "$ac_cv_func_mkfifo" in +yes) AC_DEFINE(HAVE_FIFO, 1, [Define to 1 if you have the `mkfifo' function.]) ;; +no) RC_SYS_MKNOD_FIFO ;; +esac + +dnl Now handle arguments. +AC_ARG_ENABLE(builtin-echo, [ --disable-builtin-echo Don't include `echo' as a builtin], + test "x$enableval" != "xno" && AC_DEFINE(RC_ECHO, 1, [Define to 1 to include `echo' as a builtin.]), + 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, 1, [Define to 1 to use job-control-style backgrounding.]), + 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, 1, [Define to 1 to encode exported environment names.]), + AC_DEFINE(PROTECT_ENV)) + +AC_ARG_ENABLE(def-interp, +[ --enable-def-interp=/bin/foo + Use /bin/foo as default interpreter [[/bin/sh]]], +[ + case "$enableval" in + no) + ;; + yes) + AC_DEFINE(DEFAULTINTERP, "/bin/sh", [The default interpreter]) + ;; + *) + 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/bsd /usr/ucb /bin .)]]], +[ + case "$enableval" in + no|yes) ;; + *) AC_DEFINE_UNQUOTED(DEFAULTPATH, $enableval, [The default path]) ;; + esac +], + enable_def_path=yes) + +case "$enable_def_path" in +yes) 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/bsd /usr/ucb /bin .; do + if test -d $i; then + case "$rc_cv_def_path" in + '') 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_WITH(history, + [ --with-history Build history subprograms],[ + case "$withval" in + yes) rc_history=yes ;; + *) rc_history=no ;; + esac + ], rc_history=no) +AM_CONDITIONAL(AMC_HISTORY, test "$rc_history" = yes) + + +AC_ARG_WITH(addon, [ --with-addon[[=foo.c]] Extra builtins, from addon.c by default ],[ + case "$withval" in + yes) ADDON=addon.o ;; + no) ADDON='' ;; + *) ADDON=`echo $withval |sed 's/\.c$/\.o/'` ;; + esac +]) +AM_CONDITIONAL(AMC_ADDON, test "$ADDON" != "") +case "$ADDON" in +?*) AC_DEFINE(RC_ADDON, 1, [Define to 1 to use addon functions.]) ;; +esac +AC_SUBST(ADDON) + + +EDIT=edit-null.o +AC_ARG_WITH(edit, [ --with-edit=(edit,editline,readline,vrl) Command line editing library], [ + case $withval in + yes) + AC_MSG_ERROR(must specify which library) + # might consider searching + ;; + no|null) + ;; + edit|bsd) + EDIT=edit-edit.o + RC_LIB_TGETENT + AC_CHECK_LIB(edit, el_init, [ + LIBS="$LIBS -ledit $rc_lib_tgetent" + ], AC_MSG_ERROR(edit library not found), $rc_lib_tgetent) + ;; + editline) + EDIT=edit-editline.o + RC_LIB_TGETENT + AC_CHECK_LIB(editline, el_ring_bell, [ + LIBS="$LIBS -leditline $rc_lib_tgetent" + ], AC_MSG_ERROR(editline library not found), $rc_lib_tgetent) + ;; + readline|gnu) + EDIT=edit-readline.o + RC_LIB_TGETENT + AC_CHECK_LIB(readline, readline, [ + LIBS="$LIBS -lreadline $rc_lib_tgetent" + ], AC_MSG_ERROR(readline library not found), $rc_lib_tgetent) + AC_TRY_LINK([ + #include + #include + ], [ + rl_catch_signals = 0; + ], [], AC_MSG_ERROR(readline >= 4.0 not found)) + ;; + vrl) + EDIT=edit-vrl.o + RC_LIB_TGETENT + AC_CHECK_LIB(vrl, iline_peekch, [ + LIBS="$LIBS -lvrl $rc_lib_tgetent" + ], AC_MSG_ERROR(vrl library not found), $rc_lib_tgetent) + ;; + *) + AC_MSG_ERROR(unknown editing library $withval) + ;; + esac +]) +AC_SUBST(EDIT) +dnl AC_CHECK_LIB(edit, readline, +dnl AC_DEFINE(EDITLINE, 1, [Define to 1 if you are using `editline' or `vrl'.]) LIBS="$LIBS -ledit", +dnl AC_MSG_ERROR(editline library not found))) + +dnl if test "${with_vrl+set}" = set -o "${with_readline+set}" = set; then +dnl RC_LIB_TGETENT +dnl fi + +dnl AC_ARG_WITH(vrl, [ --with-vrl Gert-Jan Vons's line editing], +dnl AC_CHECK_LIB(vrl, readline, +dnl AC_DEFINE(EDITLINE) LIBS="$LIBS -lvrl $rc_lib_tgetent", +dnl AC_MSG_ERROR(vrl library not found), $rc_lib_tgetent)) + +dnl There are (at least) two incompatible versions of readline, and we +dnl need to know which one we are using. We don't support readline 2.0. +dnl AC_ARG_WITH(readline, [ --with-readline Bloated GNU line editing], [ +dnl AC_CHECK_LIB(readline, readline, [ +dnl AC_DEFINE(READLINE, 1, [Define to 1 if you are using GNU `readline'.]) +dnl LIBS="$LIBS -lreadline $rc_lib_tgetent" +dnl AC_CHECK_LIB(readline, _rl_clean_up_for_exit, , AC_DEFINE(READLINE_OLD, 1, [Define to 1 for older versions GNU `readline'.]), $rc_lib_tgetent) +dnl ], AC_MSG_ERROR(readline library not found), $rc_lib_tgetent) +dnl ]) +dnl AM_CONDITIONAL(AMC_READLINE, test "${with_readline+set}" = set) + +dnl For some reason CPPFLAGS doesn't get propagated. +dnl AC_SUBST(CPPFLAGS) + +AC_OUTPUT(Makefile) diff --git a/depcomp b/depcomp new file mode 100755 index 0000000..4ebd5b3 --- /dev/null +++ b/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2013-05-30.07; # UTC + +# Copyright (C) 1999-2013 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/edit-edit.c b/edit-edit.c new file mode 100644 index 0000000..c2a5260 --- /dev/null +++ b/edit-edit.c @@ -0,0 +1,91 @@ +#include "rc.h" + +#include + +#include + +#include "edit.h" + +bool editing = 1; + +struct cookie { + EditLine *el; + History *hist; +}; + +static char *prompt; + +void *edit_begin(int fd) { + FILE *f; + HistEvent he; + struct cookie *c; + + c = ealloc(sizeof *c); + if (fd == 0) + f = stdin; + else + f = fdopen(fd, "r"); + c->el = el_init("rc", f, stdout, stderr); + el_set(c->el, EL_SIGNAL, 0); + el_source(c->el, NULL); + + c->hist = history_init(); + history(c->hist, &he, H_SETSIZE, 20); + el_set(c->el, EL_HIST, history, c->hist); + + return c; +} + + +static void edit_catcher(int sig) { + write(2, "\n", 1); + rc_raise(eError); +} + +char *edit_alloc(void *cookie, size_t *count) { + const char *r; + HistEvent he; + struct cookie *c = cookie; + void (*oldint)(int), (*oldquit)(int); + + oldint = sys_signal(SIGINT, edit_catcher); + oldquit = sys_signal(SIGQUIT, edit_catcher); + + r = el_gets(c->el, count); + + sys_signal(SIGINT, oldint); + sys_signal(SIGQUIT, oldquit); + + if (r) + history(c->hist, &he, H_ENTER, r); + return (char *)r; /* cast to avoid gcc warning */ +} + +static char *edit_prompter(EditLine *e) { + return prompt; +} + +void edit_prompt(void *cookie, char *pr) { + struct cookie *c = cookie; + + prompt = pr; + el_set(c->el, EL_PROMPT, edit_prompter); +} + +void edit_free(void *cookie) { + /* this function deliberately left blank */ +} + +void edit_end(void *cookie) { + struct cookie *c = cookie; + + el_end(c->el); + history_end(c->hist); + efree(c); +} + +void edit_reset(void *cookie) { + struct cookie *c = cookie; + + el_set(c->el, EL_TERMINAL, NULL); +} diff --git a/edit-editline.c b/edit-editline.c new file mode 100644 index 0000000..85e3f40 --- /dev/null +++ b/edit-editline.c @@ -0,0 +1,100 @@ +#include "rc.h" + +#include +#include + +#include "editline.h" + +bool editing = 1; + +struct cookie { + char *buffer; +}; + +static char *prompt; + +void *edit_begin(int fd) { + List *hist; + struct cookie *c; + + hist = varlookup("history"); + if (hist != NULL) + if (read_history(hist->w) != 0 && + errno != ENOENT) /* ignore if missing */ + uerror(hist->w); + + c = ealloc(sizeof *c); + c->buffer = NULL; + return c; +} + +/* +static void edit_catcher(int sig) { + write(2, "\n", 1); + rc_raise(eError); +} + +*/ + +char *edit_alloc(void *cookie, size_t *count) { + struct cookie *c = cookie; +/* + const char *r; + HistEvent he; + struct cookie *c = cookie; + void (*oldint)(int), (*oldquit)(int); + + oldint = sys_signal(SIGINT, edit_catcher); + oldquit = sys_signal(SIGQUIT, edit_catcher); + + r = el_gets(c->el, count); + + sys_signal(SIGINT, oldint); + sys_signal(SIGQUIT, oldquit); + + if (r) + history(c->hist, &he, H_ENTER, r); +*/ + + c->buffer = readline(prompt); + if (c->buffer) { + *count = strlen(c->buffer); + c->buffer[*count] = '\n'; + ++*count; + } + return c->buffer; +} + +/* +static char *edit_prompter(ne *e) { + return prompt; +} +*/ + +void edit_prompt(void *cookie, char *pr) { + //struct cookie *c = cookie; + + prompt = pr; + //el_set(c->el, EL_PROMPT, edit_prompter); +} + +void edit_free(void *cookie) { + struct cookie *c = cookie; + + efree(c->buffer); + c->buffer = NULL; /* allow "overfrees" */ +} + +void edit_end(void *cookie) { + //struct cookie *c = cookie; + + //el_end(c->el); + //history_end(c->hist); + //efree(c); +} + +void edit_reset(void *cookie) { + //struct cookie *c = cookie; + + //el_set(c->el, EL_TERMINAL, NULL); +} diff --git a/edit-null.c b/edit-null.c new file mode 100644 index 0000000..e3cbe13 --- /dev/null +++ b/edit-null.c @@ -0,0 +1,35 @@ +#include "rc.h" + +#include + +#include + +#include "edit.h" + +bool editing = 0; + +void *edit_begin(int fd) { + assert(0); /* should never be called */ + return NULL; +} + +char *edit_alloc(void *cookie, size_t *count) { + assert(0); /* should never be called */ + return NULL; +} + +void edit_prompt(void *cookie, char *prompt) { + assert(0); /* should never be called */ +} + +void edit_free(void *buffer) { + assert(0); /* should never be called */ +} + +void edit_end(void *cookie) { + assert(0); /* should never be called */ +} + +void edit_reset(void *cookie) { + assert(0); /* should never be called */ +} diff --git a/edit-readline.c b/edit-readline.c new file mode 100644 index 0000000..6a997c5 --- /dev/null +++ b/edit-readline.c @@ -0,0 +1,87 @@ +#include "rc.h" + +#include +#include +#include +#include +#include + +#include "edit.h" + +bool editing = 1; + +struct cookie { + char *buffer; +}; + +void *edit_begin(int fd) { + List *hist; + struct cookie *c; + + rl_catch_signals = 0; + rl_completer_quote_characters = "'"; + rl_filename_quote_characters = "\t\n !#$&'()*;<=>?@[\\]^`{|}~"; + + hist = varlookup("history"); + if (hist != NULL) + if (read_history(hist->w) != 0 && errno != ENOENT) /* ignore if missing */ + uerror(hist->w); + + c = ealloc(sizeof *c); + c->buffer = NULL; + return c; +} + +static void edit_catcher(int sig) { + write(2, "\n", 1); + rc_raise(eError); +} + +static char *prompt; + +char *edit_alloc(void *cookie, size_t *count) { + struct cookie *c = cookie; + void (*oldint)(int), (*oldquit)(int); + + oldint = sys_signal(SIGINT, edit_catcher); + oldquit = sys_signal(SIGQUIT, edit_catcher); + + c->buffer = readline(prompt); + + sys_signal(SIGINT, oldint); + sys_signal(SIGQUIT, oldquit); + + if (c->buffer) { + *count = strlen(c->buffer); + if (*count) + add_history(c->buffer); + c->buffer[*count] = '\n'; + ++*count; /* include the \n */ + } + return c->buffer; +} + +void edit_prompt(void *cookie, char *pr) { + prompt = pr; +} + +void edit_free(void *cookie) { + struct cookie *c = cookie; + + efree(c->buffer); + /* Set c->buffer to NULL, allowing us to "overfree" it. This + is a bit of a kludge, but it's otherwise hard to deal with + the case where a signal causes an early return from + readline. */ + c->buffer = NULL; +} + +void edit_end(void *cookie) { + struct cookie *c = cookie; + + efree(c); +} + +void edit_reset(void *cookie) { + rl_reset_terminal(NULL); +} diff --git a/edit-vrl.c b/edit-vrl.c new file mode 100644 index 0000000..5c8ab5a --- /dev/null +++ b/edit-vrl.c @@ -0,0 +1,104 @@ +#include "rc.h" + +#include +#include + +#include "edit.h" + +extern char *readline(char *); +extern void add_history(char *); + +bool editing = 1; + +struct cookie { + char *buffer; +}; + +static char *prompt; + +void *edit_begin(int fd) { + List *hist; + struct cookie *c; + + + hist = varlookup("history"); + if (hist != NULL) + ; + /* XXX will need to loop calling add_history() */ + + c = ealloc(sizeof *c); + c->buffer = NULL; + return c; +} + +/* +static void edit_catcher(int sig) { + write(2, "\n", 1); + rc_raise(eError); +} + +*/ + +char *edit_alloc(void *cookie, size_t *count) { + struct cookie *c = cookie; +/* + const char *r; + HistEvent he; + struct cookie *c = cookie; + void (*oldint)(int), (*oldquit)(int); + + oldint = sys_signal(SIGINT, edit_catcher); + oldquit = sys_signal(SIGQUIT, edit_catcher); + + r = el_gets(c->el, count); + + sys_signal(SIGINT, oldint); + sys_signal(SIGQUIT, oldquit); + + if (r) + history(c->hist, &he, H_ENTER, r); +*/ + + c->buffer = readline(prompt); + if (c->buffer) { + add_history(c->buffer); + *count = strlen(c->buffer); + c->buffer[*count] = '\n'; + ++*count; + } + return c->buffer; +} + +/* +static char *edit_prompter(ne *e) { + return prompt; +} +*/ + +void edit_prompt(void *cookie, char *pr) { + //struct cookie *c = cookie; + + prompt = pr; + //el_set(c->el, EL_PROMPT, edit_prompter); +} + +void edit_free(void *cookie) { + struct cookie *c = cookie; + + efree(c->buffer); + c->buffer = NULL; /* allow "overfrees" */ +} + +void edit_end(void *cookie) { + //struct cookie *c = cookie; + + //el_end(c->el); + //history_end(c->hist); + //efree(c); +} + +void edit_reset(void *cookie) { + //struct cookie *c = cookie; + + //el_set(c->el, EL_TERMINAL, NULL); +} diff --git a/edit.h b/edit.h new file mode 100644 index 0000000..5f4eb5c --- /dev/null +++ b/edit.h @@ -0,0 +1,12 @@ +extern bool editing; + +extern void *edit_begin(int fd); + +extern char *edit_alloc(void *, size_t *); +extern void edit_free(void *); + +extern void edit_prompt(void *, char *); + +extern void edit_end(void *); + +extern void edit_reset(void *); diff --git a/except.c b/except.c new file mode 100644 index 0000000..8f20676 --- /dev/null +++ b/except.c @@ -0,0 +1,143 @@ +#include "rc.h" + +#include +#include + +#include "input.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; + siglongjmp(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, -1); + 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 new file mode 100644 index 0000000..c9244c2 --- /dev/null +++ b/exec.c @@ -0,0 +1,131 @@ +/* exec.c */ + +#include "rc.h" + +#include +#include + +#include "wait.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()); + } + rc_execve(path, (char * const *) av, (char * const *) ev); + +#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 (WIFEXITED(stat)) + nl_on_intr = FALSE; + sigchk(); + nl_on_intr = TRUE; + pop_cmdarg(TRUE); + } +} diff --git a/execve.c b/execve.c new file mode 100644 index 0000000..5edde11 --- /dev/null +++ b/execve.c @@ -0,0 +1,62 @@ +/* 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 "rc.h" + +#include + +#define giveupif(x) { if (x) goto fail; } + +extern int rc_execve(char *path, char **av, 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 new file mode 100644 index 0000000..7d9e4f7 --- /dev/null +++ b/fn.c @@ -0,0 +1,261 @@ +/* + fn.c: functions for adding and deleting functions from the symbol table. + Support for signal handlers is also found here. +*/ + +#include "rc.h" + +#include +#include + +#include "input.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++) +#if HAVE_SYSV_SIGCLD + 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 ignore) { +} + +/* + 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 */ + rc_Function *new = get_fn_place(name); + int i; + new->def = newdef; + new->extdef = NULL; + if (strncmp(name, "sig", conststrlen("sig")) == 0) { /* slight optimization */ +#if HAVE_SYSV_SIGCLD /* 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_" */ + rc_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) { + rc_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(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) { + rc_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 new file mode 100644 index 0000000..d6f6dfd --- /dev/null +++ b/footobar.c @@ -0,0 +1,387 @@ +/* + footobar.c: a collection of functions to convert internal representations of + variables and functions to external representations, and vice versa +*/ + +#include "rc.h" + +#include "input.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 */ + +static 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) { + bool dollar = f->flags & FMT_altform; + Node *n = va_arg(f->args, Node *); + + if (n == NULL) { + fmtprint(f, "()"); + return FALSE; + } + switch (n->type) { + 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 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 nWord: + fmtprint(f, n->u[2].i && quotep(n->u[0].s, dollar) ? + "%#S" : "%S", n->u[0].s); + break; + case nLappend: { + static bool inlist; + if (!inlist) { + inlist = TRUE; + fmtprint(f, "(%T %T)", n->u[0].p, n->u[1].p); + inlist = FALSE; + } else { + 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) + 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; + } +} + +/* interpret a variable from environment. ^A separates list elements; + ^B escapes a literal ^A or ^B. For minimal surprise, ^B followed + by anything other than ^A or ^B is preserved. */ + +extern List *parse_var(char *extdef) { + char *begin, *end, *from, *to; + int len; + List *first, *last, *new; + + first = last = NULL; + begin = strchr(extdef, '='); + assert(begin); /* guaranteed by initenv() */ + while (*begin) { + ++begin; + end = begin; + len = 0; + while (*end != ENV_SEP && *end != '\0') { + if (*end == ENV_ESC) { + ++end; + if (*end != ENV_SEP && *end != ENV_ESC) --end; + } + ++end; ++len; + } + new = enew(List); + if (last) + last->n = new; + else + first = new; + last = new; + new->w = ealloc(len + 1); + new->m = NULL; + new->n = NULL; + to = new->w; + for (from = begin; from < end; ++from) { + if (*from == ENV_ESC) { + ++from; + if (*from != ENV_SEP && *from != ENV_ESC) + --from; + } + *to = *from; + ++to; + } + *to = '\0'; + begin = end; + } + return first; +} + +/* 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 *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 ignore) { + char **a = va_arg(f->args, char **); + if (*a != NULL) { + fmtcat(f, *a); + while (*++a != NULL) + fmtprint(f, " %s", *a); + } + return FALSE; +} + +/* %L -- print a list */ +static bool Lconv(Format *f, int ignore) { + bool plain; + char *sep; + List *l, *n; + + plain = f->flags & FMT_leftside; + l = va_arg(f->args, List *); + sep = va_arg(f->args, char *); + if (l == NULL && (f->flags & FMT_leftside) == 0) + fmtprint(f, "()"); + else { + for (; l != NULL; l = n) { + n = l->n; + fmtprint(f, plain ? "%s" : "%-S", l->w); + if (n != NULL) fmtputc(f, *sep); + } + } + return FALSE; +} + +/* %W -- print a list for exporting */ +static bool Wconv(Format *f, int ignore) { + List *l, *n; + + l = va_arg(f->args, List *); + for (; l != NULL; l = n) { + char c, *s; + + for (s = l->w; (c = *s) != '\0'; ++s) { + if (c == ENV_SEP || c == ENV_ESC) + fmtputc(f, ENV_ESC); + fmtputc(f, c); + } + n = l->n; + if (n != NULL) fmtputc(f, ENV_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); + fmtinstall('W', Wconv); +#if PROTECT_ENV + fmtinstall('F', Fconv); +#else + fmtinstall('F', fmtinstall('s', NULL)); +#endif +} diff --git a/getgroups.h b/getgroups.h new file mode 100644 index 0000000..982dfa0 --- /dev/null +++ b/getgroups.h @@ -0,0 +1,10 @@ +#if HAVE_GETGROUPS +#if HAVE_POSIX_GETGROUPS +/* We love POSIX. */ +#else +/* OK, so you've got getgroups, but you don't have the POSIX semantics +of a zero first argument. The conclusion is that you're on a reasonably +pure BSD system, and we can include for NGROUPS. */ +#include +#endif +#endif diff --git a/getopt.c b/getopt.c new file mode 100644 index 0000000..3c54f53 --- /dev/null +++ b/getopt.c @@ -0,0 +1,51 @@ +#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 new file mode 100644 index 0000000..5507678 --- /dev/null +++ b/glob.c @@ -0,0 +1,266 @@ +/* glob.c: rc's (ugly) globber. This code is not elegant, but it works */ + +#include "rc.h" +#include "stat.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; + if (s == NULL) { + if (p == NULL) /* null matches null */ + return TRUE; + for (; p != NULL; p = p->n) /* one or more stars match null */ + if (strspn(p->w, "*") == strlen(p->w) && + p->m != NULL && strlen(p->m) == strlen(p->w)) + 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; + 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 (lstat(path, &s) < 0) + return NULL; + r = nnew(List); + r->w = ncpy(p); + r->m = NULL; + r->n = NULL; + return r; + } + + top = r = NULL; + if (*d == '\0') d = "/"; + 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 against 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; + while (*s != '/' && *s != '\0') { + *d++ = *s++; /* get first directory component */ + *md++ = *m++; + } + *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 new file mode 100644 index 0000000..c44f0d5 --- /dev/null +++ b/glom.c @@ -0,0 +1,439 @@ +/* glom.c: builds an argument list out of words, variables, etc. */ + +#include "rc.h" + +#include +#include +#include + +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 + +#if HAVE_MKFIFO +/* Have POSIX mkfifo(). */ +#else +#define mkfifo(n,m) mknod(n, S_IFIFO | m, 0) +#endif + +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 (mkfifo(name, 0666) < 0) { + uerror("mkfifo"); + 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("command arguments 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) + 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: + 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/hash.c b/hash.c new file mode 100644 index 0000000..5fafed2 --- /dev/null +++ b/hash.c @@ -0,0 +1,317 @@ +/* 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(rc_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 rc_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(rc_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(rc_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 char *neverexport[] = { + "apid", "apids", "bqstatus", "cdpath", "home", + "ifs", "path", "pid", "status", "*" +}; + +/* for a few variables that have default values, we export them only +if they've been explicitly set; maybeexport[n].flag is TRUE if this +has occurred. */ +struct nameflag { + char *name; + bool flag; +}; +static struct nameflag maybeexport[] = { + { "prompt", FALSE }, + { "version", FALSE } +}; + +void set_exportable(char *s, bool b) { + int i; + for (i = 0; i < arraysize(maybeexport); ++i) + if (maybeexport[i].flag != b && streq(s, maybeexport[i].name)) + maybeexport[i].flag = b; +} + +static bool var_exportable(char *s) { + int i; + for (i = 0; i < arraysize(neverexport); i++) + if (streq(s, neverexport[i])) + return FALSE; + for (i = 0; i < arraysize(maybeexport); i++) + if (maybeexport[i].flag == FALSE && streq(s, maybeexport[i].name)) + 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)); +} diff --git a/heredoc.c b/heredoc.c new file mode 100644 index 0000000..348dc84 --- /dev/null +++ b/heredoc.c @@ -0,0 +1,158 @@ +/* heredoc.c: heredoc slurping is done here */ + +#include "rc.h" + +#include "input.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 (;;) { + nextline(); + 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(nWord, begin, NULL); + break; + } + case '$': { + char *begin = ++s, *var; + c = *s++; + if (c == '$') { + node = mk(nWord, "$", 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(nWord, s, NULL, FALSE) : 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) { + yyerror("eof-marker not a single literal word"); + skiptonl(); + return FALSE; + } + for (prev = &hq; (new = *prev) != NULL; prev = &new->n) + ; + *prev = new = nnew(Hq); + new->name = name->u[0].s; + new->quoted = name->u[2].i; + new->doc = n; + new->n = NULL; + return TRUE; +} diff --git a/history.1 b/history.1 new file mode 100644 index 0000000..0be8684 --- /dev/null +++ b/history.1 @@ -0,0 +1,254 @@ +.\" 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 from left to right and are repeated according to the +number of colons specified. +.PP +Finally, if the program was invoked as +.RI `` -- '' +or +.RI `` --p '', +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 except those below +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 line +If any changes have been made, the command is printed out again for +further editing. If no changes have been made, the command is executed +or printed, and the program exits. +.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 "}" +.De +.PP +Stuttering the `:' in a substitution allows things like: +.Ds +; prog 1 2 3 abc > /very/long/path/abc.out +etc. +- prog abc::xyz +prog 1 2 3 xyz > /very/long/path/xyz.out +; +.De diff --git a/history.c b/history.c new file mode 100644 index 0000000..1f22f2e --- /dev/null +++ b/history.c @@ -0,0 +1,347 @@ +/* + 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 "rc.h" + +#include + +static const char id[] = "$Release: @(#)" PACKAGE " " VERSION " " RELDATE " $"; + +#define CHUNKSIZE 65536 + +static struct { + char *old, *new; + int reps; /* no. of repetitions. i.e. 1 means sub twice. */ +} *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 *histfile; + +void *ealloc(size_t n) { + void *p = (void *) malloc(n); + if (p == NULL) { + perror("malloc"); + exit(1); + } + return p; +} + +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 *rc_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); + if (!t) + return s; + 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++) { + *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(void) { + char *s, *t; + static char *hist = NULL, *last; + + if (hist == NULL) { + hist = readhistoryfile(&last); + *--last = '\0'; /* replaces final newline */ + ++hist; /* start beyond sentinel */ + } + +again: s = last; + if (s < hist) + return NULL; + while (s >= hist && *s != '\n') + --s; + *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 '|': + case '/': + goto again; + default: + break; + } + } + return s; +} + +int main(int argc, char **argv) { + int i; + char *s; + + s = progname = rc_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].reps = 0; + while(*(++s) == ':') { + replace[nreplace].reps++; + } + replace[nreplace].old = argv[i]; + replace[nreplace].new = s; + 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 { + int j; + for (j = 0; j <= replace[i].reps; j++) + s = sub(s, replace[i].old, replace[i].new); + } + if (editit) { + s = edit(s); + if (s == NULL) + goto next; + } + fseek(histfile, 0, 2); /* 2 == end of file. i.e., append command to $history */ + fprintf(histfile, "%s\n", s); + fclose(histfile); + 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, rc_basename(shell), "-c", s, NULL); + perror(shell); + exit(1); + } + return 0; +} diff --git a/input.c b/input.c new file mode 100644 index 0000000..5737375 --- /dev/null +++ b/input.c @@ -0,0 +1,357 @@ +/* input.c: i/o routines for files and pseudo-files (strings) */ + +#include "rc.h" + +#include + +#include "edit.h" +#include "input.h" +#include "jbwrap.h" + +/* How many characters can we unget? */ +enum { UNGETSIZE = 2 }; + +typedef enum inputtype { + iFd, iString, iEdit +} inputtype; + +typedef struct Input { + bool saved; + inputtype t; + int fd, index, read, ungetcount, lineno, last; + char *ibuf; + void *cookie; + int ungetbuf[UNGETSIZE]; + int (*gchar)(void); +} Input; + +#define BUFSIZE ((size_t) 256) + +static char *inbuf; +static size_t istacksize, chars_out, chars_in; +static bool save_lineno = TRUE; +static Input *istack, *itop; + +int lastchar; + +static char *prompt, *prompt2; + +extern void ugchar(int c) { + assert(istack->ungetcount < UNGETSIZE); + istack->ungetbuf[istack->ungetcount++] = c; +} + +extern int gchar() { + int c; + + if (istack->ungetcount) + return lastchar = istack->ungetbuf[--istack->ungetcount]; + + while ((c = (*istack->gchar)()) == '\0') + pr_error("warning: null character ignored", 0); + + return c; +} + + +/* get the next character from a string. */ + +static int stringgchar() { + return lastchar = (inbuf[chars_out] == '\0' ? EOF : inbuf[chars_out++]); +} + + +/* 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]; + + /* 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); + else { + writeall(fd, inbuf, chars_in); + close(fd); + } + break; + } + } +} + + +/* read a character from a file descriptor */ + +static int fdgchar() { + if (chars_out >= chars_in) { /* replenish empty buffer */ + ssize_t r; + do { + r = rc_read(istack->fd, inbuf, BUFSIZE); + sigchk(); + if (r == -1) + switch (errno) { + case EAGAIN: + if (!makeblocking(istack->fd)) + panic("not O_NONBLOCK"); + errno = EINTR; + break; + case EIO: + if (makesamepgrp(istack->fd)) + errno = EINTR; + else + errno = EIO; + break; + } + } while (r < 0 && errno == EINTR); + if (r < 0) { + uerror("read"); + rc_raise(eError); + } + chars_in = (size_t) r; + if (chars_in == 0) + return lastchar = EOF; + chars_out = 0; + if (dashvee) + writeall(2, inbuf, chars_in); + history(); + } + + return lastchar = inbuf[chars_out++]; +} + +/* read a character from a line-editing file descriptor */ + +static int editgchar() { + if (chars_out >= chars_in) { /* replenish empty buffer */ + edit_free(istack->cookie); + inbuf = edit_alloc(istack->cookie, &chars_in); + if (inbuf == NULL) { + chars_in = 0; + fprint(2, "exit\n"); + return lastchar = EOF; + } + + chars_out = 0; + if (dashvee) + writeall(2, inbuf, chars_in); + history(); + } + + return lastchar = inbuf[chars_out++]; +} + +void termchange(void) { + if (istack->t == iEdit) + edit_reset(istack->cookie); +} + + +/* 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->ungetcount = 0; + ugchar(EOF); +} + +/* 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 = lastchar; + istack++; + idiff = istack - itop; + if (idiff >= istacksize / sizeof (Input)) { + itop = erealloc(itop, istacksize *= 2); + istack = itop + idiff; + } + chars_out = 0; + chars_in = 0; + istack->ungetcount = 0; +} + +extern void pushfd(int fd) { + pushcommon(); + save_lineno = TRUE; + istack->fd = fd; + lineno = 1; + if (editing && interactive && isatty(fd)) { + istack->t = iEdit; + istack->gchar = editgchar; + istack->cookie = edit_begin(fd); + } else { + istack->t = iFd; + istack->gchar = fdgchar; + inbuf = ealloc(BUFSIZE); + } +} + +extern void pushstring(char **a, bool save) { + pushcommon(); + istack->t = iString; + save_lineno = save; + inbuf = mprint("%A", a); + istack->gchar = stringgchar; + if (save_lineno) + lineno = 1; + else + --lineno; +} + + +/* remove an input source from the stack. restore associated variables etc. */ + +extern void popinput() { + if (istack->t == iEdit) + edit_end(istack->cookie); + if (istack->t == iFd || istack->t == iEdit) + close(istack->fd); + efree(inbuf); + --istack; + lastchar = istack->last; + 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 up to newline. Used by scanerror() */ + +extern void skiptonl() { + int c; + if (lastchar == '\n' || lastchar == 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 clobberexecit) { + bool eof; + bool execit; + Jbwrap j; + Estack e1; + Edata jerror; + + if (dashen) + clobberexecit = FALSE; + execit = clobberexecit; + sigsetjmp(j.j, 1); + jerror.jb = &j; + except(eError, jerror, &e1); + for (eof = FALSE; !eof;) { + Edata block; + Estack e2; + + block.b = newblock(); + except(eArena, block, &e2); + sigchk(); + + if (interactive) { + List *s; + if (!dashen && fnlookup("prompt") != NULL) { + static bool died = FALSE; + static char *arglist[] = { "prompt", NULL }; + + if (!died) { + died = TRUE; + funcall(arglist); + } + died = FALSE; + } + s = varlookup("prompt"); + if (s != NULL) { + prompt = s->w; + if (s->n != NULL) + prompt2 = s->n->w; + else + prompt2 = ""; + } else { + prompt = prompt2 = ""; + } + if (istack->t == iFd) + fprint(2, "%s", prompt); + else if (istack->t == iEdit) + edit_prompt(istack->cookie, prompt); + } + inityy(); + if (yyparse() == 1 && execit) + rc_raise(eError); + eof = (lastchar == EOF); /* "lastchar" 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) { + bool 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; +} + +/* 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; + } +} + +/* print (or set) prompt(2) */ + +extern void nextline() { + lineno++; + if (interactive) { + if (istack->t == iFd) + fprint(2, "%s", prompt2); + else if (istack->t == iEdit) + edit_prompt(istack->cookie, prompt2); + } +} diff --git a/input.h b/input.h new file mode 100644 index 0000000..87db27b --- /dev/null +++ b/input.h @@ -0,0 +1,35 @@ +/* initialize the input stack */ +extern void initinput(void); + +/* push an input onto the stack */ +extern void pushfd(int); +/* the Boolean argument affects line number reporting */ +extern void pushstring(char **, bool); + +/* pop the stack */ +extern void popinput(void); + +/* get / unget the next character */ +extern int gchar(void); +extern void ugchar(int); + +/* $TERM or $TERMCAP has changed */ +extern void termchange(void); + +/* parse a function from the environment */ +extern Node *parseline(char *); + +/* main parsing loop; Boolean says whether to exec also */ +extern Node *doit(bool); + +/* error recovery: skip to the next newline */ +extern void skiptonl(void); + +/* prepare for next line of input */ +extern void nextline(void); + +/* close all file descriptors on the stack */ +extern void closefds(void); + +/* the last character read */ +extern int lastchar; diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..377bb86 --- /dev/null +++ b/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-11-20.07; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# 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. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # 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 $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/jbwrap.h b/jbwrap.h new file mode 100644 index 0000000..4b3ea86 --- /dev/null +++ b/jbwrap.h @@ -0,0 +1,23 @@ +#include + +/* If we have POSIX sigjmp_buf and friends, use them. If we don't, just +use a jmp_buf. This probably fails on a traditional SysV machine, where +jmp_bufs don't preserve signal masks. I'm not worrying about this till +someone reports it as a bug :-). */ + +#if HAVE_SIGSETJMP +#else +#define sigjmp_buf jmp_buf +#define sigsetjmp(x,y) setjmp(x) +#define siglongjmp longjmp +#endif /* HAVE_SIGSETJMP */ + + +/* Certain braindamaged environments don't define jmp_buf as an array, +so wrap it in a structure. Potentially, we could use configure to do +this only where it needs to be done, but the effort is probably not +worth it. */ + +struct Jbwrap { + sigjmp_buf j; +}; diff --git a/lex.c b/lex.c new file mode 100644 index 0000000..92732f8 --- /dev/null +++ b/lex.c @@ -0,0 +1,416 @@ +/* lex.c: rc's lexical analyzer */ + +#include "rc.h" + +#include "input.h" +#include "parse.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; + +/* lookup table for non-word characters */ +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 +}; + +/* lookup table for non-word characters in variable names */ +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 +}; + +/* lookup table for quotable characters: nw + glob metachars */ +const char q[] = { + 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +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 +}; + +/* does this string require quoting? */ +extern bool quotep(char *s, bool dollar) { + unsigned char c; + const char *meta; + + meta = dollar ? dnw : q; + while ((c = *s++)) + if (meta[c]) + return TRUE; + return FALSE; +} + +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); + if (newline) { + --lineno; /* slight space optimization; nextline() always increments lineno */ + nextline(); + newline = FALSE; + } +top: while ((c = gchar()) == ' ' || c == '\t') + w = NW; + if (c != '(') dollar = FALSE; + 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') { + nextline(); + 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; + } + y->word.q = FALSE; + 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 == '^' || c == '"') + return FLAT; + ugchar(c); + return '$'; + case '\'': + w = RW; + i = 0; + /* double ' to quote it, like this: 'how''s it going?' */ + while ((c = gchar()) != '\'' || (c = gchar()) == '\'') { + buf[i++] = c; + if (c == '\n') + nextline(); + if (c == EOF) { + w = NW; + scanerror("eof in quoted string"); + return HUH; + } + if (i >= bufsize) + buf = realbuf = erealloc(buf, bufsize *= 2); + } + ugchar(c); + buf[i] = '\0'; + y->word.w = ncpy(buf); + y->word.m = NULL; + y->word.q = TRUE; + return WORD; + case '\\': + if ((c = gchar()) == '\n') { + nextline(); + 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 keywords, 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 (lastchar == EOF) + tok = "eof"; + else if (lastchar == '\n') + tok = "end of line"; + else + tok = nprint((lastchar < 32 || lastchar > 126) ? "(decimal %d)" : "'%c'", lastchar); + fprint(2, "rc: line %d: %s near %s\n", lineno - (lastchar == '\n'), s, tok); + } else + fprint(2, "rc: %s\n", s); +} + +extern void scanerror(char *s) { + skiptonl(); /* flush up to 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); +} + +/* + 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 new file mode 100644 index 0000000..fba6f6a --- /dev/null +++ b/list.c @@ -0,0 +1,57 @@ +/* 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 new file mode 100644 index 0000000..4da3014 --- /dev/null +++ b/main.c @@ -0,0 +1,154 @@ +/* main.c: handles initialization of rc and command line options */ + +#include "rc.h" + +#include + +#include "input.h" + +bool dashdee, dashee, dashvee, dashex, dasheye, + dashen, dashpee, interactive; +pid_t rc_pid; + +static bool dashEYE, dashell, dashoh, dashess; + +static void assigndefault(char *,...); +static void checkfd(int, enum redirtype); + +extern int 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, "c:deiIlnopsvx")) != -1) + switch (c) { + case 'c': + dashsee[0] = rc_optarg; + goto quitopts; + case 'd': + dashdee = TRUE; + break; + case 'e': + dashee = TRUE; + break; + case 'I': + dashEYE = TRUE; + interactive = FALSE; + break; + case 'i': + dasheye = interactive = TRUE; + break; + case 'l': + dashell = TRUE; + break; + case 'n': + dashen = TRUE; + break; + case 'o': + dashoh = TRUE; + break; + case 'p': + dashpee = TRUE; + break; + case 's': + dashess = TRUE; + break; + case 'v': + dashvee = TRUE; + break; + case 'x': + dashex = TRUE; + break; + case '?': + exit(1); + } +quitopts: + argv += rc_optind; + /* use isatty() iff neither -i nor -I is set, and iff the input is not from a script or -c flags */ + if (!dasheye && !dashEYE && dashsee[0] == NULL && (dashess || *argv == NULL)) + interactive = isatty(0); + if (!dashoh) { + checkfd(0, rFrom); + checkfd(1, rCreate); + checkfd(2, rCreate); + } + initsignal(); + inithash(); + initparse(); + assigndefault("ifs", " ", "\t", "\n", (void *)0); +#ifdef DEFAULTPATH + assigndefault("path", DEFAULTPATH, (void *)0); +#endif + assigndefault("pid", nprint("%d", rc_pid), (void *)0); + assigndefault("prompt", "; ", "", (void *)0); + assigndefault("version", VERSION, "$Release: @(#)" PACKAGE " " VERSION " " RELDATE " $", (void *)0); + initenv(envp); + initinput(); + null[0] = NULL; + starassign(dollarzero, null, FALSE); /* assign $0 to $* */ + inithandler(); + + if (dashell) { + char *rcrc; + int fd; + + rcrc = concat(varlookup("home"), word("/.rcrc", NULL))->w; + fd = rc_open(rcrc, rFrom); + if (fd == -1) { + if (errno != ENOENT) + uerror(rcrc); + } else { + bool push_interactive; + + pushfd(fd); + push_interactive = interactive; + interactive = FALSE; + doit(TRUE); + interactive = push_interactive; + close(fd); + } + } + + 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()); + return 0; /* Never really reached. */ +} + +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); + set_exportable(name, 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/make.log b/make.log new file mode 100644 index 0000000..95fbe37 --- /dev/null +++ b/make.log @@ -0,0 +1,91 @@ +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT mksignal.o -MD -MP -MF .deps/mksignal.Tpo -c -o mksignal.o mksignal.c +mv -f .deps/mksignal.Tpo .deps/mksignal.Po +gcc -Wall -g -O2 -o mksignal mksignal.o +./mksignal +make all-am +make[1]: Entering directory '/mnt/data/Downloads/rc-1.7.4' +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT builtins.o -MD -MP -MF .deps/builtins.Tpo -c -o builtins.o builtins.c +mv -f .deps/builtins.Tpo .deps/builtins.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT except.o -MD -MP -MF .deps/except.Tpo -c -o except.o except.c +mv -f .deps/except.Tpo .deps/except.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT exec.o -MD -MP -MF .deps/exec.Tpo -c -o exec.o exec.c +mv -f .deps/exec.Tpo .deps/exec.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT fn.o -MD -MP -MF .deps/fn.Tpo -c -o fn.o fn.c +mv -f .deps/fn.Tpo .deps/fn.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT footobar.o -MD -MP -MF .deps/footobar.Tpo -c -o footobar.o footobar.c +mv -f .deps/footobar.Tpo .deps/footobar.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT getopt.o -MD -MP -MF .deps/getopt.Tpo -c -o getopt.o getopt.c +mv -f .deps/getopt.Tpo .deps/getopt.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT glob.o -MD -MP -MF .deps/glob.Tpo -c -o glob.o glob.c +mv -f .deps/glob.Tpo .deps/glob.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT glom.o -MD -MP -MF .deps/glom.Tpo -c -o glom.o glom.c +mv -f .deps/glom.Tpo .deps/glom.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT hash.o -MD -MP -MF .deps/hash.Tpo -c -o hash.o hash.c +mv -f .deps/hash.Tpo .deps/hash.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT heredoc.o -MD -MP -MF .deps/heredoc.Tpo -c -o heredoc.o heredoc.c +mv -f .deps/heredoc.Tpo .deps/heredoc.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT input.o -MD -MP -MF .deps/input.Tpo -c -o input.o input.c +mv -f .deps/input.Tpo .deps/input.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT lex.o -MD -MP -MF .deps/lex.Tpo -c -o lex.o lex.c +mv -f .deps/lex.Tpo .deps/lex.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT list.o -MD -MP -MF .deps/list.Tpo -c -o list.o list.c +mv -f .deps/list.Tpo .deps/list.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c +mv -f .deps/main.Tpo .deps/main.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT match.o -MD -MP -MF .deps/match.Tpo -c -o match.o match.c +mv -f .deps/match.Tpo .deps/match.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT nalloc.o -MD -MP -MF .deps/nalloc.Tpo -c -o nalloc.o nalloc.c +mv -f .deps/nalloc.Tpo .deps/nalloc.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT open.o -MD -MP -MF .deps/open.Tpo -c -o open.o open.c +mv -f .deps/open.Tpo .deps/open.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT parse.o -MD -MP -MF .deps/parse.Tpo -c -o parse.o parse.c +mv -f .deps/parse.Tpo .deps/parse.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT print.o -MD -MP -MF .deps/print.Tpo -c -o print.o print.c +mv -f .deps/print.Tpo .deps/print.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT redir.o -MD -MP -MF .deps/redir.Tpo -c -o redir.o redir.c +mv -f .deps/redir.Tpo .deps/redir.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT signal.o -MD -MP -MF .deps/signal.Tpo -c -o signal.o signal.c +mv -f .deps/signal.Tpo .deps/signal.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT mkstatval.o -MD -MP -MF .deps/mkstatval.Tpo -c -o mkstatval.o mkstatval.c +mv -f .deps/mkstatval.Tpo .deps/mkstatval.Po +gcc -Wall -g -O2 -o mkstatval mkstatval.o +./mkstatval > statval.h +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT status.o -MD -MP -MF .deps/status.Tpo -c -o status.o status.c +mv -f .deps/status.Tpo .deps/status.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT tree.o -MD -MP -MF .deps/tree.Tpo -c -o tree.o tree.c +mv -f .deps/tree.Tpo .deps/tree.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT utils.o -MD -MP -MF .deps/utils.Tpo -c -o utils.o utils.c +utils.c: In function ‘panic’: +utils.c:40:2: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Wunused-result] + write(2, PANICMSG, conststrlen(PANICMSG)); + ^ +utils.c:41:2: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Wunused-result] + write(2, s, strlen(s)); + ^ +utils.c:42:2: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Wunused-result] + write(2, "!\n", 2); + ^ +mv -f .deps/utils.Tpo .deps/utils.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT var.o -MD -MP -MF .deps/var.Tpo -c -o var.o var.c +mv -f .deps/var.Tpo .deps/var.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT wait.o -MD -MP -MF .deps/wait.Tpo -c -o wait.o wait.c +mv -f .deps/wait.Tpo .deps/wait.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT walk.o -MD -MP -MF .deps/walk.Tpo -c -o walk.o walk.c +mv -f .deps/walk.Tpo .deps/walk.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT which.o -MD -MP -MF .deps/which.Tpo -c -o which.o which.c +which.c: In function ‘which’: +which.c:112:4: warning: ignoring return value of ‘getgroups’, declared with attribute warn_unused_result [-Wunused-result] + getgroups(ngroups, gidset); + ^ +mv -f .deps/which.Tpo .deps/which.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT sigmsgs.o -MD -MP -MF .deps/sigmsgs.Tpo -c -o sigmsgs.o sigmsgs.c +mv -f .deps/sigmsgs.Tpo .deps/sigmsgs.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT edit-null.o -MD -MP -MF .deps/edit-null.Tpo -c -o edit-null.o edit-null.c +mv -f .deps/edit-null.Tpo .deps/edit-null.Po +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT system.o -MD -MP -MF .deps/system.Tpo -c -o system.o system.c +mv -f .deps/system.Tpo .deps/system.Po +gcc -Wall -g -O2 -o rc builtins.o except.o exec.o 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 parse.o print.o redir.o signal.o status.o tree.o utils.o var.o wait.o walk.o which.o sigmsgs.o edit-null.o system.o +gcc -DHAVE_CONFIG_H -I. -Wall -g -O2 -MT tripping.o -MD -MP -MF .deps/tripping.Tpo -c -o tripping.o tripping.c +mv -f .deps/tripping.Tpo .deps/tripping.Po +gcc -Wall -g -O2 -o tripping tripping.o +make[1]: Leaving directory '/mnt/data/Downloads/rc-1.7.4' diff --git a/match.c b/match.c new file mode 100644 index 0000000..6f87614 --- /dev/null +++ b/match.c @@ -0,0 +1,99 @@ +/* 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/missing b/missing new file mode 100755 index 0000000..db98974 --- /dev/null +++ b/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2013-10-28.13; # UTC + +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 0000000..55d537f --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,162 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy + +scriptversion=2009-04-28.21; # UTC + +# Original author: Noah Friedman +# Created: 1993-05-16 +# Public domain. +# +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' +IFS=" "" $nl" +errstatus=0 +dirmode= + +usage="\ +Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... + +Create each directory DIR (with mode MODE, if specified), including all +leading file name components. + +Report bugs to ." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" + exit $? + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --version) + echo "$0 $scriptversion" + exit $? + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and +# mkdir -p a/c at the same time, both will detect that a is missing, +# one will create a, then the other will try to create a and die with +# a "File exists" error. This is a problem when calling mkinstalldirs +# from a parallel make. We use --version in the probe to restrict +# ourselves to GNU mkdir, which is thread-safe. +case $dirmode in + '') + if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + else + # On NextStep and OpenStep, the 'mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because '.' already + # exists. + test -d ./-p && rmdir ./-p + test -d ./--version && rmdir ./--version + fi + ;; + *) + if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && + test ! -d ./--version; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + else + # Clean up after NextStep and OpenStep mkdir. + for d in ./-m ./-p ./--version "./$dirmode"; + do + test -d $d && rmdir $d + done + fi + ;; +esac + +for file +do + case $file in + /*) pathcomp=/ ;; + *) pathcomp= ;; + esac + oIFS=$IFS + IFS=/ + set fnord $file + shift + IFS=$oIFS + + for d + do + test "x$d" = x && continue + + pathcomp=$pathcomp$d + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr= + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp=$pathcomp/ + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/mksignal.c b/mksignal.c new file mode 100644 index 0000000..c66ad49 --- /dev/null +++ b/mksignal.c @@ -0,0 +1,239 @@ +#include +#include +#include + +#ifdef NSIG +#define NUMSIG NSIG +#else +#define NUMSIG 1 +#endif + +struct signaming { + int signo; + const char *signame; + const char *sigmsg; +}; + +static struct signaming signamings[] = { +#ifdef SIGABRT + { SIGABRT, "sigabrt", "abort"}, +#endif +#ifdef SIGALRM + { SIGALRM, "sigalrm", "alarm clock"}, +#endif +#ifdef SIGBREAK + { SIGBREAK, "sigbreak", "break"}, +#endif +#ifdef SIGBUS + { SIGBUS, "sigbus", "bus error"}, +#endif +#ifdef SIGCANCEL + { SIGCANCEL, "sigcancel", "thread cancellation"}, +#endif +#ifdef SIGCHLD + { SIGCHLD, "sigchld", "child stop or exit"}, +#endif +#ifdef SIGCLD + { SIGCLD, "sigcld", "child stop or exit"}, +#endif +#ifdef SIGCONT + { SIGCONT, "sigcont", "continue"}, +#endif +#ifdef SIGDIL + { SIGDIL, "sigdil", "dil signal"}, +#endif +#ifdef SIGEMT + { SIGEMT, "sigemt", "emt instruction"}, +#endif +#ifdef SIGFPE + { SIGFPE, "sigfpe", "floating point error"}, +#endif +#ifdef SIGFREEZE + { SIGFREEZE, "sigfreeze", "cpr freeze"}, +#endif +#ifdef SIGHUP + { SIGHUP, "sighup", "hangup"}, +#endif +#ifdef SIGILL + { SIGILL, "sigill", "illegal instruction"}, +#endif + +/* We don't want a default message for SIGINT. */ +#ifdef SIGINT + { SIGINT, "sigint", ""}, +#endif + +#ifdef SIGIO + { SIGIO, "sigio", "socket i/o possible"}, +#endif +#ifdef SIGIOT + { SIGIOT, "sigiot", "iot instruction"}, +#endif +#ifdef SIGKILL + { SIGKILL, "sigkill", "killed"}, +#endif +#ifdef SIGLOST + { SIGLOST, "siglost", "resource lost"}, +#endif +#ifdef SIGLWP + { SIGLWP, "siglwp", "thread library signal"}, +#endif + +/* By default, SIGPIPEs are silent. */ +#ifdef SIGPIPE + { SIGPIPE, "sigpipe", ""}, +#endif + +#ifdef SIGPOLL + { SIGPOLL, "sigpoll", "pollable event occurred"}, +#endif +#ifdef SIGPROF + { SIGPROF, "sigprof", "profiling timer alarm"}, +#endif +#ifdef SIGPWR + { SIGPWR, "sigpwr", "power-fail restart"}, +#endif +#ifdef SIGQUIT + { SIGQUIT, "sigquit", "quit"}, +#endif +#ifdef SIGSEGV + { SIGSEGV, "sigsegv", "segmentation violation"}, +#endif +#ifdef SIGSTKFLT + { SIGSTKFLT, "sigstkflt", "stack fault"}, +#endif +#ifdef SIGSTOP + { SIGSTOP, "sigstop", "stopped by program"}, +#endif +#ifdef SIGSYS + { SIGSYS, "sigsys", "invalid argument to system call"}, +#endif +#ifdef SIGTERM + { SIGTERM, "sigterm", "terminated"}, +#endif +#ifdef SIGTHAW + { SIGTHAW, "sigthaw", "cpr thaw"}, +#endif +#ifdef SIGTRAP + { SIGTRAP, "sigtrap", "trace trap"}, +#endif +#ifdef SIGTSTP + { SIGTSTP, "sigtstp", "stopped"}, +#endif +#ifdef SIGTTIN + { SIGTTIN, "sigttin", "background tty read"}, +#endif +#ifdef SIGTTOU + { SIGTTOU, "sigttou", "background tty write"}, +#endif +#ifdef SIGURG + { SIGURG, "sigurg", "urgent condition on i/o channel"}, +#endif +#ifdef SIGUSR1 + { SIGUSR1, "sigusr1", "user defined signal 1"}, +#endif +#ifdef SIGUSR2 + { SIGUSR2, "sigusr2", "user defined signal 2"}, +#endif +#ifdef SIGVTALRM + { SIGVTALRM, "sigvtalrm", "virtual timer alarm"}, +#endif +#ifdef SIGWAITING + { SIGWAITING, "sigwaiting", "lwps blocked"}, +#endif +#ifdef SIGWINCH + { SIGWINCH, "sigwinch", "window size change"}, +#endif +#ifdef SIGWINDOW + { SIGWINDOW, "sigwindow", "window size change"}, +#endif +#ifdef SIGXCPU + { SIGXCPU, "sigxcpu", "exceeded cpu time limit"}, +#endif +#ifdef SIGXFSZ + { SIGXFSZ, "sigxfsz", "exceeded file size limit"}, +#endif +#ifdef SIGSAK + { SIGSAK, "sigsak", "secure attention key"}, +#endif +#ifdef SIGSOUND + { SIGSOUND, "sigsound", "hft sound sequence completed"}, +#endif +#ifdef SIGRETRACT + { SIGRETRACT, "sigretract", "hft monitor mode retracted"}, +#endif +#ifdef SIGKAP + { SIGKAP, "sigkap", "keep alive poll"}, +#endif +#ifdef SIGGRANT + { SIGGRANT, "siggrant", "hft monitor mode granted"}, +#endif +#ifdef SIGALRM1 + { SIGALRM1, "sigalrm1", "m:n condition alarm"}, +#endif +#ifdef SIGVIRT + { SIGVIRT, "sigvirt", "virtual time alarm"}, +#endif +#ifdef SIGPRE + { SIGPRE, "sigpre", "programming error"}, +#endif +#ifdef SIGMIGRATE + { SIGMIGRATE, "sigmigrate", "migrate process"}, +#endif +#ifdef SIGDANGER + { SIGDANGER, "sigdanger", "system crash imminent"}, +#endif +#ifdef SIGMSG + { SIGMSG, "sigmsg", "hft input data pending"}, +#endif +#ifdef SIGINFO + { SIGINFO, "siginfo", "information request"}, +#endif + { 0, 0, 0} +}; + +static void barf(const char *msg) { + fprintf(stderr, "mksignals: %s\n", msg); + exit(1); +} + +int main(void) { + int maxsig = NUMSIG-1; + int s; + struct signaming *snp; + FILE *outf; + + for (snp = signamings; snp->signo; ++snp) + if (snp->signo > maxsig) + maxsig = snp->signo; + + outf = fopen("sigmsgs.h", "w"); + if (!outf) barf("could not open sigmsgs.h for writing"); + fprintf(outf, "typedef struct {\n"); + fprintf(outf, "\tchar *name, *msg;\n"); + fprintf(outf, "} Sigmsgs;\n"); + fprintf(outf, "extern Sigmsgs signals[];\n"); + fprintf(outf, "#define NUMOFSIGNALS %d\n", maxsig+1); + if (fclose(outf) == EOF) barf("could not fclose sigmsgs.h after writing"); + + outf = fopen("sigmsgs.c", "w"); + if (!outf) barf("could not open sigmsgs.c for writing"); + fprintf(outf, "#include \"sigmsgs.h\"\n\n"); + fprintf(outf, "Sigmsgs signals[] = {\n"); + fprintf(outf, "\t{\"\",\t\"\"},\n"); + + /* yes, we could avoid the quadratic searching with an aux array. fap. */ + for (s = 1; s <= maxsig; ++s) { + for (snp = signamings; snp->signo && snp->signo != s; ++snp) + /* */; + if (snp->signo) + fprintf(outf, "\t{\"%s\",\t\"%s\"},\n", + snp->signame, snp->sigmsg); + else + fprintf(outf, "\t{\"sigunknown%d\",\t\"unknown signal %d\"},\n", + s, s); + } + fprintf(outf, "};\n"); + if (fclose(outf) == EOF) barf("could not fclose sigmsgs.c after writing"); + return 0; +} diff --git a/mkstatval.c b/mkstatval.c new file mode 100644 index 0000000..c74ac46 --- /dev/null +++ b/mkstatval.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +int main(void) { + int cstatus, pstatus; + pid_t pid; + + for (cstatus = 0; cstatus < 2; ++cstatus) { + switch (pid = fork()) { + case -1: + perror("fork"); + return 1; + case 0: + _exit(cstatus); + default: + if (wait(&pstatus) != pid) { + perror("wait"); + return 1; + } + printf("#define STATUS%d %d\n", cstatus, pstatus); + } + } + return 0; +} diff --git a/nalloc.c b/nalloc.c new file mode 100644 index 0000000..0144b48 --- /dev/null +++ b/nalloc.c @@ -0,0 +1,139 @@ +/* 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) { + void *p; + + assert(n); + p = malloc(n); + if (p == NULL) { + uerror("malloc"); + rc_exit(1); + } + return p; +} + +extern void *erealloc(void *p, size_t n) { + if (p == NULL) /* erealloc() has POSIX realloc() semantics */ + return ealloc(n); + if ((p = realloc(p, n)) == NULL) { + uerror("realloc"); + rc_exit(1); + } + return p; +} + +extern void efree(void *p) { + if (p != NULL) + free(p); +} diff --git a/open.c b/open.c new file mode 100644 index 0000000..60555b0 --- /dev/null +++ b/open.c @@ -0,0 +1,63 @@ +/* open.c: to insulate from the rest of rc. */ + +#include "rc.h" +#include + +/* + 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); +} + +/* make a file descriptor blocking. return value indicates whether +the desciptor was previously set to non-blocking. */ + +extern bool makeblocking(int fd) { + int flags; + + if ((flags = fcntl(fd, F_GETFL)) == -1) { + uerror("fcntl"); + rc_error(NULL); + } + if (! (flags & O_NONBLOCK)) + return FALSE; + flags &= ~O_NONBLOCK; + if (fcntl(fd, F_SETFL, (long) flags) == -1) { + uerror("fcntl"); + rc_error(NULL); + } + return TRUE; +} + +/* make a file descriptor the same pgrp as us. Returns TRUE if +it changes anything. */ + +extern bool makesamepgrp(int fd) { + pid_t grp; + + grp = getpgrp(); + + if (tcgetpgrp(fd) == grp) + return FALSE; + + if (tcsetpgrp(fd, grp) < 0) { + uerror("tcsetgrp"); + return FALSE; + } + return TRUE; +} diff --git a/parse.c b/parse.c new file mode 100644 index 0000000..1275ab5 --- /dev/null +++ b/parse.c @@ -0,0 +1,1117 @@ +#ifndef lint +static char const +yyrcsid[] = "$FreeBSD: src/usr.bin/yacc/skeleton.c,v 1.28 2000/01/17 02:04:06 bde Exp $"; +#endif +#include "rc.h" +#include +#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) +static int yygrowstack(); +#define YYPREFIX "yy" +#line 8 "parse.y" + +static Node *star, *nolist; +Node *parsetree; /* not using yylval because bison declares it as an auto */ +#line 26 "parse.y" +typedef union { + struct Node *node; + struct Redir redir; + struct Pipe pipe; + struct Dup dup; + struct Word word; + char *keyword; +} YYSTYPE; +#line 31 "y.tab.c" +#define YYERRCODE 256 +#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 +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 +const char * const 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 +#if YYDEBUG +#include +#endif +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif +#define YYINITSTACKSIZE 200 +int yydebug; +int yynerrs; +int yyerrflag; +int yychar; +short *yyssp; +YYSTYPE *yyvsp; +YYSTYPE yyval; +YYSTYPE yylval; +short *yyss; +short *yysslim; +YYSTYPE *yyvs; +int yystacksize; +#line 167 "parse.y" + +void initparse() { + star = treecpy(mk(nVar, mk(nWord,"*", NULL, FALSE)), ealloc); + nolist = treecpy(mk(nVar, mk(nWord,"ifs", NULL, FALSE)), ealloc); +} + +#line 583 "y.tab.c" +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack() +{ + int newsize, i; + short *newss; + YYSTYPE *newvs; + + if ((newsize = yystacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + i = yyssp - yyss; + newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) : + (short *)malloc(newsize * sizeof *newss); + if (newss == NULL) + return -1; + yyss = newss; + yyssp = newss + i; + newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) : + (YYSTYPE *)malloc(newsize * sizeof *newvs); + if (newvs == NULL) + return -1; + yyvs = newvs; + yyvsp = newvs + i; + yystacksize = newsize; + yysslim = yyss + newsize - 1; + return 0; +} + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +#ifndef YYPARSE_PARAM +#if defined(__cplusplus) || __STDC__ +#define YYPARSE_PARAM_ARG void +#define YYPARSE_PARAM_DECL +#else /* ! ANSI-C/C++ */ +#define YYPARSE_PARAM_ARG +#define YYPARSE_PARAM_DECL +#endif /* ANSI-C/C++ */ +#else /* YYPARSE_PARAM */ +#ifndef YYPARSE_PARAM_TYPE +#define YYPARSE_PARAM_TYPE void * +#endif +#if defined(__cplusplus) || __STDC__ +#define YYPARSE_PARAM_ARG YYPARSE_PARAM_TYPE YYPARSE_PARAM +#define YYPARSE_PARAM_DECL +#else /* ! ANSI-C/C++ */ +#define YYPARSE_PARAM_ARG YYPARSE_PARAM +#define YYPARSE_PARAM_DECL YYPARSE_PARAM_TYPE YYPARSE_PARAM; +#endif /* ANSI-C/C++ */ +#endif /* ! YYPARSE_PARAM */ + +int +yyparse (YYPARSE_PARAM_ARG) + YYPARSE_PARAM_DECL +{ + register int yym, yyn, yystate; +#if YYDEBUG + register const char *yys; + + if ((yys = getenv("YYDEBUG"))) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = (-1); + + if (yyss == NULL && yygrowstack()) goto yyoverflow; + 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 >= yysslim && yygrowstack()) + { + 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 >= yysslim && yygrowstack()) + { + 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 47 "parse.y" +{ parsetree = yyvsp[-1].node; YYACCEPT; } +break; +case 2: +#line 48 "parse.y" +{ yyerrok; parsetree = NULL; YYABORT; } +break; +case 3: +#line 51 "parse.y" +{ if (!heredoc(1)) YYABORT; } +break; +case 4: +#line 52 "parse.y" +{ if (!heredoc(0)) YYABORT; } +break; +case 6: +#line 56 "parse.y" +{ yyval.node = (yyvsp[-1].node != NULL ? mk(nNowait,yyvsp[-1].node) : yyvsp[-1].node); } +break; +case 8: +#line 60 "parse.y" +{ yyval.node = (yyvsp[-1].node != NULL ? mk(nBody,yyvsp[-1].node,yyvsp[0].node) : yyvsp[0].node); } +break; +case 10: +#line 64 "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 67 "parse.y" +{ yyval.node = yyvsp[-1].node; if (!heredoc(0)) YYABORT; } +break; +case 13: +#line 69 "parse.y" +{ yyval.node = yyvsp[-1].node; } +break; +case 14: +#line 71 "parse.y" +{ yyval.node = yyvsp[-1].node; } +break; +case 15: +#line 73 "parse.y" +{ yyval.node = mk(nAssign,yyvsp[-2].node,yyvsp[0].node); } +break; +case 16: +#line 75 "parse.y" +{ yyval.node = NULL; } +break; +case 17: +#line 76 "parse.y" +{ yyval.node = mk(nEpilog,yyvsp[-1].node,yyvsp[0].node); } +break; +case 18: +#line 79 "parse.y" +{ yyval.node = mk(nDup,yyvsp[0].dup.type,yyvsp[0].dup.left,yyvsp[0].dup.right); } +break; +case 19: +#line 80 "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 83 "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 87 "parse.y" +{ yyval.node = mk(nCase, yyvsp[-1].node); } +break; +case 22: +#line 88 "parse.y" +{ yyval.node = mk(nCase, yyvsp[-1].node); } +break; +case 23: +#line 90 "parse.y" +{ yyval.node = mk(nCbody, yyvsp[0].node, NULL); } +break; +case 24: +#line 91 "parse.y" +{ yyval.node = mk(nCbody, yyvsp[-1].node, yyvsp[0].node); } +break; +case 25: +#line 92 "parse.y" +{ yyval.node = mk(nCbody, yyvsp[-1].node, yyvsp[0].node); } +break; +case 27: +#line 95 "parse.y" +{ yyval.node = mk(nElse,yyvsp[-3].node,yyvsp[0].node); } +break; +case 28: +#line 97 "parse.y" +{ yyval.node = NULL; } +break; +case 30: +#line 99 "parse.y" +{ yyval.node = mk(nBrace,yyvsp[-1].node,yyvsp[0].node); } +break; +case 31: +#line 100 "parse.y" +{ yyval.node = mk(nIf,yyvsp[-2].node,yyvsp[0].node); } +break; +case 32: +#line 101 "parse.y" +{ yyval.node = mk(nForin,yyvsp[-5].node,yyvsp[-3].node,yyvsp[0].node); } +break; +case 33: +#line 102 "parse.y" +{ yyval.node = mk(nForin,yyvsp[-3].node,star,yyvsp[0].node); } +break; +case 34: +#line 103 "parse.y" +{ yyval.node = mk(nWhile,yyvsp[-2].node,yyvsp[0].node); } +break; +case 35: +#line 104 "parse.y" +{ yyval.node = mk(nSwitch,yyvsp[-5].node,yyvsp[-1].node); } +break; +case 36: +#line 105 "parse.y" +{ yyval.node = mk(nMatch,yyvsp[-1].node,yyvsp[0].node); } +break; +case 37: +#line 106 "parse.y" +{ yyval.node = mk(nAndalso,yyvsp[-3].node,yyvsp[0].node); } +break; +case 38: +#line 107 "parse.y" +{ yyval.node = mk(nOrelse,yyvsp[-3].node,yyvsp[0].node); } +break; +case 39: +#line 108 "parse.y" +{ yyval.node = mk(nPipe,yyvsp[-2].pipe.left,yyvsp[-2].pipe.right,yyvsp[-3].node,yyvsp[0].node); } +break; +case 40: +#line 109 "parse.y" +{ yyval.node = (yyvsp[0].node != NULL ? mk(nPre,yyvsp[-1].node,yyvsp[0].node) : yyvsp[-1].node); } +break; +case 41: +#line 110 "parse.y" +{ yyval.node = (yyvsp[0].node != NULL ? mk(nPre,yyvsp[-1].node,yyvsp[0].node) : yyvsp[-1].node); } +break; +case 42: +#line 111 "parse.y" +{ yyval.node = mk(nBang,yyvsp[0].node); } +break; +case 43: +#line 112 "parse.y" +{ yyval.node = mk(nSubshell,yyvsp[0].node); } +break; +case 44: +#line 113 "parse.y" +{ yyval.node = mk(nNewfn,yyvsp[-1].node,yyvsp[0].node); } +break; +case 45: +#line 114 "parse.y" +{ yyval.node = mk(nRmfn,yyvsp[0].node); } +break; +case 49: +#line 120 "parse.y" +{ yyval.node = (yyvsp[0].node != NULL ? mk(nArgs,yyvsp[-1].node,yyvsp[0].node) : yyvsp[-1].node); } +break; +case 50: +#line 121 "parse.y" +{ yyval.node = mk(nArgs,yyvsp[-1].node,yyvsp[0].node); } +break; +case 52: +#line 124 "parse.y" +{ yyval.node = mk(nConcat,yyvsp[-2].node,yyvsp[0].node); } +break; +case 54: +#line 127 "parse.y" +{ yyval.node = mk(nWord, yyvsp[0].keyword, NULL, FALSE); } +break; +case 56: +#line 130 "parse.y" +{ yyval.node = mk(nConcat,yyvsp[-2].node,yyvsp[0].node); } +break; +case 57: +#line 132 "parse.y" +{ yyval.node = mk(nVar,yyvsp[0].node); } +break; +case 58: +#line 133 "parse.y" +{ yyval.node = mk(nVarsub,yyvsp[-3].node,yyvsp[-1].node); } +break; +case 59: +#line 134 "parse.y" +{ yyval.node = mk(nCount,yyvsp[0].node); } +break; +case 60: +#line 135 "parse.y" +{ yyval.node = mk(nFlat, yyvsp[0].node); } +break; +case 61: +#line 136 "parse.y" +{ yyval.node = mk(nBackq,nolist,yyvsp[0].node); } +break; +case 62: +#line 137 "parse.y" +{ yyval.node = mk(nBackq,nolist,yyvsp[0].node); } +break; +case 63: +#line 138 "parse.y" +{ yyval.node = mk(nBackq,yyvsp[-1].node,yyvsp[0].node); } +break; +case 64: +#line 139 "parse.y" +{ yyval.node = mk(nBackq,yyvsp[-1].node,yyvsp[0].node); } +break; +case 65: +#line 140 "parse.y" +{ yyval.node = yyvsp[-1].node; } +break; +case 66: +#line 141 "parse.y" +{ yyval.node = mk(nNmpipe,yyvsp[-1].redir.type,yyvsp[-1].redir.fd,yyvsp[0].node); } +break; +case 67: +#line 142 "parse.y" +{ yyval.node = mk(nWord, yyvsp[0].word.w, yyvsp[0].word.m, yyvsp[0].word.q); } +break; +case 68: +#line 144 "parse.y" +{ yyval.keyword = "for"; } +break; +case 69: +#line 145 "parse.y" +{ yyval.keyword = "in"; } +break; +case 70: +#line 146 "parse.y" +{ yyval.keyword = "while"; } +break; +case 71: +#line 147 "parse.y" +{ yyval.keyword = "if"; } +break; +case 72: +#line 148 "parse.y" +{ yyval.keyword = "switch"; } +break; +case 73: +#line 149 "parse.y" +{ yyval.keyword = "fn"; } +break; +case 74: +#line 150 "parse.y" +{ yyval.keyword = "else"; } +break; +case 75: +#line 151 "parse.y" +{ yyval.keyword = "case"; } +break; +case 76: +#line 152 "parse.y" +{ yyval.keyword = "~"; } +break; +case 77: +#line 153 "parse.y" +{ yyval.keyword = "!"; } +break; +case 78: +#line 154 "parse.y" +{ yyval.keyword = "@"; } +break; +case 79: +#line 156 "parse.y" +{ yyval.node = NULL; } +break; +case 80: +#line 157 "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 159 "parse.y" +{ yyval.node = NULL; } +break; +case 83: +#line 161 "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 1062 "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 >= yysslim && yygrowstack()) + { + goto yyoverflow; + } + *++yyssp = yystate; + *++yyvsp = yyval; + goto yyloop; +yyoverflow: + yyerror("yacc stack overflow"); +yyabort: + return (1); +yyaccept: + return (0); +} diff --git a/parse.h b/parse.h new file mode 100644 index 0000000..c193710 --- /dev/null +++ b/parse.h @@ -0,0 +1,37 @@ +#ifndef YYERRCODE +#define YYERRCODE 256 +#endif + +#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; diff --git a/parse.y b/parse.y new file mode 100644 index 0000000..8be65bb --- /dev/null +++ b/parse.y @@ -0,0 +1,174 @@ +/* parse.y */ + +/* + * Adapted from rc grammar, v10 manuals, volume 2. + */ + +%{ +/* note that this actually needs to appear before any system header + files are included; byacc likes to throw in first. */ +#include "rc.h" + +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, FALSE); } + +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 { $$ = mk(nWord, $1.w, $1.m, $1.q); } + +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, FALSE)), ealloc); + nolist = treecpy(mk(nVar, mk(nWord,"ifs", NULL, FALSE)), ealloc); +} + diff --git a/print.c b/print.c new file mode 100644 index 0000000..2a30b5c --- /dev/null +++ b/print.c @@ -0,0 +1,381 @@ +/* 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 ignore) { \ + format->flags |= flag; \ + return TRUE; \ +} + +Flag(uconv, FMT_unsigned) +Flag(rc_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 ignore) { + 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 ignore) { + 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 *rc_utoa(unsigned long u, char *t, unsigned int radix, const char *digit) { + if (u >= radix) { + t = rc_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 + 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 = rc_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 ignore) { + fmtputc(format, va_arg(format->args, int)); + return FALSE; +} + +static bool dconv(Format *format, int ignore) { + intconv(format, 10, 0, ""); + return FALSE; +} + +static bool oconv(Format *format, int ignore) { + intconv(format, 8, 0, "0"); + return FALSE; +} + +static bool xconv(Format *format, int ignore) { + intconv(format, 16, 0, "0x"); + return FALSE; +} + +static bool pctconv(Format *format, int ignore) { + fmtputc(format, '%'); + return FALSE; +} + +static bool badconv(Format *ignore, int ign0re) { + 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['l'] = rc_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); + va_copy(saveargs, format->args); + va_copy(format->args, ap); + n += printfmt(format, fmt); + va_end(format->args); + va_copy(format->args, saveargs); + + return n + format->flushed; +} + +static void fprint_flush(Format *format, size_t ignore) { + 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); + va_copy(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; + size_t used = format->buf - format->bufbegin; + + len = (len >= more) + ? len * 2 + : ((len + more) + PRINT_ALLOCSIZE) &~ (PRINT_ALLOCSIZE - 1); + if (format->u.n) + buf = erealloc(format->bufbegin, len); + else { + buf = nalloc(len); + memcpy(buf, format->bufbegin, used); + } + format->buf = buf + used; + 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); + va_copy(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); + va_copy(format.args, ap); + result = memprint(&format, fmt, nalloc(PRINT_ALLOCSIZE), PRINT_ALLOCSIZE); + va_end(format.args); + return result; +} diff --git a/proto.h b/proto.h new file mode 100644 index 0000000..4a2d74a --- /dev/null +++ b/proto.h @@ -0,0 +1,100 @@ +/* + The idea of this file is to include prototypes for all external + functions that rc uses, either by including the appropriate header + file, or---for older systems---declaring the functions directly. +*/ + +#if HAVE_SYS_TYPES_H +#include +#endif + +#include + +#if HAVE_QUAD_T +typedef quad_t align_t; +#else +typedef long align_t; +#endif + +/* + We need . If you really need to build rc on a system which + doesn't have it, please contact the maintainer. +*/ + +#include + +/* C 99 specifies a va_copy() macro to be used for copying +objects of type va_list. If this doesn't exist, hope that simple +assignment works. */ +#ifndef va_copy +#define va_copy(x,y) (x)=(y) +#endif + +#if STDC_HEADERS + +#include +#include + +#else /* STDC_HEADERS */ + +/* 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); + +/* fake stdlib.h */ +extern void exit(int); +extern void free(void *); +extern void *malloc(size_t); +extern void *realloc(void *, size_t); +extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); + +#endif /* STDC_HEADERS */ + +#if HAVE_STRERROR +/* Smells like POSIX. */ +#else +/* Assume BSD-style sys_errlist[]. */ +extern int sys_nerr; +extern char *sys_errlist[]; +#define strerror(x) ((0 <= (x)) && (errno < (x)) ? sys_errlist[x] : (char *)0) +#endif + +#if HAVE_UNISTD_H +#include +#endif + +#if HAVE_SETPGRP + +#if SETPGRP_VOID +/* Smells like POSIX: should all be ok. */ +#else +/* Old BSD: fake it. */ +#define setpgid(pid, pgrp) setpgrp(pid, pgrp) +#include +#define tcgetpgrp(fd) ioctl((fd), TIOCGPGRP) +#define tcsetpgrp(fd, pgrp) ioctl((fd), TIOCSPGRP, &(pgrp)) +#endif + +#else /* HAVE_SETPGRP */ + +/* Nothing doing. */ +#define setpgid() +#define tcgetpgrp() +#define tcsetpgrp() + +#endif /*HAVE_SETPGRP */ + + +/* 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 new file mode 100644 index 0000000..4fecb87 --- /dev/null +++ b/rc.1 @@ -0,0 +1,2163 @@ +.\" 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 inter-sentence spacing, but only if +.\" the sentences end at the end of a line. Explicit spaces, if given, +.\" are apparently honored and the normal inter-sentence spacing is +.\" suppressed. +.\" +.\" DaviD W. Sanderson +.\"------- +.\" Dd distance to space vertically before a "display" +.\" These are what n/troff use for inter-paragraph 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 "2015-05-13" +.SH NAME +rc \- shell +.SH SYNOPSIS +.B rc +.RB [ \-deiIlnopsvx ] +.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 \-c +If +.Cr \-c +is present, commands are executed from the immediately following +argument. +Any further arguments to +.I rc +are placed in +.Cr $* . +Thus: +.Ds +.Cr "rc -c 'echo $*' 1 2 3" +.De +.TP +\& +prints out +.Ds +.Cr "1 2 3" +.De +.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 flag is only useful for debugging +.IR rc . +.TP +.Cr \-e +If the +.Cr \-e +flag 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 +flag 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 +.Cr SIGINT . +.TP +.Cr \-I +If the +.Cr \-I +flag is present, or if the input to +.I rc +is not from a terminal, then +.I rc +will not be in interactive mode. +No prompts will be printed, and +.Cr SIGINT +will cause +.I rc +to exit. +.TP +.Cr \-l +If the +.Cr \-l +flag 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 run commands from +.Cr $home/.rcrc , +if this file exists, before reading any other input. +.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 +flag, +.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 \-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 \-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 the presence of this flag does +.I not +mean that it is safe to run setuid +.I rc +scripts; the usual caveats about the setuid bit still apply.) +.TP +.Cr \-s +This flag causes +.I rc +to read from standard input. +Any arguments are placed in +.Cr $* . +.TP +.Cr \-v +This flag causes +.I rc +to echo its input +to standard error as it is read. +.TP +.Cr \-x +This flag causes +.I rc +to print every command on standard error before it is executed. +It can be useful for debugging +.I rc +scripts. +.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 +.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 +Redirections can appear anywhere in the line: the word +following the redirection symbol is the filename and must be +quoted if it contains spaces or other special characters. +These are all equivalent. +.Ds +.Cr "echo 1 2 3 > foo" +.Cr "> foo echo 1 2 3" +.Cr "echo 1 2 > foo 3" +.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 +As in +.IR sh , +redirections are processed from left to right. +Thus this sequence +.Ds +.Cr "command >[2=1] > file" +.De +.PP +is usually a mistake. +It first duplicates standard error to standard +output; then redirects standard output to a file, leaving standard error +wherever standard output originally was. +.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 +Note that no spaces may appear in these constructs: +.Ds +.Cr "command > [2] file" +.De +.PP +would send the output of the command to a file named +.Cr [2] , +with the intended filename appearing in the command's argument list. +.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 +Subsequent lines form the standard input of +the command, till a line containing just the +marker, in this case +.Cr eof-marker , +is encountered. +.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. +Their 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 +As with file redirections, no spaces may occur in the construct specifying +numbered file descriptors. +.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. +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, some 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 $* . +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 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. +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 a variable is a valid operation, but it +does not remove its definition. +.Ds +.Cr "null = '' empty = () echo $#null $#empty" +.De +.PP +produces the output +.Ds +.Cr "1 0" +.De +.SS "List Concatenation" +Two lists may be joined by the concatenation operator +.Rc ( ^ ). +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, at least 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 +.PP +A single word is a list of length one, so +.Ds +.Cr "echo foo^bar" +.De +.PP +produces the output +.Ds +.Cr foobar +.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 +The special variable +.Cr * +may also be assigned to using this notation; +.I rc +has no +.B set +builtin. +.PP +Any non-empty sequence of characters, except a sequence including only +digits, may be used as a variable name. +Any character except +.Cr = +may be used, but special characters must be quoted. +All user-defined variables are exported into the environment. +.PP +The value of a variable is referenced with the dollar +.Rc ( $ ) +operator: +.Ds +.Ci $ var +.De +.PP +Any variable which has not been assigned a value returns the null list, +.Cr "()" , +when referenced. +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 opening parenthesis must immediately follow the variable name. +The list of subscripts need not be in order or even unique. +Thus, +.Ds +.Cr "a=(one two three)" +.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 the dollar-caret +.Rc ( $^ ) +operator: +.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 +.PP +For compability with the Plan 9 rc, +.Ds +.Cr $"var +.De +.PP +is accepted as a synonym for dollar-caret. +.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. +In the following list, ``default'' indicates that +.I rc +gives the variable a default value on startup; ``no-export'' indicates +that the variable is never exported; and ``read-only'' indicates that +an attempt to set the variable will silently have no effect. +.PP +Also, ``alias'' means that the variable is aliased to the same name in +capitals. +For example, an assignment to +.Cr $cdpath +causes an automatic assignment to +.Cr $CDPATH , +and vice-versa. +If +.Cr $CDPATH +is set when +.I rc +is started, its value is imported into +.Cr $cdpath . +.Cr $cdpath +and +.Cr $path +are +.I rc +lists; +.Cr $CDPATH +and +.Cr $PATH +are colon-separated lists. +Only the names spelt in capitals are exported into the environment. +.TP +.Cr * " (no-export)" +The argument list of +.IR rc . +.Cr "$1, $2," +etc. are the same as +.Cr $*(1) , +.Cr $*(2) , +etc. +.TP +.Cr 0 " (default no-export)" +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. +.Cr $0 +is not an element of +.Cr $* , +and is never treated as one. +.TP +.Cr apid " (no-export)" +The process ID of the last process started in the background. +.TP +.Cr apids " (no-export read-only)" +A list whose elements are the process IDs of all background processes +which are still alive, or which have died and have not been waited for +yet. +.TP +.Cr bqstatus " (no-export)" +The exit status of the +.I rc +forked to execute the most recent backquote substitution. Note that, unlike +.Cr $status , +.Cr $bqstatus +is always a single element list (see +.BR "EXIT STATUS" +below). For example: +.Ds +.Cr "echo foo |grep bar; whatis status" +.De +.TP +\& +prints +.Ds +.Cr "status=(0 1)" +.De +.TP +\& +whereas +.Ds +.Cr "x=`{echo foo |grep bar}; whatis bqstatus" +.De +.TP +\& +prints +.Ds +.Cr "bqstatus=1" +.De +.TP +.Cr cdpath " (alias)" +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. +.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 " (alias)" +The default directory for the builtin +.B cd +command, and 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. +.TP +.Cr ifs " (default)" +The internal field separator, used for splitting up the output of +backquote commands for digestion as a list. On startup, +.I rc +assigns the list containing the characters space, tab, and newline to +.Cr $ifs . +.TP +.Cr path " (alias)" +This is a list of directories to search in for commands. +The empty string stands for the current directory. +If neither +.Cr $PATH +nor +.Cr $path +is set at startup time, +.Cr $path +assumes a default value suitable for your system. +This is typically +.Cr "(/usr/local/bin /usr/bin /usr/ucb /bin .)" +.TP +.Cr pid " (default no-export)" +On startup, +.Cr $pid +is initialized to the numeric process ID of the currently running +.IR rc . +.TP +.Cr prompt " (default)" +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 defined, then it gets executed every time +.I rc +is about to print +.Cr "$prompt(1)" . +.TP +.Cr status " (no-export read-only)" +The exit status of the last command. +If the command exited with a numeric value, that number is the status. +If the command 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)" . +.TP +.Cr version " (default)" +On startup, the first element of this list variable is initialized to +a string which identifies this version of +.IR rc . +The second element is initialized to a string which can be found by +.IR ident (1) +and the +.I what +command of +.IR sccs (1). +.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 } # WRONG" +.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 +.Cr 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. +For example: +.Ds +.Cr "fn ls { builtin ls -FC $* }" +.De +.TP +\& +is a reasonable way to pass a default set of arguments to +.Cr ls (1), +whereas +.Ds +.Cr "fn ls { ls -FC $* } # WRONG" +.De +.TP +\& +is a non-terminating recursion, which will cause +.Cr rc +to exhaust its stack space and (eventually) terminate if it is executed. +.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 resource 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 , +.BR coredumpsize , +.BR memoryuse , +and, where supported, +.BR descriptors , +.BR memoryuse , +.BR memoryrss , +.BR maxproc , +.BR memorylocked , +and +.BR filelocks . +For example: +.Ds +.Cr "limit coredumpsize 0" +.De +.TP +\& +disables core dumps. +To set a soft limit equal to the hard limit: +.Ds +.Cr "limit `{limit -h datasize}" +.De +.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 valid exit status, or a list of them. +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. +.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 process with the specified +.IR pid , +which must have been started by +.IR rc , +to exit. +If no +.I pid +is specified, +.I rc +waits for all its child processes to exit. +.TP +\fBwhatis \fR[\fB\-b\fR] \fR[\fB\-f\fR] \fR[\fB\-p\fR] \fR[\fB\-s\fR] \fR[\fB\-v\fR] [\fB\-\|\-\fR] [\fIname ...\fR] +Prints a definition of the named objects. +For builtins, +.Cr builtin +.I foo +is printed; for functions, including signal handlers, their definitions +are printed; for executable files, path names are printed; and for +variables, their values are printed. +The flags restrict output to builtins, functions, executable +programs, signal handlers, and variables, respectively. +If no +.IR name s +are specified, +.I rc +lists all objects of that type. +(This is not permitted for +.Cr \-p .) +Without arguments, +.Cr whatis +is equivalent to +.Cr "whatis -fv" , +and prints the values of all shell variables and functions. +.TP +\& +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 flags. +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 EXAMPLES +The +.B shift +builtin only shifts +.Cr "$*" . +This function can shift any variable (except +.Cr "$lshift" ). +.Ds +.Cr "fn lshift { lshift=$*; *=$$1; shift $lshift(2); $lshift(1)=$* }" +.De +.PP +With this definition in place, +.Ds +.Cr "walrus = (shoes ships sealing-wax cabbages kings)" +.Cr "lshift walrus 3" +.Cr "whatis walrus" +.De +.PP +prints +.Ds +.Cr "walrus=(cabbages kings)" +.De +.PP +The +.Cr $^var +operator flattens a list by separating each element with a space. +This function allows the separator to be an arbitrary string. +.Ds +.Cr "fn lflat {" +.Cr " lflat=$*; *=$$1" +.Cr " while () {" +.Cr " echo -n $1; shift" +.Cr " ~ $#* 0 && break" +.Cr " echo -n $lflat(2)" +.Cr "}" +.De +.PP +With this definition in place, +.Ds +.Cr "hops=(uunet mcvax ukc tlg)" +.Cr "lflat hops !" +.De +.PP +prints (with no final newline) +.Ds +.Cr uunet!mcvax!ukc!tlg +.De +.SH "EXIT STATUS" +The exit status of +.I rc +is normally the same as that of the last command executed. +If the +last command was a pipeline, +.I rc +exits +.Cr 0 +if every command in the pipeline did; otherwise it exits +.Cr 1 . +.PP +.I rc +can be made to exit with a particular status using the +.B exit +builtin. +.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 was copied from the +.I rc +that Tom Duff wrote at Bell Labs. +.SH BUGS +There is a compile-time limit on the number of +.Cr ; +separated commands in a line: usually 500. +This is sometimes a problem for automatically generated scripts: +substituting the newline character for +.Cr ; +avoids the limit. +.PP +On modern systems that support +.Cr /dev/fd +or +.Cr /proc/self/fd , +.Cr <{foo} +style redirection is implemented that way. +However, on older systems it is implemented with named pipes. +Allegedly, 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. +(The current maintainer has never seen this, but then he +doesn't use systems which lack +.Cr /dev/fd +any more. +If anybody can reproduce this problem, please let the maintainer know.) +.PP +The +.B echo +command does not need to be a builtin. It is one for reasons of +performance and portability (of +.I rc +scripts). +.PP +There should be a way to avoid exporting a variable. +.PP +Extra parentheses around a +.Cr ~ +expression or a +.Cr ! +expression are a syntax error. +Thus, this code is illegal. +.Ds +.Cr "while ((~ $1 -*) && (! ~ $1 --)) { ..." +.De +.TP +The redundant inner parentheses must be omitted. +.PP +Variable subscripting cannot be used in here documents. +.PP +The +.Cr limit +builtin silently ignores extra arguments. +.PP +Backquote substitution never produces empty strings - multiple +consecutive occurrences of the separator are treated the same as a +single occurrence. +.Ds +.Cr "ifs=! { x = `{echo -n a!!b}; whatis x }" +.Cr "x=(a b) # NOT x=(a '' b)" +.PP +Bug reports should be mailed to +.Cr "" . +.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 Tenth Edition +.I rc +does not have the +.B else +keyword. +Instead, +.B if +is optionally followed by +an +.B "if not" +clause which is executed +if the preceding +.B if +test does not succeed. +.PP +Backquotes are slightly different in Tenth Edition +.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 +For +.Cr . +.IR file , +the Tenth Edition +.IR rc +searches +.Cr $path +for +.IR file . +This +.I rc +does not, since it is not considered useful. +.PP +The list flattening operator, +.Cr $^foo , +is spelt +.Cr "$""foo" +in those versions of the Bell Labs +.IR rc +which have it. +.PP +The following are all new with this version of +.IR rc : +The +.Cr \-n +flag, +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 +.Cr bqstatus +and +.Cr version +variables, +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, +Tenth Edition, +Volume 2. (Saunders College Publishing) +.PP +.Cr http://static.tobold.org/rc/rc-duff.html , +an updated version of the above paper. +.PP +.IR history (1) diff --git a/rc.h b/rc.h new file mode 100644 index 0000000..2912e60 --- /dev/null +++ b/rc.h @@ -0,0 +1,394 @@ +#undef NDEBUG +#include "config.h" +#include "proto.h" + +#include + +#define RC "rc: " + +/* datatypes */ + +#define ENV_SEP '\001' +#define ENV_ESC '\002' + +/* braindamaged IBM header files #define true and false */ +#undef FALSE +#undef TRUE + +typedef void builtin_t(char **); +typedef struct Block Block; +typedef struct Dup Dup; +typedef struct Estack Estack; +typedef struct rc_Function rc_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, + 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 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; + bool q; +}; + +struct Rq { + Node *r; + struct Rq *n; +}; + +struct rc_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 maintenance 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_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) ((rc_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 Rq *redirq; +extern bool dashdee, dashee, dashvee, dashex, 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); + +#if HASH_BANG +#define rc_execve execve +#else +/* execve.c */ +extern int my_execve(char *, char **, char **); +#endif + +/* footobar.c */ +extern char **list2array(List *, bool); +extern char *get_name(char *); +extern List *parse_var(char *); +extern Node *parse_fn(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 rc_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 set_exportable(char *, bool); +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; + +/* lex.c */ +extern bool quotep(char *, bool); +extern int yylex(void); +extern void inityy(void); +extern void yyerror(const char *); +extern void scanerror(char *); +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); +extern bool makeblocking(int); +extern bool makesamepgrp(int); + +/* 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);\ +} + +/* parse.c (parse.y) */ +extern Node *parsetree; +extern int yyparse(void); +extern void initparse(void); + +/* readline */ +extern volatile sig_atomic_t rl_active; +extern struct Jbwrap rl_buf; + +/* 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 (*sys_signal(int, void (*)(int)))(int); +extern void (*sighandlers[])(int); + + +/* 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); + + +/* system.c or system-bsd.c */ +extern void writeall(int, char *, size_t); + +#if HAVE_RESTARTABLE_SYSCALLS +extern int rc_read(int, char *, size_t); +extern pid_t rc_wait(int *); +extern Jbwrap slowbuf; +extern volatile sig_atomic_t slow; + +#else /* HAVE_RESTARTABLE_SYSCALLS */ + +#define rc_read read +#define rc_wait wait +#endif /* HAVE_RESTARTABLE_SYSCALLS */ + + +/* 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 mvfd(int, int); +extern int starstrcmp(const void *, const void *); +extern void pr_error(char *, int); +extern void panic(char *); +extern void uerror(char *); + +/* 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 new file mode 100644 index 0000000..b582341 --- /dev/null +++ b/redir.c @@ -0,0 +1,77 @@ +/* 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 new file mode 100644 index 0000000..a3dbe8d --- /dev/null +++ b/rlimit.h @@ -0,0 +1,53 @@ +/* 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 + +struct Suffix { + const struct Suffix *next; + long amount; + char *name; +}; + +struct Limit { + char *name; + int flag; + const struct Suffix *suffix; +}; +#endif /* HAVE_SETRLIMIT */ diff --git a/signal.c b/signal.c new file mode 100644 index 0000000..037be1d --- /dev/null +++ b/signal.c @@ -0,0 +1,106 @@ +/* signal.c: a Hugh-approved signal handler. */ + +#include "rc.h" + +#include +#include + +#include "sigmsgs.h" +#include "jbwrap.h" + +#if HAVE_SIGACTION +void (*sys_signal(int signum, void (*handler)(int)))(int) { + struct sigaction new, old; + + new.sa_handler = handler; + new.sa_flags = 0; /* clear SA_RESTART */ + sigfillset(&new.sa_mask); + sigaction(signum, &new, &old); + return old.sa_handler; +} +#else +void (*sys_signal(int signum, void (*handler)(int)))(int) { + return signal(signum, handler); +} +#endif + +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; + } + sys_signal(s, catcher); + +#if HAVE_RESTARTABLE_SYSCALLS + if (slow) { + siglongjmp(slowbuf.j, s); + } +#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]; + sighandlers[s] = h; + if (h == SIG_DFL || h == SIG_IGN) + sys_signal(s, h); + else + sys_signal(s, catcher); + return old; +} + +extern void initsignal() { + void (*h)(int); + int i; + +#if HAVE_SYSV_SIGCLD + /* Ensure that SIGCLD is not SIG_IGN. Solaris's rshd does this. :-( */ + h = sys_signal(SIGCLD, SIG_IGN); + if (h != SIG_IGN && h != SIG_ERR) + sys_signal(SIGCLD, h); + else + sys_signal(SIGCLD, SIG_DFL); +#endif + + for (i = 1; i < NUMOFSIGNALS; i++) { +#ifdef SIGKILL + if (i == SIGKILL) continue; +#endif +#ifdef SIGSTOP + if (i == SIGSTOP) continue; +#endif + h = sys_signal(i, SIG_IGN); + if (h != SIG_IGN && h != SIG_ERR) + sys_signal(i, h); + sighandlers[i] = h; + } +} diff --git a/stat.h b/stat.h new file mode 100644 index 0000000..5f87a69 --- /dev/null +++ b/stat.h @@ -0,0 +1,6 @@ +#include + +#if HAVE_LSTAT +#else +#define lstat(name, buf) (stat((name), (buf))) +#endif diff --git a/status.c b/status.c new file mode 100644 index 0000000..5b37aa5 --- /dev/null +++ b/status.c @@ -0,0 +1,151 @@ +/* status.c: functions for printing fancy status messages in rc */ + +#include "rc.h" +#include "sigmsgs.h" +#include "statval.h" +#include "wait.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]; + if (WIFSIGNALED(s)) + return 1; + return WEXITSTATUS(s); +} + +extern void set(bool code) { + setstatus(-1, code ? STATUS0 : STATUS1); +} + +/* 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 (WIFSIGNALED(i)) { + int t = WTERMSIG(i); + char *msg = ((t > 0) && (t < NUMOFSIGNALS) ? signals[WTERMSIG(i)].msg : ""); + if (pid != -1) + fprint(2, "%ld: ", (long)pid); + if (myWIFDUMPED(i)) { + 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) { + if (WIFSIGNALED(s)) { + int t = WTERMSIG(s); + const char *core = myWIFDUMPED(s) ? "+core" : ""; + if ((t > 0) && (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", WEXITSTATUS(s)); +} + +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/system-bsd.c b/system-bsd.c new file mode 100644 index 0000000..f081e1a --- /dev/null +++ b/system-bsd.c @@ -0,0 +1,61 @@ +/* signal-safe read and write (for BSD slow devices). writeall() also +allows partial writes */ + +#include "rc.h" + +#include + +#include "jbwrap.h" +#include "wait.h" + +Jbwrap slowbuf; +volatile sig_atomic_t slow; + +static char *safe_buf; +static size_t safe_remain; + +extern void writeall(int fd, char *buf, size_t remain) { + int i; + + safe_buf = buf; + safe_remain = remain; + for (i = 0; safe_remain > 0; buf += i, safe_remain -= i) { + if (sigsetjmp(slowbuf.j, 1) == 0) { + slow = TRUE; + if ((i = write(fd, safe_buf, safe_remain)) <= 0) + break; /* abort silently on errors in write() */ + } else + break; + } + slow = FALSE; + sigchk(); +} + +extern int rc_read(int fd, char *buf, size_t n) { + ssize_t r; + + if (sigsetjmp(slowbuf.j, 1) == 0) { + slow = TRUE; + r = read(fd, buf, n); + } else { + errno = EINTR; + r = -1; + } + slow = FALSE; + + return r; +} + +static int r = -1; +extern pid_t rc_wait(int *stat) { + if (sigsetjmp(slowbuf.j, 1) == 0) { + slow = TRUE; + r = wait(stat); + } else { + errno = EINTR; + r = -1; + } + slow = FALSE; + + return r; +} diff --git a/system.c b/system.c new file mode 100644 index 0000000..edc0e0f --- /dev/null +++ b/system.c @@ -0,0 +1,10 @@ +#include "rc.h" + +extern void writeall(int fd, char *buf, size_t remain) { + int i; + + for (i = 0; remain > 0; buf += i, remain -= i) + if ((i = write(fd, buf, remain)) <= 0) + break; /* abort silently on errors in write() */ + sigchk(); +} diff --git a/tree.c b/tree.c new file mode 100644 index 0000000..60b42e3 --- /dev/null +++ b/tree.c @@ -0,0 +1,174 @@ +/* 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: + n = nalloc(offsetof(Node, u[3])); + n->u[0].s = va_arg(ap, char *); + n->u[1].s = va_arg(ap, char *); + n->u[2].i = va_arg(ap, int); + 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: + n = (*alloc)(offsetof(Node, u[3])); + 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; + n->u[2].i = s->u[2].i; + 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: + 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 new file mode 100644 index 0000000..c811347 --- /dev/null +++ b/trip.rc @@ -0,0 +1,599 @@ +# trip.rc -- take a tour of rc +# Invoke as "path-to-new-rc < trip.rc" + +rc=$0 +echo tripping $rc $version + +tmpdir='' +fn fail { + echo >[1=2] trip took a wrong turn: $* + rm -rf $tmpdir + fn sigexit + exit 1 +} +fn expect { + echo >[1=2] -n expect $^*^': ' +} +fn submatch { + if (!~ $#* 3) + fail incorrect invocation of submatch + prompt=$nl if (!~ `` $nl {$rc -ic $1>[2=1]} $2) + fail $3 +} +fn sigexit sigint sigquit sigsegv +fn sigexit { + echo trip complete +} +tmpdir=`{ mktemp -d -t rc-trip.XXXXXX } +tmp=$tmpdir/tmp +nl=' +' + +# +# rc -c +# + +if ($rc -c >[2]/dev/null) fail 'rc -c didn''t report a bad exit status' +x=`{$rc -c 'echo $0 $2 $#*' a b c d e f} +if (false) { # WARNING: this differs from sh + if (!~ $x(1) a) fail rc -c reports '$0' incorrectly as $x(1) + if (!~ $x(2) c) fail rc -c reports '$2' incorrectly as $x(2) + if (!~ $x(3) 5) fail rc -c reports '$#' incorrectly as $x(3) +} else { + if (!~ $x(1) $rc) fail rc -c reports '$0' incorrectly as $x(1) + if (!~ $x(2) b) fail rc -c reports '$2' incorrectly as $x(2) + if (!~ $x(3) 6) fail rc -c reports '$#' incorrectly as $x(3) +} + +# +# umask +# + +umask 0 +> $tmp +x=`{ls -l $tmp} +if (!~ $x(1) -rw-rw-rw-*) fail umask 0 produced incorrect result: $x(1) +rm -f $tmp +umask 027 +> $tmp +y=`{ls -l $tmp} +if (!~ $y(1) -rw-r-----*) fail umask 027 produced incorrect file: $y(1) +rm -f $tmp +if (!~ `umask 027) fail umask reported bad value: `umask + +submatch 'umask bad' 'bad umask' 'bad umask' +submatch 'umask -027' 'bad umask' 'bad umask' +submatch 'umask 999999' 'bad umask' 'bad umask' +submatch 'umask hi there' 'rc: too many arguments to umask' 'umask arg count' + +if (!~ `umask 027) fail bad umask changed umask value to `umask + +# +# redirections +# + +fn bytes { for (i) x=`{wc -c $i} echo $x(1) } +echo foo > foo > bar +if (!~ `{bytes foo} 0) fail double redirection created non-empty empty file +if (!~ `{bytes bar} 4) fail double redirection created wrong sized file: `{bytes bar} +rm -f foo bar +echo -n >1 >[2]2 >[1=2] foo +x = `` '' {cat 1} +if (!~ $#x 0) fail dup created non-empty empty file: `` '' {cat 1} +if (!~ `` '' {cat 2} foo) fail dup put wrong contents in file : `` '' {cat 2} +rm -f 1 2 + +expect error from cat, closing stdin +cat >[0=] + +submatch 'cat>(1 2 3)' 'rc: multi-word filename in redirection' 'redirection error' +submatch 'cat>()' 'rc: null filename in redirection' 'redirection error' + +# +# blow the input stack +# + +if (!~ hi `{ +eval eval eval eval eval eval eval eval eval eval eval eval eval \ +eval eval eval eval eval eval eval eval eval eval eval eval eval \ +eval eval eval eval eval eval eval eval eval eval eval eval eval \ +eval eval eval eval eval eval eval eval eval eval eval eval eval \ +eval eval eval eval eval eval eval eval eval eval eval eval eval \ +eval eval eval eval eval eval eval eval eval eval eval eval eval \ +eval eval eval eval eval eval eval eval eval eval eval eval eval \ +eval eval eval eval eval eval eval eval eval eval eval eval eval \ +eval eval eval eval eval eval eval eval eval eval eval eval eval \ +eval eval eval eval eval eval eval eval eval eval eval eval eval \ +eval eval eval eval eval eval eval eval eval eval eval echo hi +}) + fail huge eval + +# +# heredocs and herestrings +# + +bigfile=$tmpdir/big.$pid +od $rc | sed 5000q > $bigfile +abc=(this is a) +x=() +result='this is a heredoc +this is an heredoc +' +if (!~ `` '' {<<[5] EOF cat <[0=5]} $result) fail unquoted heredoc +$abc heredoc$x +$abc^n $x^here$x^doc +EOF +{if (!~ `` $nl cat ' ') fail quoted heredoc} << ' ' + + + +<<<[9] ``''{cat $bigfile} \ +{ + if(!~ ``''{cat <[0=9]}``'' cat)fail large herestrings +} < \ +$bigfile + +rm -f $bigfile + +if (!~ `{cat< $tmp +$rc $tmp +rm -f $tmp + +echo here_is_a_really_long_word.It_has_got_to_be_longer_than_1000_characters_for_the_lexical_analyzers_buffer_to_overflow_but_that_should_not_be_too_difficult_to_do.Let_me_start_writing_some_Lewis_Carroll.Twas_brillig_and_the_slithy_toves,Did_gyre_and_gimble_in_the_wabe.All_mimsy_were_the_borogoves,And_the_mome-raths_outgrabe.Beware_the_Jabberwock_my_son,The_jaws_that_bite,the_claws_that_catch.Beware_the_Jub-jub_bird,and_shun_The_frumious_Bandersnatch.He_took_his_vorpal_sword_in_hand,Long_time_the_manxome_foe_he_sought,So_rested_he_by_the_Tumtum_tree,And_stood_awhile_in_thought.And_as_in_uffish_thought_he_stood,The_Jabberwock,with_eyes_of_flame,Came_whiffling_through_the_tulgey_wood,And_burbled_as_it_came.One_two,one_two.And_through_and_through_The_vorpal_blade_went_snicker-snack.He_left_it_dead_and_with_its_head,He_went_galumphing_back.And_hast_thou_slain_the_Jabberwock?Come_to_my_arms,my_beamish_boy,Oh_frabjous_day.Callooh_callay.He_chortled_in_his_joy.Twas_brillig,and_the_slithy_toves,Did_gyre_and_gimble_in_the_wabe,All_mimsy_were_the_borogoves,And_the_mome-raths_outgrabe. > $tmpdir/$pid.lw + +echo 'here_is_a_really_long_word.It_has_got_to_be_longer_than_1000_characters_for_the_lexical_analyzers_buffer_to_overflow_but_that_should_not_be_too_difficult_to_do.Let_me_start_writing_some_Lewis_Carroll.Twas_brillig_and_the_slithy_toves,Did_gyre_and_gimble_in_the_wabe.All_mimsy_were_the_borogoves,And_the_mome-raths_outgrabe.Beware_the_Jabberwock_my_son,The_jaws_that_bite,the_claws_that_catch.Beware_the_Jub-jub_bird,and_shun_The_frumious_Bandersnatch.He_took_his_vorpal_sword_in_hand,Long_time_the_manxome_foe_he_sought,So_rested_he_by_the_Tumtum_tree,And_stood_awhile_in_thought.And_as_in_uffish_thought_he_stood,The_Jabberwock,with_eyes_of_flame,Came_whiffling_through_the_tulgey_wood,And_burbled_as_it_came.One_two,one_two.And_through_and_through_The_vorpal_blade_went_snicker-snack.He_left_it_dead_and_with_its_head,He_went_galumphing_back.And_hast_thou_slain_the_Jabberwock?Come_to_my_arms,my_beamish_boy,Oh_frabjous_day.Callooh_callay.He_chortled_in_his_joy.Twas_brillig,and_the_slithy_toves,Did_gyre_and_gimble_in_the_wabe,All_mimsy_were_the_borogoves,And_the_mome-raths_outgrabe.' > $tmpdir/$pid.lq + +if (!~ ``(){cat $tmpdir/$pid.lw} ``(){cat $tmpdir/$pid.lq}) + fail expected long string and long word to be identical +if (! x=`{wc -c $tmpdir/$pid.lw} ~ $x(1) 1088) + fail expected long word to be 1088 bytes +if (! x=`{wc -c $tmpdir/$pid.lq} ~ $x(1) 1088) + fail expected long quote to be 1088 bytes + +rm $tmpdir/$pid.lw +rm $tmpdir/$pid.lq + +submatch 'echo hi |[2' 'rc: expected ''='' or '']'' after digit' 'scan error' +submatch 'echo hi |[92=]' 'rc: expected digit after ''=''' 'scan error' +submatch 'echo hi |[a]' 'rc: expected digit after ''[''' 'scan error' +submatch 'echo hi |[2-' 'rc: expected ''='' or '']'' after digit' 'scan error' +submatch 'echo hi |[2=99a]' 'rc: expected '']'' after digit' 'scan error' +submatch 'echo hi |[2=a99]' 'rc: expected digit or '']'' after ''=''' 'scan error' +submatch 'echo ''hi' 'rc: eof in quoted string' 'scan error' + +ifs='' { + if (!~ 'h i' `{echo -n h\ +i}) + fail backslash-newline to space conversion + if (!~ $rc^\rc `{echo -n $rc\rc}) + fail backslash after variable name did not terminate variable name scan + if (!~ $rc^' rc' `{echo -n $rc\ +rc}) + fail backslash-newline after variable name space conversion + if (!~ 'h\i' `{echo -n h\i}) + fail backslash in the middle of word + if (!~ 'h \ i' `{echo -n h \ i}) + fail free-standing backslash +} + +if (! $rc -c '# eof in comment') + fail eof in comment exited with nonzero status + +# test the syntax error printer + +prompt='' if (!~ `` $nl {$rc -cif>[2=1]} 'rc: line 1: '*' error near if') + fail print syntax error + +prompt='' if (!~ `` $nl {$rc -icif>[2=1]} *' error') + fail print syntax error + +# +# builtins +# + +fn foo { + return sigfpe +} + +foo +if (!~ $status sigfpe) + fail return builtin did not return sigfpe + +fn foo # test deleting of function +fn bar { + for (i in 1 2 3 4 5) + if (~ $i 3) + return +} + +bar +if (!~ $i 3) + fail return inside loop inside function failed + +submatch return 'rc: return outside of function' 'return outside of function' +submatch 'break 1' 'rc: too many arguments to break' 'break arg count' +submatch break 'rc: break outside of loop' 'break outside of loop' + +for (i in 1 2 3 4 5) + if (~ $i 2) + break +if (!~ $i 2) + fail break out of loop + +submatch 'wait foo' 'rc: `foo'' is a bad number' 'bogus argument to wait' + +if (~ `{echo -n} ?) + fail echo -n +if (!~ `` '' {echo --} $nl) + fail echo -- + +pwd=`/bin/pwd cdpath=/ { # some local assignments + home=/tmp cd + if (!~ `/bin/pwd `{sh -c 'cd /tmp; /bin/pwd'}) + fail could not cd to '$home' + + cdpath=/ cd tmp + if (!~ `/bin/pwd `{sh -c 'cd /tmp; /bin/pwd'}) + fail could not cd to /tmp + + cd $pwd + if (!~ `/bin/pwd `{sh -c 'cd $pwd; /bin/pwd'}) + fail could not cd to current directory! +} + +# Test that cd to a directory found via cdpath produces output +# when interactive. +submatch 'cdpath=/ cd tmp' /tmp 'cdpath produced wrong output' + +*=(1 2 3 4 5) { + expect bad number + shift foo + expect arg count + shift 1 2 3 + expect shift overflow + shift 123 + shift 3 + if (!~ $#* 2) + fail shift 3 of '(1 2 3 4 5)' failed + shift + if (!~ $* 5) + fail shift failed to shift left-to-right +} + +false +eval && fail null eval reset '$status' + +if (!~ `{rm=(); fn rm; path=(. /bin); whatis rm} /bin/rm) + fail rm isn''''t in bin!? + +expect list of signal handlers +whatis -s + +expect list of variables and functions +whatis + +submatch 'whatis -x' 'whatis: bad option: -x' 'bad option to whatis' + +submatch 'whatis /frobnatz' '/frobnatz not found' 'search for /frobnatz' + +if (~ `{whatis limit >[2]/dev/null} builtin) { + limit coredumpsize 0 + if (!~ `{limit coredumpsize} 0*) + fail failed to set coredumpsize to zero + if (!~ `` () {limit coredumpsize} `` () {limit|grep coredumpsize}) + fail limit limit + submatch 'limit foo' 'no such limit' 'bad limit' +} + +fn cd + +submatch 'cd a b c' 'rc: too many arguments to cd' 'cd arg count' +$rc -c 'cdpath=() cd /frobnatz' >[2]/dev/null && fail 'cd to /frobnatz succeeded!?' +submatch 'cdpath='''' cd frobnatz' 'couldn''t cd to frobnatz' 'cd to frobnatz succeeded!?' + +'if'=keyword { + {whatis if | fgrep '''if''=keyword' >/dev/null} || fail whatis of keyword is not quoted +} + +# +# wait +# + +submatch 'wait 1 2 3' 'rc: too many arguments to wait' 'wait arg count' +$rc -c 'wait 1' >[2]/dev/null && fail wait 1 + +sleep 3& +expect $apid +echo $apids +wait + +if (~ `` '' {wait} ?) + fail waiting for nothing + +# +# matching +# +touch $tmpdir/abc.$pid $tmpdir/bbc.$pid +mkdir $tmpdir/dir.$pid $tmpdir/dip.$pid +touch $tmpdir/dir.$pid/^(a b c) $tmpdir/dip.$pid/^(a b c) + +if (!~ 123 [~x]?[0-9]) + fail match +if (!~ () *) + fail match of null list with '*' +if (~ () *v*) + fail match of null list with '*v*' succeeded +if (!~ (foo bar zar) *****z*****) + fail match of list by one pattern failed +if (~ (foo bar zar) *c*) + fail bad match +if (!~ [aaa [aaa) + fail bad rangematch +if (!~ ']' []]) + fail match right bracket +if (~ x [y]) + fail rangematch out of range +if (~ x x?) + fail too many characters in pattern + +sh -c 'test -f /////$tmpdir//////a?c.'^$pid || fail glob with many slashes +if (!~ /////$tmpdir//////a*.$pid /////$tmpdir//////a?c.$pid) + fail glob with many slashes +if (!~ ////$tmpdir////di?.$pid////* ////$tmpdir////dir.$pid////*b*) + fail glob with more slashes +if (! @{cd $tmpdir; ~ *.$pid/a d*/*}) + fail glob in current directory +if (!~ $tmpdir/?bc.$pid $tmpdir/bbc.$pid) + fail match of bbc.$pid against '('abc.$pid bbc.$pid')' + +rm $tmpdir/abc.$pid $tmpdir/bbc.$pid +rm -rf $tmpdir/dir.$pid $tmpdir/dip.$pid + +# +# signals +# +fn sigint {eval} +kill -2 $pid +fn sigint + +# +# path searching +# +$rc -c /frobnatz >[2]/dev/null && fail 'search error' + +touch $tmpdir/noexec.$pid +chmod a-x $tmpdir/noexec.$pid +$rc -c $tmpdir/noexec.$pid >[2]/dev/null && fail $tmpdir/noexec.$pid is found!? +rm $tmpdir/noexec.$pid + +submatch 'path='''' frobnatz' 'rc: cannot find `frobnatz''' 'search error' + +{path=() /bin/sh -c 'exit 0'} || fail abs pathname with path set to null + +# +# options +# + +# this test is meaningless; not really a trip +expect prompt, echo hi +home=/frobnatz $rc -nolpeivdxc 'echo hi' +if (!~ `` $nl {$rc -c>[2=1]} *': option requires an argument -- c') + fail getopt on -c +if (!~ `` $nl {$rc -q>[2=1]} *': bad option: -q') + fail getopt on -q (bogus option) +if (!~ `{echo '#echo' | $rc -v |[2] sed 's/#//'} echo) + fail rc -v + +# +# dot +# + +if (~ `` '' . ?*) + fail null dot +if (~ `` '' {. -i} ?*) + fail null dot -i + +cat > $tmpdir/dot.$pid << eof +echo hi +eof + +prompt=';' if (!~ `` '' {. -i $tmpdir/dot.$pid>[2=1]} ';hi'^$nl';') + fail dot -i +submatch .' '$tmpdir/dot.$pid hi dot + +rm $tmpdir/dot.$pid + +$rc -c '. /frobnatz' >[2]/dev/null && fail 'dot of a nonexistent file' + +# +# stdin +# +if (!~ `{echo echo hi | $rc} hi) + fail piping stdin to rc + +# +# functions, variables & environment +# +fn --- {for(i)a|[2=3]b>>c<<[2=1]} + +if (whatis printenv >/dev/null>[2=1]) { + printenv=printenv +} else if (whatis env >/dev/null>[2=1]) { + printenv=env +} else + printenv=() + +if (~ $#printenv 1 && !~ `` $nl {$printenv | grep fn___2d__2d__2d} 'fn___2d__2d__2d={for(i in $*)a|[2=3]b >>c <<[2=1]}') + fail protect_env + +fn --- {replace} +~ `{whatis -- ---} *replace* || fail replace a function definition +fn --- +whatis -- --- >[2]/dev/null && fail function deletion +foo=bar *=bar +foo=nest *=nest { + ~ $foo nest || fail local assignment + ~ $* nest || fail local assignment to '$*' + foo=() + *=() + ~ $foo () || fail local deletion + ~ $* () || fail local deletion to '$*' +} +~ $foo bar || fail restore of global after local group +~ $* bar || fail restore of '$*' after local group +~ `{exec>[2=1];$rc -xc 'foo=()'} 'foo=()' || fail -x echo of variable deletion + +fn_ff='{' prompt='' if (!~ `` $nl {$rc -cff>[2=1]} 'rc: line 1: '*' error near eof') + fail 'bogus function in environment' + +# +# statuses +# +~ `{$rc -ec 'sleep 10&kill -9 $apid;wait'>[2=1]} killed || + fail status diagnostic + +$rc -c 'exit 0 sigfpe' && fail exit of bad pipeline is true + +submatch 'exit foo' 'bad status' 'exit diagnostic' + +# +# control structures +# +if (!~ `{false || echo hi} hi) + fail '||' +if (!~ `{true && echo hi} hi) + fail '&&' +if (~ `{true || echo hi} hi) + fail '||' +if (~ `{false && echo hi} hi) + fail '&&' + +while (false) + fail false while +while (true) { + break + fail break in while +} + +switch (foo) { + case bar + fail matched bar in switch + case foo + eval + case * + fail match foo in switch +} + +switch (nothing) { + case bar + fail matched bar in switch + case * + i=frobnatz +} + +~ $i frobnatz || fail match '*' in switch + +submatch '()=()' 'rc: null variable name' 'assignment diagnostic' +submatch 'fn () {eval}' 'rc: null function name' 'assigning null function name' + +# +# prompt +# +fn prompt {echo hi} +prompt=() if (!~ `{$rc -i /dev/null>[2]/dev/null} hi) fail fn prompt +fn prompt + +# +# history +# +history=$tmpdir/hist.$pid prompt='' echo 'history=()' | $rc -i + +if (!~ `{cat $tmpdir/hist.$pid} 'history=()') + fail output to history file + +history=$tmpdir/hist.$pid prompt='' echo 'history=()' | $rc -i + +if (!~ `` () {cat $tmpdir/hist.$pid} 'history=() +history=() +') + fail append to history file + +rm $tmpdir/hist.$pid + +if (!~ `{history=/frobnatz/foo prompt='' echo eval | $rc -i >[2=1]} ?*) + fail accessing bad history file + +# +# regression +# + +expect date +{ date & wait } |cat + +# Making rc's input non-blocking should have no untoward side effects. +x=`{ { sleep 1; echo echo foo } | { ./tripping n; $rc >[2=1] } } +if (!~ foo $x) + fail input file descriptor nonblocking + +# `rc -s' reads from stdin, but should not imply `-i' +expect foo bar qux +$rc -s foo bar qux <<'eof' +echo $* +eof + +# Believe it or not, I broke root directory globbing in rc-1.6b1. +x=/* +~ '/*' $^x && fail root directory globbing + +# fn sigexit should be cleared in children + +x = () +expect rc: cannot find '`nonesuch''' +x = `{true | nonesuch}; if (~ $x trip) fail sigexit in children +x = `{ < /dev/null wc |grep xxx }; if (~ $x trip) fail sigexit in children +x = `{{ wc | wc } < /dev/null }; if (~ $x trip) fail sigexit in children + +# core dumps in glob.c +~ () '*' && fail globber problem +~ () '**' && fail globber problem + +# check for ctrl-a bug +x=`{./tripping a} +~ `{$rc -c 'echo $x'} $x || fail ctrl-a bug detected + +# check for hilarious quoting bug introduced while fixing ctrl-a +x=('#' '#' '#') +eval z^`{whatis -v x} +~ $#zx 3 || fail hilarious quoting bug + +# parens bypass quote detector bug +fn x {echo x.y $(x.y)} +~ ``''{whatis -f x} 'fn x {echo x.y $(x^.y)} +' || fail sneaky parens bug + +# before rc-1.7.1, certain glob patterns could fail on broken symlinks +mkdir $tmpdir/qux +ln -s /frobnatz $tmpdir/qux/foo +x=$tmpdir/qux/foo* +~ $x $tmpdir/qux/foo || { rm -rf $tmpdir/qux; fail broken symlink globbing } +x=$tmpdir/qux*/foo +~ $x $tmpdir/qux/foo || { rm -rf $tmpdir/qux; fail broken symlink globbing } + +rm -rf $tmpdir diff --git a/tripping.c b/tripping.c new file mode 100644 index 0000000..23b2972 --- /dev/null +++ b/tripping.c @@ -0,0 +1,45 @@ +/* This is an auxiliary test program for rc. */ + +#include "config.h" + +#include +#include +#include +#include +#include + +static void out0(void) { + putchar('t'); putchar('r'); + putchar('\0'); + putchar('u'); putchar('e'); + putchar('\n'); +} + +static void ctrl_a(void) { + puts("a\001ab\002b"); +} + +static void makenonblock(void) { + int flags; + + if ((flags = fcntl(0, F_GETFL)) == -1) + perror("fcntl 1"); + flags |= O_NONBLOCK; + if (fcntl(0, F_SETFL, (long) flags) == -1) + perror("fcntl 2"); +} + +int main(int argc, char **argv) { + switch(argv[1][0]) { + case '0': + out0(); + break; + case 'a': + ctrl_a(); + break; + case 'n': + makenonblock(); + break; + } + return 0; +} diff --git a/utils.c b/utils.c new file mode 100644 index 0000000..482f7a7 --- /dev/null +++ b/utils.c @@ -0,0 +1,81 @@ +/* utils.c: functions of general utility */ + +#include "rc.h" + +#include +#include + +#include "jbwrap.h" + +/* print error with line number on noninteractive shells (i.e., scripts) */ + +extern void pr_error(char *s, int offset) { + if (s != NULL) { + if (interactive) + fprint(2, RC "%s\n", s); + else + fprint(2, RC "line %d: %s\n", lineno + offset, s); + } +} + +/* our perror */ + +extern void uerror(char *s) { + char *err; + + err = strerror(errno); + if (!err) err = "unknown error"; + + if (s) + fprint(2, RC "%s: %s\n", s, err); + else + fprint(2, RC "%s\n", err); +} + +/* 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 * const *)s1, *(char * const *)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] == '/'))); +} + + +/* 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 new file mode 100644 index 0000000..2fa7c35 --- /dev/null +++ b/var.c @@ -0,0 +1,225 @@ +/* var.c: provide "public" functions for adding and removing variables from the symbol table */ + +#include "rc.h" + +#include "input.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; + set_exportable(name, TRUE); + if (streq(name, "TERM") || streq(name, "TERMCAP")) + termchange(); +} + +/* 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); + set_exportable(name, TRUE); + 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, "apids")) + return sgetapids(); + if (streq(name, "status")) + return sgetstatus(); + 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(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=%W", name, look->def); +} + +/* 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/wait.c b/wait.c new file mode 100644 index 0000000..1ab8533 --- /dev/null +++ b/wait.c @@ -0,0 +1,128 @@ +#include "rc.h" + +#include + +#include "wait.h" + +bool forked = FALSE; + +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; + struct Pid *p, *q; + pid_t pid = fork(); + + switch (pid) { + case -1: + uerror("fork"); + rc_error(NULL); + /* NOTREACHED */ + case 0: + forked = TRUE; + sigchk(); + p = plist; q = 0; + while (p) { + if (q) efree(q); + q = p; + p = p->n; + } + if (q) efree(q); + plist = 0; + 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; + + /* Find the child on the list. */ + for (r = plist, prev = NULL; r != NULL; prev = r, r = r->n) + if (r->pid == pid) + break; + + /* Uh-oh, not there. */ + if (r == NULL) { + errno = ECHILD; /* no children */ + uerror("wait"); + *stat = 0x100; /* exit(1) */ + return -1; + } + + /* If it's still alive, wait() for it. */ + while (r->alive) { + int ret; + Pid *q; + + ret = rc_wait(stat); + + if (ret < 0) { + if (errno == ECHILD) + panic("lost child"); + if (nointr) + continue; + else + return ret; + } + + for (q = plist; q != NULL; q = q->n) + if (q->pid == ret) { + q->alive = FALSE; + q->stat = *stat; + break; + } + } + *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) { + pid_t pid = rc_wait4(plist->pid, &stat, FALSE); + if (pid > 0) + setstatus(pid, stat); + else { + set(FALSE); + if (errno == EINTR) + return; + } + sigchk(); + } +} diff --git a/wait.h b/wait.h new file mode 100644 index 0000000..e54ae45 --- /dev/null +++ b/wait.h @@ -0,0 +1,23 @@ +#if HAVE_SYS_WAIT_H +#include +#endif + +/* Fake the POSIX wait() macros if we don't have them. */ +#ifndef WIFEXITED +#define WIFEXITED(s) (((s) & 0xFF) == 0) +#endif +#ifndef WEXITSTATUS +#define WEXITSTATUS(s) (((unsigned)(s) >> 8) && 0xFF) +#endif +#ifndef WIFSIGNALED +#define WIFSIGNALED(s) (((s) & 0xFF) != 0) +#endif +#ifndef WTERMSIG +#define WTERMSIG(s) ((s) & 0x7F) +#endif + +/* These don't exist in POSIX. */ +#define myWIFDUMPED(s) (((s) & 0x80) != 0) + + + diff --git a/walk.c b/walk.c new file mode 100644 index 0000000..984a68c --- /dev/null +++ b/walk.c @@ -0,0 +1,365 @@ +/* walk.c: walks the parse tree. */ + +#include "rc.h" + +#include +#include + +#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: + 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 (sigsetjmp(j.j, 1)) + 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 (sigsetjmp(j.j, 1)) + 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)) { + setsigdefaults(FALSE); + 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; + setsigdefaults(FALSE); + 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)) { + setsigdefaults(FALSE); + 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) { + setsigdefaults(FALSE); + 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) { + setsigdefaults(FALSE); + 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 new file mode 100644 index 0000000..798d7b0 --- /dev/null +++ b/which.c @@ -0,0 +1,142 @@ +/* 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 accommodate 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 "getgroups.h" + +#define X_USR 0100 +#define X_GRP 0010 +#define X_OTH 0001 +#define X_ALL (X_USR|X_GRP|X_OTH) + +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) { + int i; + for (i = 0; i < ngroups; ++i) + if (g == gidset[i]) + return 1; + return 0; +} +#else +#define ingidset(g) (FALSE) +#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; + else if (gid == st.st_gid || ingidset(st.st_gid)) + 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; +} + +/* replace non-printing characters with question marks in a freshly + * allocated string */ +static char *protect(char *in) { + int l = strlen(in); + char *out = ealloc(l + 1); + int i; + + for (i = 0; i < l; ++i) + out[i] = isprint(in[i]) ? in[i] : '?'; + out[i] = '\0'; + return out; +} + +/* 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 +#if HAVE_POSIX_GETGROUPS + ngroups = getgroups(0, (GETGROUPS_T *)0); + if (ngroups < 0) { + uerror("getgroups"); + rc_exit(1); + } +#else + ngroups = NGROUPS; +#endif + if (ngroups) { + gidset = ealloc(ngroups * sizeof(GETGROUPS_T)); + 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) { + char *n = protect(name); + fprint(2, RC "cannot find `%s'\n", n); + efree(n); + } + return NULL; +}